Bug #36320 server crashes on "select 1e37" and on "select -1e15" etc.
Submitted: 24 Apr 2008 15:16 Modified: 29 May 2008 3:43
Reporter: Daniel Fischer Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Data Types Severity:S1 (Critical)
Version:6.0.5 OS:Other (Solaris Sparc64, HP-UX ia64/hppa64)
Assigned to: Alexey Kopytov CPU Architecture:Any

[24 Apr 2008 15:16] Daniel Fischer
Description:
MySQL 6.0.5 crashes reproducibly with SIGBUS on specific platforms when attempting to parse large floating-point numbers. These are actually many different bugs that are caused by similar mistakes in strings/dtoa.c. The code in dtoa.c assumes in many places that aligning pointers to 32 bit boundaries is always sufficient. This is incorrect specifically on Sparc in 64 bit mode, on ia64, and on hppa in 64 bit mode.

Examples of statement that crash the server in different places in the source code:

select 1e37;   (dtoa.c:Balloc)
select 1e-15;  (dtoa.c:dtoa_alloc, after fixing Balloc)
select 1e-48;  (dtoa.c:cmp, after fixing dtoa_alloc)

This also manifests itself in many test case failures.

MySQL 6.0.5 is the lowest version that is affected.

How to repeat:
Build 6.0.5 on Solaris 10 Sparc in 64-bit mode (cc-5.0 -xarch=v9 etc.). Run your choice of the above queries.

Suggested fix:
 < jperkin> import gdtoa from netbsd and have done with it

Fixes for the first two examples:

===== dtoa.c 1.8 vs edited =====
--- 1.8/strings/dtoa.c	2008-01-08 08:33:02 +01:00
+++ edited/dtoa.c	2008-04-24 17:14:42 +02:00
@@ -664,6 +664,10 @@
     int x, len;
 
     x= 1 << k;
+#if SIZEOF_LONG == 8
+    /* Align len to 8-byte boundary */
+    x+= x&1;
+#endif
     len= sizeof(Bigint) + x * sizeof(ULong);
 
     if (alloc->free + len <= alloc->end)
@@ -709,13 +713,15 @@
 /*
   This is to place return value of dtoa in: tries to use stack
   as well, but passes by free lists management and just aligns len by
-  sizeof(ULong).
+  sizeof(long).
+  Aligning len by sizeof(ULong) is not sufficient because of alignment
+  restrictions on 64-bit values on some 64 bit architectures.
 */
 
 static char *dtoa_alloc(int i, Stack_alloc *alloc)
 {
   char *rv;
-  int aligned_size= (i + sizeof(ULong) - 1) / sizeof(ULong) * sizeof(ULong);
+  int aligned_size= (i + sizeof(long) - 1) / sizeof(long) * sizeof(long);
   if (alloc->free + aligned_size <= alloc->end)
   {
     rv= alloc->free;
[27 Apr 2008 8: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/46068

ChangeSet@1.2626, 2008-04-27 12:00:14+04:00, kaa@mbp.local +1 -0
  Fix for bug #36320: server crashes on "select 1e37" and on "select 
                      -1e15" etc.
  
  The bug is a regression introduced by the patch for WL #2934.
  
  On 64-bit architectures with strict alignment rules converting some 
  floating point numbers to/from strings could crash the server due to
  improper alignment of internal data structures.
  
  Fixed allocation routines in dtoa.c to ensure allocated objects to be
  aligned by the pointer size.
  
  No test case is required because the necessary coverage is provided
  by existing tests.
[28 Apr 2008 9:30] 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/46102

ChangeSet@1.2625, 2008-04-28 11:29:17+02:00, jperkin@mysql.com +1 -0
  dtoa.c:
    Pull in patch from bug#36320 to fix 64bit
    architectures with strict alignment rules.
[28 May 2008 10:01] Bugs System
Pushed into 6.0.6-alpha
[29 May 2008 3:43] Paul DuBois
Noted in 6.0.6 changelog.

The server crashed while parsing large floating-point numbers such as
1e37 or -1e15.
[23 Jul 2008 13:08] Bugs System
Pushed into 6.0.7-alpha  (revid:serg@mysql.com-20080722121106-wy84j0yvceyu72zr) (pib:2)
[14 Sep 2008 0:27] Bugs System
Pushed into 6.0.7-alpha  (revid:sp1r-jperkin/mysqldev@mysql.com/production.mysql.com-20080428092917-15381) (version source revid:vvaintroub@mysql.com-20080804094710-jb2qpqxpf2ir2gf3) (pib:3)