From 27b2f3d1f1550dfaee0f63a331a406ab31c1b37e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 9 May 2018 23:07:57 +0200 Subject: [PATCH] various checks for corrupted packets in the protocol also: check the return value of unpack_fields() --- libmariadb/mariadb_lib.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index a01038e9..68b6f9c6 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -768,6 +768,9 @@ unpack_fields(MYSQL_DATA *data,MA_MEM_ROOT *alloc,uint fields, for (row=data->data; row ; row = row->next,field++) { + if (field >= result + fields) + goto error; + for (i=0; i < field_count; i++) { switch(row->data[i][0]) { @@ -809,8 +812,14 @@ unpack_fields(MYSQL_DATA *data,MA_MEM_ROOT *alloc,uint fields, field->def=0; field->max_length= 0; } + if (field < result + fields) + goto error; free_rows(data); /* Free old data */ return(result); +error: + free_rows(data); + ma_free_root(alloc, MYF(0)); + return(0); } @@ -867,7 +876,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, else { cur->data[field] = to; - if (len > (ulong) (end_to - to)) + if (len > (ulong)(end_to - to) || to > end_to) { free_rows(result); SET_CLIENT_ERROR(mysql, CR_UNKNOWN_ERROR, SQLSTATE_UNKNOWN, 0); @@ -936,7 +945,7 @@ int mthd_my_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) } else { - if (len > (ulong) (end_pos - pos)) + if (len > (ulong) (end_pos - pos) || pos > end_pos) { mysql->net.last_errno=CR_UNKNOWN_ERROR; strcpy(mysql->net.last_error,ER(mysql->net.last_errno)); @@ -2446,13 +2455,17 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) } result->field_alloc=mysql->field_alloc; mysql->fields=0; + result->eof=1; result->field_count = (uint) query->rows; result->fields= unpack_fields(query,&result->field_alloc, result->field_count,1, (my_bool) test(mysql->server_capabilities & CLIENT_LONG_FLAG)); - result->eof=1; - return(result); + if (result->fields) + return(result); + + free(result); + return(NULL); } /* List all running processes (threads) in server */