fix CVE-2020-13249
This commit is contained in:
parent
4b3c3e54b4
commit
006dabc742
172
0001-CVE-2020-13249.patch
Normal file
172
0001-CVE-2020-13249.patch
Normal file
@ -0,0 +1,172 @@
|
||||
From 2759b87d72926b7c9b5426437a7c8dd15ff57945 Mon Sep 17 00:00:00 2001
|
||||
From: Sergei Golubchik <serg@mariadb.org>
|
||||
Date: Thu, 7 May 2020 14:57:00 +0200
|
||||
Subject: [PATCH] sanity checks for client-supplied OK packet content
|
||||
reason: Fix CVE-2020-13249
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/mariadb-corporation/mariadb-connector-c/commit/2759b87d72926b7c9b5426437a7c8dd15ff57945
|
||||
|
||||
reported by Matthias Kaiser, Apple Information Security
|
||||
Signed-off-by: Sergei Golubchik <serg@mariadb.org>
|
||||
---
|
||||
libmariadb/mariadb_lib.c | 55 +++++++++++++++++++++++++++-------------
|
||||
1 file changed, 37 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c
|
||||
index b7316b2..877c216 100644
|
||||
--- a/libmariadb/mariadb_lib.c
|
||||
+++ b/libmariadb/mariadb_lib.c
|
||||
@@ -75,6 +75,8 @@
|
||||
#define ASYNC_CONTEXT_DEFAULT_STACK_SIZE (4096*15)
|
||||
#define MA_RPL_VERSION_HACK "5.5.5-"
|
||||
|
||||
+#define CHARSET_NAME_LEN 64
|
||||
+
|
||||
#undef max_allowed_packet
|
||||
#undef net_buffer_length
|
||||
extern ulong max_allowed_packet; /* net.c */
|
||||
@@ -1979,6 +1981,7 @@ mysql_send_query(MYSQL* mysql, const char* query, unsigned long length)
|
||||
|
||||
int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
{
|
||||
+ uchar *end= mysql->net.read_pos+length;
|
||||
size_t item_len;
|
||||
mysql->affected_rows= net_field_length_ll(&pos);
|
||||
mysql->insert_id= net_field_length_ll(&pos);
|
||||
@@ -1986,10 +1989,14 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
pos+=2;
|
||||
mysql->warning_count=uint2korr(pos);
|
||||
pos+=2;
|
||||
- if (pos < mysql->net.read_pos+length)
|
||||
+ if (pos > end)
|
||||
+ goto corrupted;
|
||||
+ if (pos < end)
|
||||
{
|
||||
if ((item_len= net_field_length(&pos)))
|
||||
mysql->info=(char*) pos;
|
||||
+ if (pos + item_len > end)
|
||||
+ goto corrupted;
|
||||
|
||||
/* check if server supports session tracking */
|
||||
if (mysql->server_capabilities & CLIENT_SESSION_TRACKING)
|
||||
@@ -2000,23 +2007,26 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
if (mysql->server_status & SERVER_SESSION_STATE_CHANGED)
|
||||
{
|
||||
int i;
|
||||
- if (pos < mysql->net.read_pos + length)
|
||||
+ if (pos < end)
|
||||
{
|
||||
LIST *session_item;
|
||||
MYSQL_LEX_STRING *str= NULL;
|
||||
enum enum_session_state_type si_type;
|
||||
uchar *old_pos= pos;
|
||||
- size_t item_len= net_field_length(&pos); /* length for all items */
|
||||
+
|
||||
+ item_len= net_field_length(&pos); /* length for all items */
|
||||
+ if (pos + item_len > end)
|
||||
+ goto corrupted;
|
||||
+ end= pos + item_len;
|
||||
|
||||
/* length was already set, so make sure that info will be zero terminated */
|
||||
if (mysql->info)
|
||||
*old_pos= 0;
|
||||
|
||||
- while (item_len > 0)
|
||||
+ while (pos < end)
|
||||
{
|
||||
size_t plen;
|
||||
char *data;
|
||||
- old_pos= pos;
|
||||
si_type= (enum enum_session_state_type)net_field_length(&pos);
|
||||
switch(si_type) {
|
||||
case SESSION_TRACK_SCHEMA:
|
||||
@@ -2025,15 +2035,14 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
case SESSION_TRACK_SYSTEM_VARIABLES:
|
||||
net_field_length(&pos); /* ignore total length, item length will follow next */
|
||||
plen= net_field_length(&pos);
|
||||
+ if (pos + plen > end)
|
||||
+ goto corrupted;
|
||||
if (!ma_multi_malloc(0,
|
||||
&session_item, sizeof(LIST),
|
||||
&str, sizeof(MYSQL_LEX_STRING),
|
||||
&data, plen,
|
||||
NULL))
|
||||
- {
|
||||
- SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||
- return -1;
|
||||
- }
|
||||
+ goto oom;
|
||||
str->length= plen;
|
||||
str->str= data;
|
||||
memcpy(str->str, (char *)pos, plen);
|
||||
@@ -2056,29 +2065,28 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
if (!strncmp(str->str, "character_set_client", str->length))
|
||||
set_charset= 1;
|
||||
plen= net_field_length(&pos);
|
||||
+ if (pos + plen > end)
|
||||
+ goto corrupted;
|
||||
if (!ma_multi_malloc(0,
|
||||
&session_item, sizeof(LIST),
|
||||
&str, sizeof(MYSQL_LEX_STRING),
|
||||
&data, plen,
|
||||
NULL))
|
||||
- {
|
||||
- SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||
- return -1;
|
||||
- }
|
||||
+ goto oom;
|
||||
str->length= plen;
|
||||
str->str= data;
|
||||
memcpy(str->str, (char *)pos, plen);
|
||||
pos+= plen;
|
||||
session_item->data= str;
|
||||
mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item);
|
||||
- if (set_charset &&
|
||||
+ if (set_charset && str->length < CHARSET_NAME_LEN &&
|
||||
strncmp(mysql->charset->csname, str->str, str->length) != 0)
|
||||
{
|
||||
- char cs_name[64];
|
||||
- MARIADB_CHARSET_INFO *cs_info;
|
||||
+ char cs_name[CHARSET_NAME_LEN];
|
||||
+ const MARIADB_CHARSET_INFO *cs_info;
|
||||
memcpy(cs_name, str->str, str->length);
|
||||
cs_name[str->length]= 0;
|
||||
- if ((cs_info = (MARIADB_CHARSET_INFO *)mysql_find_charset_name(cs_name)))
|
||||
+ if ((cs_info = mysql_find_charset_name(cs_name)))
|
||||
mysql->charset= cs_info;
|
||||
}
|
||||
}
|
||||
@@ -2086,10 +2094,11 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
default:
|
||||
/* not supported yet */
|
||||
plen= net_field_length(&pos);
|
||||
+ if (pos + plen > end)
|
||||
+ goto corrupted;
|
||||
pos+= plen;
|
||||
break;
|
||||
}
|
||||
- item_len-= (pos - old_pos);
|
||||
}
|
||||
}
|
||||
for (i= SESSION_TRACK_BEGIN; i <= SESSION_TRACK_END; i++)
|
||||
@@ -2101,6 +2110,16 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length)
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
+
|
||||
+oom:
|
||||
+ ma_clear_session_state(mysql);
|
||||
+ SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||
+ return -1;
|
||||
+
|
||||
+corrupted:
|
||||
+ ma_clear_session_state(mysql);
|
||||
+ SET_CLIENT_ERROR(mysql, CR_MALFORMED_PACKET, SQLSTATE_UNKNOWN, 0);
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
int mthd_my_read_query_result(MYSQL *mysql)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: mariadb-connector-c
|
||||
Version: 3.0.6
|
||||
Release: 7
|
||||
Release: 8
|
||||
Summary: MariaDB connector library in C
|
||||
License: LGPLv2+
|
||||
URL: https://github.com/MariaDB/mariadb-connector-c
|
||||
@ -11,6 +11,8 @@ BuildRequires: cmake git
|
||||
Provides: %{name}-config%{?_isa} %{name}-config
|
||||
Obsoletes: %{name}-config
|
||||
|
||||
Patch1: 0001-CVE-2020-13249.patch
|
||||
|
||||
%description
|
||||
This package is used for connecting C/C++ programs to MariaDB and
|
||||
MySQL database.
|
||||
@ -91,6 +93,9 @@ end
|
||||
%{_libdir}/*.so
|
||||
|
||||
%changelog
|
||||
* Tue Jul 27 2021 yanglongkang <yanglongkang@huawei.com> - 3.0.6-8
|
||||
- fix CVE-2020-13249
|
||||
|
||||
* Tue Nov 10 2020 yanglongkang <yanglongkang@huawei.com> - 3.0.6-7
|
||||
- Temporarily roll back the version 3.0.6 to resolve the conflict
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user