aboutsummaryrefslogtreecommitdiff
path: root/databases/mariadb55-client/files/patch-CVE-2017-3302
blob: 87d08f1d8f93e735998f2e89d17c427ade3da31d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From eef21014898d61e77890359d6546d4985d829ef6 Mon Sep 17 00:00:00 2001
From: Sergei Golubchik <serg@mariadb.org>
Date: Thu, 16 Feb 2017 11:32:47 +0100
Subject: [PATCH] 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.
---
 sql-common/client.c       | 11 ++---------
 tests/mysql_client_test.c | 50 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/sql-common/client.c b/sql-common/client.c
index c2e0cc3..b348afc 100644
--- sql-common/client.c.orig
+++ sql-common/client.c
@@ -1,5 +1,5 @@
 /* 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;
 }
 
 
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 446018e..f62545d 100644
--- tests/mysql_client_test.c.orig
+++ tests/mysql_client_test.c
@@ -1,5 +1,5 @@
-/* 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 }
 };