Bug #2274 mysqld gets SIGSEGV during processing of malformed COM_EXECUTE packet
Submitted: 4 Jan 2004 4:25 Modified: 15 Mar 2004 9:48
Reporter: Konstantin Osipov (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.1, 5.0 OS:Any (All)
Assigned to: Michael Widenius

[4 Jan 2004 4:25] Konstantin Osipov
Description:
The problem is that we don't check packet length of COM_EXECUTE packet.
Add +4 (zero) bytes to COM_EXECUTE packet right after statement id and the server will SIGSEGV
with the following diagnostics:

==20326== Use of uninitialised value of size 4
==20326==    at 0x81B3FE6: insert_params(Prepared_statement*, unsigned char*, unsigned char*) (sql_prepare.cc:473)
==20326==    by 0x81B411C: setup_params_data(Prepared_statement*) (sql_prepare.cc:506)
==20326==    by 0x81B50BA: mysql_stmt_execute(THD*, char*) (sql_prepare.cc:1022)
==20326==    by 0x816CE3B: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1364)
==20326==    by 0x816C8C0: do_command(THD*) (sql_parse.cc:1223)
==20326==    by 0x816BD95: handle_one_connection (sql_parse.cc:989)
==20326==    by 0x4037A53E: thread_wrapper (vg_libpthread.c:667)
==20326==    by 0x40177104: do__quit (vg_scheduler.c:2146)
==20326== 
==20326== Thread 3:
==20326== Jump to the invalid address stated on the next line
==20326==    at 0x0: ???
==20326==    by 0x81B411C: setup_params_data(Prepared_statement*) (sql_prepare.cc:506)
==20326==    by 0x81B50BA: mysql_stmt_execute(THD*, char*) (sql_prepare.cc:1022)
==20326==    by 0x816CE3B: dispatch_command(enum_server_command, THD*, char*, unsigned) (sql_parse.cc:1364)
==20326==    by 0x816C8C0: do_command(THD*) (sql_parse.cc:1223)
==20326==    by 0x816BD95: handle_one_connection (sql_parse.cc:989)
==20326==    by 0x4037A53E: thread_wrapper (vg_libpthread.c:667)

The bug is not something rare: it will be easy the case when new (5.0 + cursors) client library will be used against old 4.1.1 and 5.0.0 servers.

How to repeat:
Patch client library with the following patch:
===== libmysql.c 1.203 vs edited =====
--- 1.203/libmysql/libmysql.c   Tue Dec 23 18:46:55 2003
+++ edited/libmysql.c   Sun Jan  4 15:05:53 2004
@@ -2004,14 +2004,15 @@
 {
   MYSQL *mysql= stmt->mysql;
   NET  *net= &mysql->net;
-  char buff[MYSQL_STMT_HEADER];
+  char buff[8];
   DBUG_ENTER("execute");
   DBUG_PRINT("enter",("packet: %s, length :%d",packet ? packet :" ", length));
 
   mysql->last_used_con= mysql;
   int4store(buff, stmt->stmt_id);              /* Send stmt id to server */
+  int4store(buff+4, 0);
   if (cli_advanced_command(mysql, COM_EXECUTE, buff, 
-                           MYSQL_STMT_HEADER, packet, 
+                           sizeof(buff), packet, 
                            length, 1) ||
       (*mysql->methods->read_query_result)(mysql))
   {

And run client_test linked with patched libmysql against the server.

Suggested fix:
We need to overhaul COM_EXECUTE command processing from security standpoint.
[15 Mar 2004 2:43] Michael Widenius
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

This is a already fixed differently in the current 4.1 tree
[15 Mar 2004 9:48] Konstantin Osipov
Fixed in 4.1 tree: bk commit - 4.1 tree (konstantin:1.1790)