Skip to content

Commit e478470

Browse files
author
Arun Kuruvila
committed
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()".
1 parent e585dec commit e478470

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

include/mysql_com.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -561,6 +561,7 @@ void my_thread_end(void);
561561

562562
#ifdef _global_h
563563
ulong STDCALL net_field_length(uchar **packet);
564+
ulong STDCALL net_field_length_checked(uchar **packet, ulong max_length);
564565
my_ulonglong net_field_length_ll(uchar **packet);
565566
uchar *net_store_length(uchar *pkg, ulonglong length);
566567
#endif

sql-common/client.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
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)
17231723
end_pos=pos+pkt_len;
17241724
for (field=0 ; field < fields ; field++)
17251725
{
1726-
if ((len=(ulong) net_field_length(&pos)) == NULL_LENGTH)
1726+
len=(ulong) net_field_length_checked(&pos, (ulong)(end_pos - pos));
1727+
if (pos > end_pos)
1728+
{
1729+
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
1730+
return -1;
1731+
}
1732+
1733+
if (len == NULL_LENGTH)
17271734
{ /* null field */
17281735
row[field] = 0;
17291736
*lengths++=0;
17301737
}
17311738
else
17321739
{
1733-
if (len > (ulong) (end_pos - pos))
1734-
{
1735-
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
1736-
return -1;
1737-
}
17381740
row[field] = (char*) pos;
17391741
pos+=len;
17401742
*lengths++=len;

sql-common/pack.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
/* Copyright (c) 2000-2003, 2007 MySQL AB
2-
Use is subject to license terms
1+
/* Copyright (c) 2000, 2018 Oracle and/or its affiliates. All rights reserved.
32
43
This program is free software; you can redistribute it and/or modify
54
it under the terms of the GNU General Public License as published by
@@ -46,6 +45,40 @@ ulong STDCALL net_field_length(uchar **packet)
4645
return (ulong) uint4korr(pos+1);
4746
}
4847

48+
/* The same as above but with max length check */
49+
ulong STDCALL net_field_length_checked(uchar **packet, ulong max_length)
50+
{
51+
ulong len;
52+
uchar *pos= (uchar *)*packet;
53+
54+
if (*pos < 251)
55+
{
56+
(*packet)++;
57+
len= (ulong) *pos;
58+
return (len > max_length) ? max_length : len;
59+
}
60+
if (*pos == 251)
61+
{
62+
(*packet)++;
63+
return NULL_LENGTH;
64+
}
65+
if (*pos == 252)
66+
{
67+
(*packet)+=3;
68+
len= (ulong) uint2korr(pos+1);
69+
return (len > max_length) ? max_length : len;
70+
}
71+
if (*pos == 253)
72+
{
73+
(*packet)+=4;
74+
len= (ulong) uint3korr(pos+1);
75+
return (len > max_length) ? max_length : len;
76+
}
77+
(*packet)+=9; /* Must be 254 when here */
78+
len= (ulong) uint4korr(pos+1);
79+
return (len > max_length) ? max_length : len;
80+
}
81+
4982
/* The same as above but returns longlong */
5083
my_ulonglong net_field_length_ll(uchar **packet)
5184
{

0 commit comments

Comments
 (0)