1 |
commit: 83e075e9a297e8e1b0014f96969d477e053e2595 |
2 |
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Mar 1 20:19:35 2017 +0000 |
4 |
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Mar 1 20:19:35 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=83e075e9 |
7 |
|
8 |
Add patch to mysql 5.5 branch for CVE-2017-3302 |
9 |
|
10 |
00000_index.txt | 6 ++ |
11 |
20023_all_mysql-5.5-CVE-2017-3302.patch | 142 ++++++++++++++++++++++++++++++++ |
12 |
2 files changed, 148 insertions(+) |
13 |
|
14 |
diff --git a/00000_index.txt b/00000_index.txt |
15 |
index 8f3a4c3..3c8627f 100644 |
16 |
--- a/00000_index.txt |
17 |
+++ b/00000_index.txt |
18 |
@@ -946,3 +946,9 @@ |
19 |
@ver 10.01.11.00 to 10.01.11.99 |
20 |
@pn mariadb |
21 |
@@ Fix server gssapi plugin compile with heimdal |
22 |
+ |
23 |
+@patch 20023_all_mysql-5.5-CVE-2017-3302.patch |
24 |
+@ver 5.05.45.00 to 5.05.54.99 |
25 |
+@pn mysql |
26 |
+@@ Fix use-after-free in mysql_prune_stmt_list |
27 |
+@@ Back ported from mysql 5.6; Oracle bug 17512527 |
28 |
|
29 |
diff --git a/20023_all_mysql-5.5-CVE-2017-3302.patch b/20023_all_mysql-5.5-CVE-2017-3302.patch |
30 |
new file mode 100644 |
31 |
index 0000000..23bff1a |
32 |
--- /dev/null |
33 |
+++ b/20023_all_mysql-5.5-CVE-2017-3302.patch |
34 |
@@ -0,0 +1,142 @@ |
35 |
+From 1037977895aa4a145de16719df0a2375c71bbf26 Mon Sep 17 00:00:00 2001 |
36 |
+From: Nisha Gopalakrishnan <nisha.gopalakrishnan@××××××.com> |
37 |
+Date: Mon, 21 Jul 2014 21:21:15 +0530 |
38 |
+Subject: [PATCH] BUG#17512527: LIST HANDLING INCORRECT IN |
39 |
+ MYSQL_PRUNE_STMT_LIST() |
40 |
+ |
41 |
+Analysis: |
42 |
+--------- |
43 |
+Invalid memory access maybe observed when using prepared statements if: |
44 |
+a) The mysql client connection is lost after statement preparation |
45 |
+ is complete and |
46 |
+b) There is at least one statement which is in initialized state but |
47 |
+ not prepared yet. |
48 |
+ |
49 |
+When the client detects a closed connection, it calls end_server() |
50 |
+to shutdown the connection. As part of the clean up, the |
51 |
+mysql_prune_stmt_list() removes the statements which has transitioned |
52 |
+beyond the initialized state and retains only the statements which |
53 |
+are in a initialized state. During this processing, the initialized |
54 |
+statements are moved from 'mysql->stmts' to a temporary 'pruned_list'. |
55 |
+When moving the first 'INIT_DONE' element to the pruned_list, |
56 |
+'element->next' is set to NULL. Hence the rest of the list is never |
57 |
+traversed and the statements which have transitioned beyond the |
58 |
+initialized state are never invalidated. |
59 |
+ |
60 |
+When the mysql_stmt_close() is called for the statement which is not |
61 |
+invalidated; the statements list is updated in order to remove the |
62 |
+statement. This would end up accessing freed memory(freed by the |
63 |
+mysql_stmt_close() for a previous statement in the list). |
64 |
+ |
65 |
+Fix: |
66 |
+--- |
67 |
+mysql_prune_stmt_list() called list_add() incorrectly to create a |
68 |
+temporary list. The use case of list_add() is to add a single |
69 |
+element to the front of the doubly linked list. |
70 |
+mysql_prune_stmt_list() called list_add() by passing an entire |
71 |
+list as the 'element'. |
72 |
+ |
73 |
+mysql_prune_stmt_list() now uses list_delete() to remove the |
74 |
+statement which has transitioned beyond the initialized phase. |
75 |
+Thus the statement list would contain only elements where the |
76 |
+the state of the statement is initialized. |
77 |
+ |
78 |
+Note: Run the test with valgrind-mysqltest and leak-check=full |
79 |
+option to see the invalid memory access. |
80 |
+ |
81 |
+Back-ported to MySQL 5.5 branch by Balint Reczey |
82 |
+ |
83 |
+Conflicts: |
84 |
+ sql-common/client.c |
85 |
+ tests/mysql_client_test.c |
86 |
+--- |
87 |
+ sql-common/client.c | 11 +++++++---- |
88 |
+ tests/mysql_client_test.c | 41 +++++++++++++++++++++++++++++++++++++++++ |
89 |
+ 2 files changed, 48 insertions(+), 4 deletions(-) |
90 |
+ |
91 |
+diff --git a/sql-common/client.c b/sql-common/client.c |
92 |
+index cd9b6a7..be60cc1 100644 |
93 |
+--- a/sql-common/client.c |
94 |
++++ b/sql-common/client.c |
95 |
+@@ -3790,12 +3790,15 @@ static void mysql_close_free(MYSQL *mysql) |
96 |
+ */ |
97 |
+ static void mysql_prune_stmt_list(MYSQL *mysql) |
98 |
+ { |
99 |
+- LIST *element= mysql->stmts; |
100 |
+- LIST *pruned_list= 0; |
101 |
++ LIST *pruned_list= NULL; |
102 |
+ |
103 |
+- for (; element; element= element->next) |
104 |
++ while(mysql->stmts) |
105 |
+ { |
106 |
+- MYSQL_STMT *stmt= (MYSQL_STMT *) element->data; |
107 |
++ LIST *element= mysql->stmts; |
108 |
++ MYSQL_STMT *stmt; |
109 |
++ |
110 |
++ mysql->stmts= list_delete(element, element); |
111 |
++ stmt= (MYSQL_STMT *) element->data; |
112 |
+ if (stmt->state != MYSQL_STMT_INIT_DONE) |
113 |
+ { |
114 |
+ stmt->mysql= 0; |
115 |
+diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c |
116 |
+index e600d82..d3f3899 100644 |
117 |
+--- a/tests/mysql_client_test.c |
118 |
++++ b/tests/mysql_client_test.c |
119 |
+@@ -18648,6 +18648,46 @@ static void test_bug13001491() |
120 |
+ myquery(rc); |
121 |
+ } |
122 |
+ |
123 |
++static void test_bug17512527() |
124 |
++{ |
125 |
++ MYSQL *conn1, *conn2; |
126 |
++ MYSQL_STMT *stmt1, *stmt2; |
127 |
++ const char *stmt1_txt= "SELECT NOW();"; |
128 |
++ const char *stmt2_txt= "SELECT 1;"; |
129 |
++ unsigned long thread_id; |
130 |
++ char query[MAX_TEST_QUERY_LENGTH]; |
131 |
++ int rc; |
132 |
++ |
133 |
++ conn1= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1); |
134 |
++ conn2= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 0); |
135 |
++ |
136 |
++ stmt1 = mysql_stmt_init(conn1); |
137 |
++ check_stmt(stmt1); |
138 |
++ rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt)); |
139 |
++ check_execute(stmt1, rc); |
140 |
++ |
141 |
++ thread_id= mysql_thread_id(conn1); |
142 |
++ sprintf(query, "KILL %lu", thread_id); |
143 |
++ if (thread_query(query)) |
144 |
++ exit(1); |
145 |
++ |
146 |
++ /* |
147 |
++ After the connection is killed, the connection is |
148 |
++ re-established due to the reconnect flag. |
149 |
++ */ |
150 |
++ stmt2 = mysql_stmt_init(conn1); |
151 |
++ check_stmt(stmt2); |
152 |
++ |
153 |
++ rc= mysql_stmt_prepare(stmt2, stmt2_txt, strlen(stmt2_txt)); |
154 |
++ check_execute(stmt1, rc); |
155 |
++ |
156 |
++ mysql_stmt_close(stmt2); |
157 |
++ mysql_stmt_close(stmt1); |
158 |
++ |
159 |
++ mysql_close(conn1); |
160 |
++ mysql_close(conn2); |
161 |
++} |
162 |
++ |
163 |
+ |
164 |
+ static struct my_tests_st my_tests[]= { |
165 |
+ { "disable_query_logs", disable_query_logs }, |
166 |
+@@ -18911,6 +18951,7 @@ static struct my_tests_st my_tests[]= { |
167 |
+ { "test_bug12337762", test_bug12337762 }, |
168 |
+ { "test_bug11754979", test_bug11754979 }, |
169 |
+ { "test_bug13001491", test_bug13001491 }, |
170 |
++ { "test_bug17512527", test_bug17512527}, |
171 |
+ { 0, 0 } |
172 |
+ }; |
173 |
+ |
174 |
+-- |
175 |
+2.1.4 |
176 |
+ |