Commit eef21014 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-11933 Wrong usage of linked list in mysql_prune_stmt_list

mysql_prune_stmt_list() was walking the list following
element->next pointers, but inside the loop it was invoking
list_add(element) that modified element->next. So, mysql_prune_stmt_list()
failed to visit and reset all elements, and some of them were left
with pointers to invalid MYSQL.
parent ac78927a
/* Copyright (c) 2003, 2016, Oracle and/or its affiliates.
Copyright (c) 2009, 2016, MariaDB
Copyright (c) 2009, 2017, MariaDB
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
......@@ -3819,8 +3819,6 @@ static void mysql_close_free(MYSQL *mysql)
static void mysql_prune_stmt_list(MYSQL *mysql)
{
LIST *element= mysql->stmts;
LIST *pruned_list= 0;
for (; element; element= element->next)
{
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
......@@ -3830,14 +3828,9 @@ static void mysql_prune_stmt_list(MYSQL *mysql)
stmt->last_errno= CR_SERVER_LOST;
strmov(stmt->last_error, ER(CR_SERVER_LOST));
strmov(stmt->sqlstate, unknown_sqlstate);
}
else
{
pruned_list= list_add(pruned_list, element);
mysql->stmts= list_delete(mysql->stmts, element);
}
}
mysql->stmts= pruned_list;
}
......
/* Copyright (c) 2002, 2012, Oracle and/or its affiliates.
Copyright (c) 2008, 2012, Monty Program Ab
/* Copyright (c) 2002, 2014, Oracle and/or its affiliates.
Copyright (c) 2008, 2017, MariaDB
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
......@@ -19031,6 +19031,49 @@ static void test_mdev4326()
myquery(rc);
}
/**
BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
*/
static void test_bug17512527()
{
MYSQL *conn;
MYSQL_STMT *stmt1, *stmt2;
unsigned long thread_id;
char query[MAX_TEST_QUERY_LENGTH];
int rc;
conn= client_connect(0, MYSQL_PROTOCOL_SOCKET, 1);
stmt1 = mysql_stmt_init(conn);
check_stmt(stmt1);
rc= mysql_stmt_prepare(stmt1, STRING_WITH_LEN("SELECT 1"));
check_execute(stmt1, rc);
stmt2 = mysql_stmt_init(conn);
check_stmt(stmt2);
thread_id= mysql_thread_id(conn);
sprintf(query, "KILL %lu", thread_id);
if (thread_query(query))
exit(1);
rc= mysql_stmt_prepare(stmt2, STRING_WITH_LEN("SELECT 2"));
check_execute(stmt2, rc);
rc= mysql_stmt_execute(stmt1);
check_execute_r(stmt1, rc);
rc= mysql_stmt_execute(stmt2);
check_execute(stmt2, rc);
mysql_close(conn);
mysql_stmt_close(stmt2);
mysql_stmt_close(stmt1);
}
static struct my_tests_st my_tests[]= {
{ "disable_query_logs", disable_query_logs },
{ "test_view_sp_list_fields", test_view_sp_list_fields },
......@@ -19297,6 +19340,9 @@ static struct my_tests_st my_tests[]= {
{ "test_bug13001491", test_bug13001491 },
{ "test_mdev4326", test_mdev4326 },
{ "test_ps_sp_out_params", test_ps_sp_out_params },
#ifndef _WIN32
{ "test_bug17512527", test_bug17512527},
#endif
{ 0, 0 }
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment