Bug #23653 Crash if last_day('0000-00-00')
Submitted: 25 Oct 2006 23:39 Modified: 9 Dec 2006 18:26
Reporter: Peter Gulutzan Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0, 5.1 OS:Linux (SUSE 10.0 / 64-bit)
Assigned to: Ramil Kalimullin CPU Architecture:Any

[25 Oct 2006 23:39] Peter Gulutzan
Description:
I use the last_day() function with a zero date.
Crash.

How to repeat:
mysql> select last_day('0000-00-00');
ERROR 2013 (HY000): Lost connection to MySQL server during query
[26 Oct 2006 1:06] MySQL Verification Team
On Suse 10.0 32-bit the crash not happens or something missed (my.cnf)?

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.13-beta-debug Source distribution

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

mysql> select last_day('0000-00-00');
+------------------------+
| last_day('0000-00-00') |
+------------------------+
| 0000-00-58             | 
+------------------------+
1 row in set (0.00 sec)

mysql> select version();
+-------------------+
| version()         |
+-------------------+
| 5.1.13-beta-debug | 
+-------------------+
1 row in set (0.00 sec)
[26 Oct 2006 11:22] Peter Gulutzan
The crash does not happen on my 32-bit (SUSE 10) machine.

I reported this bug with OS = "SUSE 10.0 / 64-bit".

ChangeSet@1.2320, 2006-10-20.
[26 Oct 2006 19:50] Hartmut Holzgraefe
Verified on SuSE 10.1 64bit / AMD64 with rather current 5.1 source
[26 Oct 2006 19:55] Hartmut Holzgraefe
gdb backtrace

#0  0x00002b988e74d4c5 in pthread_kill () from /lib64/libpthread.so.0
#1  0x00000000007fe778 in write_core (sig=11) at stacktrace.c:245
#2  0x000000000064748c in handle_segfault (sig=11) at mysqld.cc:2156
#3  <signal handler called>
#4  0x00000000005e89e7 in Item_func_last_day::get_date (this=0x18b9378, ltime=0x44086c70, fuzzy_date=1) at item_timefunc.cc:3103
#5  0x000000000058b357 in Item::send (this=0x18b9378, protocol=0x1892fe0, buffer=0x44087040) at item.cc:4723
#6  0x000000000062ec03 in select_send::send_data (this=0x18b9548, items=@0x1892400) at sql_class.cc:1060
#7  0x00000000006d3eb9 in JOIN::exec (this=0x18b9568) at sql_select.cc:1362
#8  0x00000000006d17a7 in mysql_select (thd=0x1891e38, rref_pointer_array=0x1892538, tables=0x0, wild_num=0, fields=@0x1892400,
    conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2147764736, result=0x18b9548, unit=0x1891f40,
    select_lex=0x1892300) at sql_select.cc:2032
#9  0x00000000006d6039 in handle_select (thd=0x1891e38, lex=0x1891ea0, result=0x18b9548, setup_tables_done_option=0) at sql_select.cc:257
#10 0x000000000065f9e9 in execute_sqlcom_select (thd=0x1891e38, all_tables=0x0) at sql_parse.cc:5262
#11 0x0000000000662c57 in mysql_execute_command (thd=0x1891e38) at sql_parse.cc:2628
#12 0x000000000066b815 in mysql_parse (thd=0x1891e38, inBuf=0x18b9208 "select last_day('0000-00-00')", length=29) at sql_parse.cc:6080
#13 0x000000000066c4b1 in dispatch_command (command=COM_QUERY, thd=0x1891e38, packet=0x18b1179 "", packet_length=30) at sql_parse.cc:1828
#14 0x000000000066dc4f in do_command (thd=0x1891e38) at sql_parse.cc:1612
#15 0x000000000066e060 in handle_one_connection (arg=0x1891e38) at sql_parse.cc:1227
#16 0x00002b988e749193 in start_thread () from /lib64/libpthread.so.0
#17 0x00002b988ecbe47d in clone () from /lib64/libc.so.6
[26 Oct 2006 20:07] Hartmut Holzgraefe
the actual failing code in item_timefunc.cc is:

3102   uint month_idx= ltime->month-1;
3103   ltime->day= days_in_month[month_idx];

the ltime structure passed into the function has all fields set to 0 (probably simply uninitialized due to the invalid date string)

so ltime->month - 1 is 0 - 1 which would be -1, so causing an array underflow in the next line, but as month_idx is defined as unsigned int this ends up being MAX_UNSIGNED. On a 32bit system this still seems to be within accessible range, on a 64bit machines this is outside of the address range though, so causing the crash whereas the behavior on a 32bit box (returning NULL) seems to be right by accident
[26 Oct 2006 21:14] Hartmut Holzgraefe
crashes on 5.0 and 5.1 but *not* 4.1 although the code for the crashing function seems to be identical ... probably gets different data passed into it
[2 Nov 2006 14:25] Andrey Hristov
Rings a bell...
[2 Nov 2006 15:12] Andrey Hristov
I think this one will be fixed when bug#22229 is fixed, because LAST_DAY() reuses code of STR_TO_DATE(). Recheck when bug#22229 is fixed.
[9 Nov 2006 12:16] 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/15084

ChangeSet@1.2555, 2006-11-09 16:17:50+04:00, ramil@mysql.com +3 -0
  Fix for bug #23653: Crash if last_day('0000-00-00')
  
  As get_arg0_date() in the Item_func_last_day::get_date() returns 
  0000-00-00 date sometimes, we have to check ltime->month for 0 after the call.
[14 Nov 2006 11:33] Magnus BlÄudd
Looks fine to me.
[9 Dec 2006 18:26] Paul DuBois
Noted in 4.1.23, 5.0.32, 5.1.15 changelogs.

LAST_DAY('0000-00-00') could cause a server crash.