Bug #27513 mysql 5.0.x + NULL pointer DoS
Submitted: 29 Mar 2007 8:47 Modified: 27 Jun 2007 13:17
Reporter: Neil Kettle Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Errors Severity:S1 (Critical)
Version:5.0.26, 5.0.34, 5.0.40-debug OS:Linux (Gentoo Linux)
Assigned to: Georgi Kodinov CPU Architecture:Any
Tags: Contribution, DoS

[29 Mar 2007 8:47] Neil Kettle
Description:
Executing the following query results in a NULL pointer derefence.

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.34-log Gentoo Linux mysql-5.0.34

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)));

0xb7f6d410 in __kernel_vsyscall ()
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1277277296 (LWP 15719)]
0x081215b2 in my_decimal2decimal (from=0x0, to=0x8b3b380) at my_decimal.h:198
198       *to= *from;
(gdb) bt
#0  0x081215b2 in my_decimal2decimal (from=0x0, to=0x8b3b380) at
my_decimal.h:198
#1  0x08146b58 in in_decimal::set (this=0x8b3b2f0, pos=1, item=0x8b3a120) at
item_cmpfunc.cc:2171
#2  0x0814e5cc in Item_func_in::fix_length_and_dec (this=0x8b3a2f8) at
item_cmpfunc.cc:2483
#3  0x0813cb3a in Item_func::fix_fields (this=0x8b3a2f8, thd=0x8b06dc0,
ref=0x8b3b1c0) at item_func.cc:189
#4  0x08148c4a in Item_func_in::fix_fields (this=0x8b3a2f8, thd=0x8b06dc0,
ref=0x8b3b1c0)
    at item_cmpfunc.cc:2406
#5  0x081e4e1c in setup_conds (thd=0x8b06dc0, tables=0x8b39708,
leaves=0x8b39708, conds=0x8b3b1c0)
    at sql_base.cc:4951
#6  0x08216495 in setup_without_group (thd=0x8b06dc0,
ref_pointer_array=0x8b3b210, tables=0x8b39708, 
    leaves=0x8b39708, fields=@0x8b07118, all_fields=@0x8b3b14c,
conds=0x8b3b1c0, order=0x0, group=0x0, 
    hidden_group_fields=0x8b3b132) at sql_select.cc:288
#7  0x082109b9 in JOIN::prepare (this=0x8b3a430, rref_pointer_array=0x8b071a8,
tables_init=0x8b39708, 
    wild_num=0, conds_init=0x8b3a2f8, og_num=0, order_init=0x0, group_init=0x0,
having_init=0x0, 
    proc_param_init=0x0, select_lex_arg=0x8b0708c, unit_arg=0x8b06e60) at
sql_select.cc:345
#8  0x08211320 in mysql_select (thd=0x8b06dc0, rref_pointer_array=0x8b071a8,
tables=0x8b39708, wild_num=0, 
    fields=@0x8b07118, conds=0x8b3a2f8, og_num=0, order=0x0, group=0x0,
having=0x0, proc_param=0x0, 
    select_options=2156153344, result=0x8b3a420, unit=0x8b06e60,
select_lex=0x8b0708c)
    at sql_select.cc:2023
#9  0x08214b6e in handle_select (thd=0x8b06dc0, lex=0x8b06dfc,
result=0x8b3a420, 
    setup_tables_done_option=0) at sql_select.cc:256
#10 0x081b9ddd in mysql_execute_command (thd=0x8b06dc0) at sql_parse.cc:2614
#11 0x081c13f2 in mysql_parse (thd=0x8b06dc0, 
    inBuf=0x8b39598 "SELECT id from example WHERE id IN(1, (SELECT
IF(1=0,1,2/0)))", length=61)
    at sql_parse.cc:5832
#12 0x081c34e9 in dispatch_command (command=COM_QUERY, thd=0x8b06dc0, 
    packet=0x8b35569 "SELECT id from example WHERE id IN(1, (SELECT
IF(1=0,1,2/0)))", packet_length=62)
    at sql_parse.cc:1774
#13 0x081c47f1 in do_command (thd=0x8b06dc0) at sql_parse.cc:1556
#14 0x081c56da in handle_one_connection (arg=0x8b06dc0) at sql_parse.cc:1187
#15 0xb7df070f in start_thread () from /lib/libpthread.so.0

How to repeat:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.34-log Gentoo Linux mysql-5.0.34

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)));

Suggested fix:
A functional patch is given below :-

*** item_cmpfunc.cc-new Fri Mar 23 15:39:41 2007
--- item_cmpfunc.cc-old Fri Mar 23 14:34:07 2007
***************
*** 2167,2173 ****
    dec->len= DECIMAL_BUFF_LENGTH;
    dec->fix_buffer_pointer();
    my_decimal *res= item->val_decimal(dec);
!   if (!item->null_value && res != dec)
      my_decimal2decimal(res, dec);
  }

--- 2167,2173 ----
    dec->len= DECIMAL_BUFF_LENGTH;
    dec->fix_buffer_pointer();
    my_decimal *res= item->val_decimal(dec);
!   if (res != dec)
      my_decimal2decimal(res, dec);
  }
[29 Mar 2007 9:30] Valeriy Kravchuk
Please, try to repeat with a newer version, 5.0.36/5.0.37 and, in case of the same failure, send a dump of your table. I can not repeat with simple test on 5.0.40-BK:

openxs@suse:~/dbs/5.0> bin/mysql -uroot test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.0.40 Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> create table example (id int);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into example values (1), (2), (3);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)));
+------+
| id   |
+------+
|    1 |
+------+
1 row in set (0.00 sec)
[29 Mar 2007 9:37] Andrey Hristov
Valeriy, I can repeat it on openSuSE 10.2, Version: '5.0.40-valgrind-max-debug'

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1257112688 (LWP 8469)]
in_decimal::set (this=0x8d0a720, pos=1, item=0x8d08480) at my_decimal.h:198
198       *to= *from;
(gdb)
(gdb) bt
#0  in_decimal::set (this=0x8d0a720, pos=1, item=0x8d08480) at my_decimal.h:198
#1  0x08183843 in Item_func_in::fix_length_and_dec (this=0x8d08810) at item_cmpfunc.cc:2764
#2  0x0816ad91 in Item_func::fix_fields (this=0x8d08810, thd=0x8c69900, ref=0x8d09744) at item_func.cc:189
#3  0x0817ad78 in Item_func_in::fix_fields (this=0x8d08810, thd=0x8c69900, ref=0x8d09744) at item_cmpfunc.cc:2662
#4  0x08219e97 in setup_conds (thd=0x8c69900, tables=0x8d076a0, leaves=0x8d076a0, conds=0x8d09744) at sql_base.cc:5195
#5  0x08236446 in JOIN::prepare (this=0x8d08960, rref_pointer_array=0x8c6a9e8, tables_init=0x8d076a0, wild_num=0, conds_init=0x8d08810, og_num=0, order_init=0x0, group_init=0x0, having_init=0x0, proc_param_init=0x0,
    select_lex_arg=0x8c6a8a4, unit_arg=0x8c6a664) at sql_select.cc:351
#6  0x0824876b in mysql_select (thd=0x8c69900, rref_pointer_array=0x8c6a9e8, tables=0x8d076a0, wild_num=0, fields=@0x8c6a93c, conds=0x8d08810, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0,
    select_options=2156153344, result=0x8ced280, unit=0x8c6a664, select_lex=0x8c6a8a4) at sql_select.cc:2140
#7  0x08248ccd in handle_select (thd=0x8c69900, lex=0x8c6a600, result=0x8ced280, setup_tables_done_option=0) at sql_select.cc:255
#8  0x081f4a93 in mysql_execute_command (thd=0x8c69900) at sql_parse.cc:2660
#9  0x081f59d8 in mysql_parse (thd=0x8c69900, inBuf=0x8d074c8 "SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)))", length=61) at sql_parse.cc:5931
#10 0x081f6576 in dispatch_command (command=COM_QUERY, thd=0x8c69900, packet=0x8c6ae81 "SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)))", packet_length=62) at sql_parse.cc:1798
#11 0x081f77b9 in do_command (thd=0x8c69900) at sql_parse.cc:1577
#12 0x081f8531 in handle_one_connection (arg=0x8c69900) at sql_parse.cc:1191
#13 0xb7eff112 in start_thread () from /lib/libpthread.so.0
#14 0xb7e1b2ee in clone () from /lib/libc.so.6
[29 Mar 2007 9:45] Andrey Hristov
Doesn't crash 5.1.17-valgrind-max
[29 Mar 2007 9:50] Andrey Hristov
mysql> use test;
Database changed
mysql> select version();
+---------------------------+
| version()                 |
+---------------------------+
| 5.0.40-valgrind-max-debug |
+---------------------------+
1 row in set (0.00 sec)

mysql> create table example (id int);
Query OK, 0 rows affected (0.04 sec)

mysql> SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)));
ERROR 2013 (HY000): Lost connection to MySQL server during query

------------------------------------------------------------------------
mysql> use test;
Database changed
mysql> select version();
+---------------------------+
| version()                 |
+---------------------------+
| 5.0.40-valgrind-max-debug |
+---------------------------+
1 row in set (0.00 sec)

mysql> create table example (id int);
Query OK, 0 rows affected (0.04 sec)

mysql> insert into example values(1);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)));
ERROR 2013 (HY000): Lost connection to MySQL server during query
------------------------------------------------------------------------
mysql> use test;
Database changed
mysql> create table example (id int);
Query OK, 0 rows affected (0.04 sec)

mysql> insert into example values(1),(2),(3);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT id from example WHERE id IN(1, (SELECT IF(1=0,1,2/0)));
ERROR 2013 (HY000): Lost connection to MySQL server during query
[29 Mar 2007 10:04] Valeriy Kravchuk
Verified with -debug binaries based on Andrey's last comments.
[2 Apr 2007 13:31] Timour Katchaounov
Changed to P1 as this is a crash.
[3 Apr 2007 15:01] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/23685

ChangeSet@1.2432, 2007-04-03 18:00:57+03:00, gkodinov@magare.gmz +2 -0
  Bug #27513: test case added to make sure this 
  crash bug doesn't reappear.
[3 Apr 2007 15:02] Georgi Kodinov
Cannot repeat with the latest 5.0-BK. Added a test case to make sure this bug went away.
[9 Apr 2007 12:42] Bugs System
Pushed into 5.1.18-beta
[9 Apr 2007 12:43] Bugs System
Pushed into 5.0.40
[9 Apr 2007 19:26] Paul DuBois
Test case change only. No changelog entry needed.
[23 Jun 2007 13:03] Christian Hammers
Please add to the changelog that this one is known as CVE-2007-2583.
[27 Jun 2007 13:17] Paul DuBois
This bug is covered by the fix for Bug#27362. I have added the CVE number to the changelog entry for that bug.