Bug#25471090: MYSQL USE AFTER FREE
Description:- Mysql client crashes when trying to connect to a fake server which is sending incorrect packets. Analysis:- Mysql client crashes when it tries to read server version details. Fix:- A check is added in "red_one_row()".
This commit is contained in:
parent
e585decb45
commit
e4784703ee
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -561,6 +561,7 @@ void my_thread_end(void);
|
||||
|
||||
#ifdef _global_h
|
||||
ulong STDCALL net_field_length(uchar **packet);
|
||||
ulong STDCALL net_field_length_checked(uchar **packet, ulong max_length);
|
||||
my_ulonglong net_field_length_ll(uchar **packet);
|
||||
uchar *net_store_length(uchar *pkg, ulonglong length);
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
/* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -1723,18 +1723,20 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
|
||||
end_pos=pos+pkt_len;
|
||||
for (field=0 ; field < fields ; field++)
|
||||
{
|
||||
if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
|
||||
len=(ulong) net_field_length_checked(&pos, (ulong)(end_pos - pos));
|
||||
if (pos > end_pos)
|
||||
{
|
||||
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len == NULL_LENGTH)
|
||||
{ /* null field */
|
||||
row[field] = 0;
|
||||
*lengths++=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len > (ulong) (end_pos - pos))
|
||||
{
|
||||
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
|
||||
return -1;
|
||||
}
|
||||
row[field] = (char*) pos;
|
||||
pos+=len;
|
||||
*lengths++=len;
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* Copyright (c) 2000-2003, 2007 MySQL AB
|
||||
Use is subject to license terms
|
||||
/* Copyright (c) 2000, 2018 Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -46,6 +45,40 @@ ulong STDCALL net_field_length(uchar **packet)
|
||||
return (ulong) uint4korr(pos+1);
|
||||
}
|
||||
|
||||
/* The same as above but with max length check */
|
||||
ulong STDCALL net_field_length_checked(uchar **packet, ulong max_length)
|
||||
{
|
||||
ulong len;
|
||||
uchar *pos= (uchar *)*packet;
|
||||
|
||||
if (*pos < 251)
|
||||
{
|
||||
(*packet)++;
|
||||
len= (ulong) *pos;
|
||||
return (len > max_length) ? max_length : len;
|
||||
}
|
||||
if (*pos == 251)
|
||||
{
|
||||
(*packet)++;
|
||||
return NULL_LENGTH;
|
||||
}
|
||||
if (*pos == 252)
|
||||
{
|
||||
(*packet)+=3;
|
||||
len= (ulong) uint2korr(pos+1);
|
||||
return (len > max_length) ? max_length : len;
|
||||
}
|
||||
if (*pos == 253)
|
||||
{
|
||||
(*packet)+=4;
|
||||
len= (ulong) uint3korr(pos+1);
|
||||
return (len > max_length) ? max_length : len;
|
||||
}
|
||||
(*packet)+=9; /* Must be 254 when here */
|
||||
len= (ulong) uint4korr(pos+1);
|
||||
return (len > max_length) ? max_length : len;
|
||||
}
|
||||
|
||||
/* The same as above but returns longlong */
|
||||
my_ulonglong net_field_length_ll(uchar **packet)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user