List:Internals« Previous MessageNext Message »
From:sca Date:April 18 2010 3:13pm
Subject:net_skip_rest bugfix patch
View as plain text  
Hi

Attached is our fix for a net_skip_rest DoS bug.
Unless a user is authenticated, net_skip_rest does not skip anything at
all.  After successful authentication, it skips, but there is a limit on
how much it does.

Regards,
Sergei


------------------------------------------------------------
revno: 2821
committer: Sergei Golubchik <sergii@stripped>
branch nick: maria-5.1
timestamp: Tue 2010-02-23 13:04:58 +0100
message:
  fix for a possible DoS in the my_net_skip_rest()
modified:
  include/mysql.h.pp
  include/mysql_com.h
  sql/net_serv.cc
  sql/sql_connect.cc
diff:
=== modified file 'include/mysql.h.pp'
--- include/mysql.h.pp	2010-01-15 15:27:55 +0000
+++ include/mysql.h.pp	2010-02-23 12:04:58 +0000
@@ -28,7 +28,7 @@
   unsigned int *return_status;
   unsigned char reading_or_writing;
   char save_char;
-  my_bool unused0;
+  char net_skip_rest_factor;
   my_bool unused;
   my_bool compress;
   my_bool unused1;

=== modified file 'include/mysql_com.h'
--- include/mysql_com.h	2008-10-10 15:28:41 +0000
+++ include/mysql_com.h	2010-02-23 12:04:58 +0000
@@ -254,7 +254,7 @@
   unsigned int *return_status;
   unsigned char reading_or_writing;
   char save_char;
-  my_bool unused0; /* Please remove with the next incompatible ABI change. */
+  char net_skip_rest_factor;
   my_bool unused; /* Please remove with the next incompatible ABI change */
   my_bool compress;
   my_bool unused1; /* Please remove with the next incompatible ABI change. */

=== modified file 'sql/net_serv.cc'
--- sql/net_serv.cc	2010-01-29 10:42:31 +0000
+++ sql/net_serv.cc	2010-02-23 12:04:58 +0000
@@ -130,6 +130,7 @@
   net->last_error[0]=0;
   net->compress=0; net->reading_or_writing=0;
   net->where_b = net->remain_in_buf=0;
+  net->net_skip_rest_factor= 0;
   net->last_errno=0;
 #ifdef USE_QUERY_CACHE
   query_cache_init_query(net);
@@ -743,6 +744,7 @@
 static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
 				ALARM *alarm_buff)
 {
+  longlong limit= net->max_packet_size*net->net_skip_rest_factor;
   uint32 old=remain;
   DBUG_ENTER("my_net_skip_rest");
   DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
@@ -766,11 +768,15 @@
 	DBUG_RETURN(1);
       update_statistics(thd_increment_bytes_received(length));
       remain -= (uint32) length;
+      limit-= length;
+      if (limit < 0)
+        DBUG_RETURN(1);
     }
     if (old != MAX_PACKET_LENGTH)
       break;
     if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
       DBUG_RETURN(1);
+    limit-= NET_HEADER_SIZE;
     old=remain= uint3korr(net->buff);
     net->pkt_nr++;
   }

=== modified file 'sql/sql_connect.cc'
--- sql/sql_connect.cc	2010-01-29 10:42:31 +0000
+++ sql/sql_connect.cc	2010-02-23 12:04:58 +0000
@@ -474,7 +474,8 @@
         }
       }
       my_ok(thd);
-      thd->password= test(passwd_len);          // remember for error messages 
+      thd->net.net_skip_rest_factor= 2;  // skip at most 2*max_packet_size
+      thd->password= test(passwd_len);   // remember for error messages 
       /* Ready to handle queries */
       DBUG_RETURN(0);
     }

Thread
net_skip_rest bugfix patchsca18 Apr