Commit f04cf03f authored by Sergei Golubchik's avatar Sergei Golubchik

fix for a possible DoS in the my_net_skip_rest()

parent 2840821c
...@@ -28,7 +28,7 @@ typedef struct st_net { ...@@ -28,7 +28,7 @@ typedef struct st_net {
unsigned int *return_status; unsigned int *return_status;
unsigned char reading_or_writing; unsigned char reading_or_writing;
char save_char; char save_char;
my_bool unused0; char net_skip_rest_factor;
my_bool unused; my_bool unused;
my_bool compress; my_bool compress;
my_bool unused1; my_bool unused1;
......
...@@ -254,7 +254,7 @@ typedef struct st_net { ...@@ -254,7 +254,7 @@ typedef struct st_net {
unsigned int *return_status; unsigned int *return_status;
unsigned char reading_or_writing; unsigned char reading_or_writing;
char save_char; 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 unused; /* Please remove with the next incompatible ABI change */
my_bool compress; my_bool compress;
my_bool unused1; /* Please remove with the next incompatible ABI change. */ my_bool unused1; /* Please remove with the next incompatible ABI change. */
......
...@@ -130,6 +130,7 @@ my_bool my_net_init(NET *net, Vio* vio) ...@@ -130,6 +130,7 @@ my_bool my_net_init(NET *net, Vio* vio)
net->last_error[0]=0; net->last_error[0]=0;
net->compress=0; net->reading_or_writing=0; net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0; net->where_b = net->remain_in_buf=0;
net->net_skip_rest_factor= 0;
net->last_errno=0; net->last_errno=0;
#ifdef USE_QUERY_CACHE #ifdef USE_QUERY_CACHE
query_cache_init_query(net); query_cache_init_query(net);
...@@ -743,6 +744,7 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length, ...@@ -743,6 +744,7 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed, static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
ALARM *alarm_buff) ALARM *alarm_buff)
{ {
longlong limit= net->max_packet_size*net->net_skip_rest_factor;
uint32 old=remain; uint32 old=remain;
DBUG_ENTER("my_net_skip_rest"); DBUG_ENTER("my_net_skip_rest");
DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain)); DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
...@@ -766,11 +768,15 @@ static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed, ...@@ -766,11 +768,15 @@ static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
DBUG_RETURN(1); DBUG_RETURN(1);
update_statistics(thd_increment_bytes_received(length)); update_statistics(thd_increment_bytes_received(length));
remain -= (uint32) length; remain -= (uint32) length;
limit-= length;
if (limit < 0)
DBUG_RETURN(1);
} }
if (old != MAX_PACKET_LENGTH) if (old != MAX_PACKET_LENGTH)
break; break;
if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed)) if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
DBUG_RETURN(1); DBUG_RETURN(1);
limit-= NET_HEADER_SIZE;
old=remain= uint3korr(net->buff); old=remain= uint3korr(net->buff);
net->pkt_nr++; net->pkt_nr++;
} }
......
...@@ -474,6 +474,7 @@ check_user(THD *thd, enum enum_server_command command, ...@@ -474,6 +474,7 @@ check_user(THD *thd, enum enum_server_command command,
} }
} }
my_ok(thd); my_ok(thd);
thd->net.net_skip_rest_factor= 2; // skip at most 2*max_packet_size
thd->password= test(passwd_len); // remember for error messages thd->password= test(passwd_len); // remember for error messages
/* Ready to handle queries */ /* Ready to handle queries */
DBUG_RETURN(0); DBUG_RETURN(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment