From 3144d5eb48b578525cb24378fb616a1b59bf0f27 Mon Sep 17 00:00:00 2001 From: "serg@sergbook.mysql.com" <> Date: Tue, 25 Apr 2006 13:37:33 -0700 Subject: [PATCH 1/2] buffer overflow and information exposure bugs fixed (reported by Stefano Di Paola) --- sql/sql_parse.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4b32703c1ee..93f696f6d49 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -647,6 +647,11 @@ check_connections(THD *thd) char *db=0; if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) db=strend(passwd)+1; + if (strend(db ? db : passwd) - (char*)net->read_pos > pkt_len) + { + inc_host_errors(&thd->remote.sin_addr); + return ER_HANDSHAKE_ERROR; + } if (thd->client_capabilities & CLIENT_INTERACTIVE) thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout; if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && @@ -1002,7 +1007,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd, statistic_increment(com_other, &LOCK_status); slow_command = TRUE; uint db_len = *(uchar*)packet; + if (db_len >= packet_length || db_len > NAME_LEN) + { + send_error(&thd->net, ER_UNKNOWN_COM_ERROR); + break; + } uint tbl_len = *(uchar*)(packet + db_len + 1); + if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN) + { + send_error(&thd->net, ER_UNKNOWN_COM_ERROR); + break; + } char* db = thd->alloc(db_len + tbl_len + 2); memcpy(db, packet + 1, db_len); char* tbl_name = db + db_len; From 54c97e61501936a8e468be0c96536558b66809c1 Mon Sep 17 00:00:00 2001 From: "serg@sergbook.mysql.com" <> Date: Tue, 25 Apr 2006 17:12:06 -0700 Subject: [PATCH 2/2] after merge fix --- sql/sql_parse.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3fc71351d74..51ef3f31b26 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -908,7 +908,7 @@ static int check_connection(THD *thd) db + passwd_len + 1 : 0; uint db_len= db ? strlen(db) : 0; - if (passwd + passwd_len + db_len > net->read_pos + pkt_len) + if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len) { inc_host_errors(&thd->remote.sin_addr); return ER_HANDSHAKE_ERROR; @@ -1388,13 +1388,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, uint db_len= *(uchar*) packet; if (db_len >= packet_length || db_len > NAME_LEN) { - send_error(&thd->net, ER_UNKNOWN_COM_ERROR); + send_error(thd, ER_UNKNOWN_COM_ERROR); break; } uint tbl_len= *(uchar*) (packet + db_len + 1); if (db_len+tbl_len+2 > packet_length || tbl_len > NAME_LEN) { - send_error(&thd->net, ER_UNKNOWN_COM_ERROR); + send_error(thd, ER_UNKNOWN_COM_ERROR); break; }