Bug #7774 segmentation fault/data corruption by my_sprintf in Field_str::store(double)
Submitted: 10 Jan 2005 15:35 Modified: 16 Feb 2005 19:24
Reporter: Tim Cutts Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:4.1.8 OS:Linux (Linux/IA64, MacOS X 10.3)
Assigned to: Jim Winstead CPU Architecture:Any

[10 Jan 2005 15:35] Tim Cutts
Description:
We installed the stock debug binary Linux/ia64 distribution of 4.1.8 from MySQL.com, and can crash it by inserting an unquoted floating point number into a varchar column.

The problem does not occur on X86 - we suspect that the configure script on IA64 is mis-detecting the return type of sprintf.

How to repeat:
The following code causes a SIGSEGV in the standard server, or SIGABRT due to an assertion in Field_str::store in the debug server:

create database tim_crash;
create table crash_me(num varchar(20));
insert into crash_me(num) values (5.1e-28);

Suggested fix:
We suspect that the configure script on IA64 is mis-detecting the return type of sprintf.

We investigated this with gdb, and noted that the my_sprintf macro is returning a crazy value for length: 

Breakpoint 1, Field_str::store (this=0x6000000002c97a10, 
    nr=5.1000000000000001e-28) at field.cc:4335
4335      bool use_scientific_notation= TRUE;
(gdb) 
(gdb) n
4337      if (field_length < 32 && fabs(nr) < log_10[field_length]-1)
(gdb) n
4340      length= (uint) my_sprintf(buff, (buff, "%-.*g",
(gdb) ni
4340      length= (uint) my_sprintf(buff, (buff, "%-.*g",
(gdb) ni
0x4000000000203702      4340      length= (uint) my_sprintf(buff, (buff, "%-.*g",
(gdb) ni
4340      length= (uint) my_sprintf(buff, (buff, "%-.*g",
(gdb) p length
$6 = 46694840
[10 Jan 2005 17:20] Tim Cutts
We tried compiling it from source too, using gcc, and that stops the crash, but ressults in a different bug; the value is inserted in the varchar column as '5.100000000000000088' which is clearly wrong, and the bug is also present in that form on other architectures (the 4.1.8 release for MacOS X exhibits this behaviour too)

Any negative exponent greater in magnitude than -4 triggers this behaviour.
[10 Jan 2005 17:26] Tim Cutts
Changed the title and increased the severity since we have found a form of the bug which corrupts data as well as crashing the server, and is not limited to a single architecture.
[10 Jan 2005 19:03] MySQL Verification Team
I was able reproduce server crash on my x86 too using latest 4.1 and 5.0.
4.0 - works fine.
[13 Jan 2005 2:22] Jim Winstead
The handling of values < 1 was just not correct. (The decision to disable scientific notation was 
being made by comparing against the largest positive power of ten that would fit, not the smallest 
negative power of ten.)
[16 Feb 2005 19:24] Paul DuBois
Mentioned in 4.1.10 change notes.