Bug #38520 Floating point exception in ndb_restore
Submitted: 1 Aug 2008 14:12 Modified: 5 Oct 2008 16:28
Reporter: Hartmut Holzgraefe Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Cluster: Cluster (NDB) storage engine Severity:S2 (Serious)
Version:ndb-6.3.16 OS:Linux (probably all)
Assigned to: Jonas Oreland CPU Architecture:Any

[1 Aug 2008 14:12] Hartmut Holzgraefe
Description:
ndb_restore runs into a floating point exception due to a division by zero when trying to restore certain data files

The root cause seems to be in the following snippet in RestoreDataIterator::readFragmentHeader():

    if (Header.SectionType == BackupFormat::EMPTY_ENTRY)
    {
      void *tmp;
      buffer_get_ptr(&tmp, Header.SectionLength*4-8, 1);
      continue;
    }

If SectionLength is 2 then the 2nd parameter passed to buffer_get_ptr(),
which is the 'size' parameter, becomes 0.

buffer_get_ptr() in turn calls buffer_get_ptr_ahead() 
which returns "sz / size" and so causes the division
by zero exception.

No idea whether SectionLength being 2 is an error 
already to begin with but even if it is ndb_restore
should be robust enough to not crash on such
potential backup file corruption

How to repeat:
run ndb_restore on one of the affected files
and see it crash

Suggested fix:
sz is initialized as size*nmemb 

so it is 0 if size==0 and it will never
be modified in buffer_get_ptr_ahead() 

buffer_get_ptr_ahead() returns

  sz/size

which comes down to returning nmemb
if sz was not modified within the method

so at least as a short term fix i would
suggest the following shortcut on size==0 :

--- mysql-5.1.24-ndb-6.3.16-telco/storage/ndb/tools/restore/Restore.cpp	2008-06-27 14:22:50.000000000 +0200
+++ mysql-5.1.24-ndb-6.3.16-patched/storage/ndb/tools/restore/Restore.cpp	2008-08-01 15:32:05.000000000 +0200
@@ -1152,6 +1152,8 @@
 
 Uint32 BackupFile::buffer_get_ptr_ahead(void **p_buf_ptr, Uint32 size, Uint32 nmemb)
 {
+  if (size == 0) return nmemb;
+
   Uint32 sz = size*nmemb;
   if (sz > m_buffer_data_left) {
[5 Aug 2008 14:07] 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/50931

2638 jonas@mysql.com	2008-08-05
      ndb - bug#38520
        Incorrect handling EMPTY_ENTRY setion with length 2
[5 Aug 2008 14:31] 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/50937

2646 jonas@mysql.com	2008-08-05 [merge]
      ndb - bug#38520 (merge telco-6.2 to telco-6.3)
        Incorrect handling EMPTY_ENTRY setion with length 2
[5 Aug 2008 14:33] 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/50938

2698 jonas@mysql.com	2008-08-05 [merge]
      ndb - bug#38520 (merge telco-6.3 to telco-6.4)
        Incorrect handling EMPTY_ENTRY setion with length 2
[6 Aug 2008 6:10] Jonas Oreland
pushed to telco-6.2, 6.3 and 6.4
the bug was in ndb_restore
[7 Aug 2008 12:33] 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/51093
[11 Sep 2008 19:10] Jon Stephens
Documented bugfix in the NDB 6.2.16 and 6.3.17 changelogs as follows:

        ndb_restore failed with a floating point exception due to a division by
        zero error when trying to restore certain data files.
[5 Oct 2008 16:28] Jon Stephens
Already documented for NDB 6.2/6.3; closed.
[12 Dec 2008 23:26] Bugs System
Pushed into 6.0.6-alpha  (revid:jonas@mysql.com-20080805140840-card9qlwsfmse14b) (version source revid:jonas@mysql.com-20080812185642-1nevjb94zj621dqx) (pib:5)