diff --git a/include/mysql_com.h b/include/mysql_com.h index 94b34c1c3f0..2eeec270cd0 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -219,6 +219,16 @@ 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) + /* + Controls whether a big packet should be skipped. + + Initially set to FALSE by default. Unauthenticated sessions must have + this set to FALSE so that the server can't be tricked to read packets + indefinitely. + */ + my_bool skip_big_packet; +#endif } NET; #define packet_error (~(unsigned long) 0) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index fdabad6f569..1d1871e27a8 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -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_big_packet= FALSE; +#endif if (vio != 0) /* If real connection */ { @@ -947,6 +950,7 @@ my_real_read(NET *net, ulong *complen) { #if defined(MYSQL_SERVER) && !defined(NO_ALARM) if (!net->compress && + net->skip_big_packet && !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff)) net->error= 3; /* Successfully skiped packet */ #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f1fb3d646b5..2b43d95dd7c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -493,6 +493,13 @@ int check_user(THD *thd, enum enum_server_command command, } send_ok(thd); thd->password= test(passwd_len); // remember for error messages + /* + Allow the network layer to skip big packets. Although a malicious + authenticated session might use this to trick the server to read + big packets indefinitely, this is a previously established behavior + that needs to be preserved as to not break backwards compatibility. + */ + thd->net.skip_big_packet= TRUE; /* Ready to handle queries */ DBUG_RETURN(0); }