From: Davi Arnaut Date: April 20 2010 12:42am Subject: bzr commit into mysql-5.0-bugteam branch (davi:2858) Bug#50974 List-Archive: http://lists.mysql.com/commits/106060 X-Bug: 50974 Message-Id: <20100420004232.31FC048E2C7@skynet> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_SQ5Y6Yo9XOSoRI3oWRRoDA)" --Boundary_(ID_SQ5Y6Yo9XOSoRI3oWRRoDA) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline # At a local mysql-5.0-bugteam repository of davi 2858 Davi Arnaut 2010-04-19 Bug#50974: Server keeps receiving big (> max_allowed_packet) packets indefinitely. The server could be tricked to read packets indefinitely if it received a packet larger than the maximum size of one packet. This problem is aggravated by the fact that it can be triggered before authentication. The solution is to skip at least twice the maximum packet size. If the packet (or following packets) are larger then twice the maximum size, a error is returned and the connection is closed. Skipping is only performed for authenticated users. @ include/mysql_com.h Add skip factor. Only used in server builds. @ sql/net_serv.cc Control the amount of data that can be skipped. Similar behavior for client and server. @ tests/mysql_client_test.c Add test case. modified: include/mysql_com.h sql/net_serv.cc sql/sql_parse.cc tests/mysql_client_test.c === modified file 'include/mysql_com.h' --- a/include/mysql_com.h 2007-12-13 10:53:24 +0000 +++ b/include/mysql_com.h 2010-04-20 00:42:25 +0000 @@ -219,6 +219,10 @@ typedef struct st_net { my_bool report_error; /* We should report error (we have unreported error) */ my_bool return_errno; +#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) + /* Limit on how much data can be skipped if a packet is too big. */ + unsigned char skip_rest_factor; +#endif } NET; #define packet_error (~(unsigned long) 0) === modified file 'sql/net_serv.cc' --- a/sql/net_serv.cc 2009-07-28 18:35:55 +0000 +++ b/sql/net_serv.cc 2010-04-20 00:42:25 +0000 @@ -141,6 +141,9 @@ my_bool my_net_init(NET *net, Vio* vio) net->query_cache_query= 0; #endif net->report_error= 0; +#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) + net->skip_rest_factor= 0; +#endif if (vio != 0) /* If real connection */ { @@ -725,6 +728,21 @@ static my_bool net_safe_read(NET *net, c return 0; } + +/* + Helper function to determine the skip factor. +*/ + +static ulonglong my_net_skip_rest_factor(NET *net) +{ +#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) + return net->max_packet_size * net->skip_rest_factor; +#else + return net->max_packet_size * 2; +#endif +} + + /* Help function to clear the commuication buffer when we get a too big packet. @@ -744,6 +762,7 @@ static my_bool my_net_skip_rest(NET *net ALARM *alarm_buff) { uint32 old=remain; + ulonglong skippable= my_net_skip_rest_factor(net); DBUG_ENTER("my_net_skip_rest"); DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain)); @@ -759,6 +778,12 @@ static my_bool my_net_skip_rest(NET *net } for (;;) { + /* Don't read packets indefinitely. */ + if (remain >= skippable) + DBUG_RETURN(1); + else + skippable-= remain; + while (remain > 0) { uint length= min(remain, net->max_packet); @@ -769,9 +794,12 @@ static my_bool my_net_skip_rest(NET *net } if (old != MAX_PACKET_LENGTH) break; + else if (skippable < NET_HEADER_SIZE) + DBUG_RETURN(1); if (net_safe_read(net, (char*) net->buff, NET_HEADER_SIZE, alarmed)) DBUG_RETURN(1); old=remain= uint3korr(net->buff); + skippable-= NET_HEADER_SIZE; net->pkt_nr++; } DBUG_RETURN(0); === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2010-02-25 14:57:15 +0000 +++ b/sql/sql_parse.cc 2010-04-20 00:42:25 +0000 @@ -493,6 +493,8 @@ int check_user(THD *thd, enum enum_serve } send_ok(thd); thd->password= test(passwd_len); // remember for error messages + /* Skip at most 2 * max_packet_size bytes. */ + thd->net.skip_rest_factor= 2; /* Ready to handle queries */ DBUG_RETURN(0); } === modified file 'tests/mysql_client_test.c' --- a/tests/mysql_client_test.c 2009-08-08 02:32:01 +0000 +++ b/tests/mysql_client_test.c 2010-04-20 00:42:25 +0000 @@ -16679,6 +16679,80 @@ static void test_bug45010() } +/** + Bug#50974: Server keeps receiving big (> max_allowed_packet) packets indefinitely. +*/ + +#ifndef EMBEDDED_LIBRARY + +static void test_bug50974() +{ + int rc; + MYSQL *con; + MYSQL_RES *res; + MYSQL_ROW row; + char query_buffer[128], packet[NET_HEADER_SIZE]; + + DBUG_ENTER("test_bug50974"); + myheader("test_bug50974"); + + memset(query_buffer, 0, sizeof(query_buffer)); + + /* Save values and set them to 1024. */ + + rc= mysql_query(mysql, "SELECT @@net_buffer_length, @@max_allowed_packet"); + myquery(rc); + + res= mysql_store_result(mysql); + mytest(res); + + row= mysql_fetch_row(res); + mytest(row); + + rc= my_snprintf(query_buffer, sizeof(query_buffer) - 1, + "SET GLOBAL net_buffer_length = %s, " + "max_allowed_packet = %s", row[0], row[1]); + DIE_UNLESS((size_t) rc <= sizeof(query_buffer)); + + mysql_free_result(res); + + rc= mysql_query(mysql, "SET GLOBAL net_buffer_length = 1024, " + "max_allowed_packet = 1024;"); + myquery(rc); + + /* New connection to test bug. */ + + con= mysql_init(NULL); + DIE_UNLESS(con); + + con= mysql_real_connect(con, opt_host, opt_user, opt_password, "test", + opt_port, opt_unix_socket, 0); + DIE_UNLESS(con); + + net_clear(&con->net); + + /* Packet length and number. */ + int3store(packet, 4096); + packet[3]= (char) con->net.pkt_nr++; + + DIE_IF(net_real_write(&con->net, packet, NET_HEADER_SIZE)); + + /* A error is now expected. */ + DIE_UNLESS(mysql_read_query_result(con)); + /* ER_NET_PACKET_TOO_LARGE = 1153 */ + DIE_UNLESS(mysql_errno(con) == 1153); + + mysql_close(con); + + /* Restore original values. */ + rc= mysql_query(mysql, query_buffer); + myquery(rc); + + DBUG_VOID_RETURN; +} + +#endif + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16982,6 +17056,9 @@ static struct my_tests_st my_tests[]= { { "test_bug41078", test_bug41078 }, { "test_bug20023", test_bug20023 }, { "test_bug45010", test_bug45010 }, +#ifndef EMBEDDED_LIBRARY + { "test_bug50974", test_bug50974 }, +#endif { 0, 0 } }; --Boundary_(ID_SQ5Y6Yo9XOSoRI3oWRRoDA) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/davi.arnaut@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/davi.arnaut@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: davi.arnaut@stripped # target_branch: file:///home/davi/bzr/bugs/50974-5.0/ # testament_sha1: d5f81e72426c255084df27328a5eae21f1699cdd # timestamp: 2010-04-19 21:42:32 -0300 # base_revision_id: joro@stripped # # Begin bundle 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 --Boundary_(ID_SQ5Y6Yo9XOSoRI3oWRRoDA)--