From f665d62bec2ff75f24ad5ae6e47f770cb906c826 Mon Sep 17 00:00:00 2001 From: lv-426 Date: Mon, 1 Dec 2008 01:41:35 +0000 Subject: [PATCH] MHD_gtls_server_name_recv_params - address CVE-2008-1948 --- src/daemon/https/tls/ext_server_name.c | 133 ++++++++++++++----------- 1 file changed, 73 insertions(+), 60 deletions(-) diff --git a/src/daemon/https/tls/ext_server_name.c b/src/daemon/https/tls/ext_server_name.c index 45afc31b..1441f692 100644 --- a/src/daemon/https/tls/ext_server_name.c +++ b/src/daemon/https/tls/ext_server_name.c @@ -48,76 +48,89 @@ MHD_gtls_server_name_recv_params (MHD_gtls_session_t session, ssize_t data_size = _data_size; int server_names = 0; - if (session->security_parameters.entity == GNUTLS_SERVER) + DECR_LENGTH_RET (data_size, 2, 0); + len = MHD_gtls_read_uint16 (data); + + if (len != data_size) { - DECR_LENGTH_RET (data_size, 2, 0); - len = MHD_gtls_read_uint16 (data); + /* This is unexpected packet length, but + * just ignore it, for now. + */ + MHD_gnutls_assert (); + return 0; + } - if (len != data_size) + p = data + 2; + + /* Count all server_names in the packet. */ + while (data_size > 0) + { + DECR_LENGTH_RET (data_size, 1, 0); + p++; + + DECR_LEN (data_size, 2); + len = MHD_gtls_read_uint16 (p); + p += 2; + + /* make sure supplied server name is not empty */ + if (len > 0) { - /* This is unexpected packet length, but - * just ignore it, for now. - */ - MHD_gnutls_assert (); - return 0; - } - - p = data + 2; - - /* Count all server_names in the packet. */ - while (data_size > 0) - { - DECR_LENGTH_RET (data_size, 1, 0); - p++; - - DECR_LEN (data_size, 2); - len = MHD_gtls_read_uint16 (p); - p += 2; - DECR_LENGTH_RET (data_size, len, 0); server_names++; - p += len; } - - session->security_parameters.extensions.server_names_size = - server_names; - if (server_names == 0) - return 0; /* no names found */ - - /* we cannot accept more server names. - */ - if (server_names > MAX_SERVER_NAME_EXTENSIONS) - server_names = MAX_SERVER_NAME_EXTENSIONS; - - p = data + 2; - for (i = 0; i < server_names; i++) + else { - type = *p; - p++; - - len = MHD_gtls_read_uint16 (p); - p += 2; - - switch (type) - { - case 0: /* NAME_DNS */ - if (len <= MAX_SERVER_NAME_SIZE) - { - memcpy (session->security_parameters. - extensions.server_names[i].name, p, len); - session->security_parameters.extensions.server_names[i]. - name_length = len; - session->security_parameters.extensions.server_names[i]. - type = GNUTLS_NAME_DNS; - break; - } - } - - /* move to next record */ - p += len; +#if HAVE_MESSAGES + MHD__gnutls_handshake_log + ("HSK[%x]: Received zero size server name (under attack?)\n", + session); +#endif } } + + /* we cannot accept more server names. */ + if (server_names > MAX_SERVER_NAME_EXTENSIONS) + { +#if HAVE_MESSAGES + MHD__gnutls_handshake_log + ("HSK[%x]: Too many server names received (under attack?)\n", + session); +#endif + server_names = MAX_SERVER_NAME_EXTENSIONS; + } + + session->security_parameters.extensions.server_names_size = server_names; + if (server_names == 0) + return 0; /* no names found */ + + p = data + 2; + for (i = 0; i < server_names; i++) + { + type = *p; + p++; + + len = MHD_gtls_read_uint16 (p); + p += 2; + + switch (type) + { + case 0: /* NAME_DNS */ + if (len <= MAX_SERVER_NAME_SIZE) + { + memcpy (session->security_parameters.extensions.server_names[i]. + name, p, len); + session->security_parameters.extensions. + server_names[i].name_length = len; + session->security_parameters.extensions.server_names[i].type = + GNUTLS_NAME_DNS; + break; + } + } + + /* move to next record */ + p += len; + } return 0; }