summaryrefslogtreecommitdiff
path: root/sql-common
diff options
context:
space:
mode:
authorArun Kuruvila <arun.kuruvila@oracle.com>2018-02-12 15:19:43 +0530
committerArun Kuruvila <arun.kuruvila@oracle.com>2018-02-12 15:19:43 +0530
commite4784703ee44d0a0a497a1a411dea20987d501ad (patch)
tree1f28ecfa226f27d3f65abd9e9c210504d3edcba1 /sql-common
parente585decb459740ec53b1ac1b85f332f7bd3c8ccf (diff)
downloadmariadb-git-e4784703ee44d0a0a497a1a411dea20987d501ad.tar.gz
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()".
Diffstat (limited to 'sql-common')
-rw-r--r--sql-common/client.c16
-rw-r--r--sql-common/pack.c37
2 files changed, 44 insertions, 9 deletions
diff --git a/sql-common/client.c b/sql-common/client.c
index 759d95117cb..9972ca741f2 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -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;
diff --git a/sql-common/pack.c b/sql-common/pack.c
index 02e91b5c3e3..57ff55689a2 100644
--- a/sql-common/pack.c
+++ b/sql-common/pack.c
@@ -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)
{