Bug #47598 MyISAM may write uninitialized data to disk
Submitted: 24 Sep 2009 10:40 Modified: 18 Jun 2010 2:10
Reporter: Alexey Kopytov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: MyISAM storage engine Severity:S3 (Non-critical)
Version:All OS:Any
Assigned to: Sergey Vojtovich CPU Architecture:Any
Tags: Security
Triage: Triaged: D2 (Serious)

[24 Sep 2009 10:40] Alexey Kopytov
Description:
MyISAM does not initialize index pages being created which results in uninitialized (or partially initialized) buffers going to key cache and then to disk (I did not check whether this also applies to data pages).

This has security implications in cases when users have access to file systems containing datadir/tmpdir. For example, a user can create a temporary table with the corresponding .MYI file in tmpdir potentially containing data that would be otherwise inaccessible to him through both SQL access rights and file system permissions on datadir.

For valgrind builds (i.e. with HAVE_purify defined) we do initialize pages to avoid valgrind errors. However, the problem still remains for non-valgrind builds, both debug (with --skip-safemalloc) and release ones.

How to repeat:
mysql> create table t1 (c1 int not null,c2 int not null, primary key(c1,c2));
mysql> insert into t1 (c1,c2) values  (10,1),(10,2),(10,3),(20,4),(20,5),(20,6),(30,7),(30,8),(30,9);

It's easy to see (using safemalloc, for example) that my_pwrite() called from flush_cached_blocks() writes a partially initialized index page to disk.
[24 Sep 2009 15:12] Sergei Golubchik
we should not simply bzero all new pages on creation - it may introduce a noticeable slowdown for bulk inserts.

A better solution would be to keep a flag per cached page, that tells if the page was newly created (as opposite to being read from the disk). When such a page is being written down the uninitialized tail of the page can be bzero-ed. Hopefully most of the page will be filled with data by that time and the uninitialized portion of the page will be small
[23 Oct 2009 11:52] Georgi Kodinov
Bug #46756 marked as a duplicate of this one. This bug is the core reason for 46756 failure.
[30 Oct 2009 11:35] Alexander Barkov
A similar problem with http://bugs.mysql.com/bug.php?id=46756 happens
if you run "./mtr --valgrind loadxml" in the trees mysql-next-mr
and mysql-6.0-codebase.
[12 Nov 2009 8:34] 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/90186

3167 Sergey Vojtovich	2009-11-12
      BUG#47598 - MyISAM may write uninitialized data to disk
      
      When MyISAM writes newly created index page it may be
      initialized partially. In other words some bytes of
      sensible data and uninitialized tail of the page may
      go into index file.
      
      Under certain rare circumstances these hunks of memory
      may contain data that would be otherwise inaccessible
      to user, like passwords or data from other tables.
      
      Fixed by initializing memory for temporary MyISAM key
      buffer to '\0'.
      
      No test case for this fix as it is covered by lots of
      tests already.
     @ storage/myisam/mi_open.c
        When creating new MI_INFO object, initialize MI_INFO::buff.
        This is done to ensure that we never write uninitialized
        memory hunks to index file.
     @ storage/myisam/mi_page.c
        Disabled legacy code.
[16 Mar 2010 13:53] 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/103459

3402 Sergey Vojtovich	2010-03-16
      BUG#47598 - MyISAM may write uninitialized data to disk
      
      When MyISAM writes newly created index page it may be
      initialized partially. In other words some bytes of
      sensible data and uninitialized tail of the page may
      go into index file.
      
      Under certain rare circumstances these hunks of memory
      may contain data that would be otherwise inaccessible
      to user, like passwords or data from other tables.
      
      Fixed by initializing memory for temporary MyISAM key
      buffer to '\0'.
      
      No test case for this fix as it is heavily covered by
      existing tests.
     @ storage/myisam/mi_open.c
        When creating new MI_INFO object, initialize MI_INFO::buff.
        This is done to ensure that we never write uninitialized
        memory hunks to index file.
     @ storage/myisam/mi_page.c
        With fix for BUG#47598 we always pass initialized
        buffer to key cache, thus no need to silence memory
        error detector anymore.
     @ storage/myisam/mi_write.c
        Fixed invalid memory read of 2 bytes. new_right_length
        is length of data on a page, including first 2 bytes
        that store this length itself. pos + k_length is pure
        data excluding these 2 bytes containing length.
     @ storage/myisam/rt_index.c
        To avoid uninitialized data write, create new page
        on info->buff, instead of locally allocated buffer.
        
        Note: second key block on info->buff is used here,
        because first block is used by called functions.
     @ storage/myisam/rt_split.c
        To avoid uninitialized data write, create new page
        on info->buff, instead of locally allocated buffer.
[16 Mar 2010 17:32] Ingo Strüwing
Approved with small comments. Please see email.
[22 Mar 2010 12:54] 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/103984

3402 Sergey Vojtovich	2010-03-22
      BUG#47598 - MyISAM may write uninitialized data to disk
      
      When MyISAM writes newly created index page it may be
      initialized partially. In other words some bytes of
      sensible data and uninitialized tail of the page may
      go into index file.
      
      Under certain rare circumstances these hunks of memory
      may contain data that would be otherwise inaccessible
      to user, like passwords or data from other tables.
      
      Fixed by initializing memory for temporary MyISAM key
      buffer to '\0'.
      
      No test case for this fix as it is heavily covered by
      existing tests.
     @ storage/myisam/mi_open.c
        When creating new MI_INFO object, initialize MI_INFO::buff.
        This is done to ensure that we never write uninitialized
        memory hunks to index file.
     @ storage/myisam/mi_page.c
        No need to silence memory error detector anymore,
        pager buffer is always initialized.
     @ storage/myisam/mi_write.c
        Fixed invalid memory read of 2 bytes. new_right_length
        is length of data on a page, including first 2 bytes
        that store this length itself. pos + k_length is pure
        data excluding these 2 bytes containing length.
     @ storage/myisam/rt_index.c
        To avoid uninitialized data write, create new page
        on info->buff, instead of locally allocated buffer.
        
        Note: second key block on info->buff is used here,
        because first block is used by called functions.
     @ storage/myisam/rt_split.c
        To avoid uninitialized data write, create new page
        on info->buff, instead of locally allocated buffer.
[25 Mar 2010 11:18] 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/104301

3402 Sergey Vojtovich	2010-03-25
      BUG#47598 - MyISAM may write uninitialized data to disk
      
      When MyISAM writes newly created index page it may be
      initialized partially. In other words some bytes of
      sensible data and uninitialized tail of the page may
      go into index file.
      
      Under certain rare circumstances these hunks of memory
      may contain data that would be otherwise inaccessible
      to user, like passwords or data from other tables.
      
      Fixed by initializing memory for temporary MyISAM key
      buffer to '\0'.
      
      No test case for this fix as it is heavily covered by
      existing tests.
     @ storage/myisam/mi_open.c
        When creating new MI_INFO object, initialize MI_INFO::buff.
        This is done to ensure that we never write uninitialized
        memory hunks to index file.
     @ storage/myisam/mi_page.c
        No need to silence memory error detector anymore,
        page buffer is always initialized.
     @ storage/myisam/mi_write.c
        Fixed invalid memory read of 2 bytes. new_right_length
        is length of data on a page, including first 2 bytes
        that store this length itself. pos + k_length is pure
        data excluding these 2 bytes containing length.
     @ storage/myisam/rt_index.c
        To avoid uninitialized data write, create new page
        on info->buff, instead of locally allocated buffer.
        
        Note: second key block on info->buff is used here,
        because first block is used by called functions.
     @ storage/myisam/rt_split.c
        To avoid uninitialized data write, create new page
        on info->buff, instead of locally allocated buffer.
[6 Apr 2010 8:01] Bugs System
Pushed into 5.1.46 (revid:sergey.glukhov@sun.com-20100405111026-7kz1p8qlzglqgfmu) (version source revid:aelkin@mysql.com-20100325161323-40o0cmhdzphdn1nk) (merge vers: 5.1.46) (pib:16)
[15 Apr 2010 23:35] Paul Dubois
Noted in 5.1.46 changelog.

MyISAM could write uninitialized data to new index pages. Now zeros
are written to unused bytes in the pages.

Setting report to Need Merge pending push to Celosia.
[28 May 2010 5:52] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100524190136-egaq7e8zgkwb9aqi) (version source revid:alik@sun.com-20100422150750-vp0n37kp9ywq5ghf) (pib:16)
[28 May 2010 6:21] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100524190941-nuudpx60if25wsvx) (version source revid:alik@sun.com-20100422150658-fkhgnwwkyugtxrmu) (merge vers: 6.0.14-alpha) (pib:16)
[28 May 2010 6:49] Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100524185725-c8k5q7v60i5nix3t) (version source revid:alexey.kopytov@sun.com-20100402151743-xowc2u930h729jsy) (merge vers: 5.5.4-m3) (pib:16)
[30 May 2010 0:23] Paul Dubois
Noted in 5.5.5, 6.0.14 changelogs.
[17 Jun 2010 11:52] Bugs System
Pushed into 5.1.47-ndb-7.0.16 (revid:martin.skold@mysql.com-20100617114014-bva0dy24yyd67697) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 12:30] Bugs System
Pushed into 5.1.47-ndb-6.2.19 (revid:martin.skold@mysql.com-20100617115448-idrbic6gbki37h1c) (version source revid:martin.skold@mysql.com-20100609211156-tsac5qhw951miwtt) (merge vers: 5.1.46-ndb-6.2.19) (pib:16)
[17 Jun 2010 13:18] Bugs System
Pushed into 5.1.47-ndb-6.3.35 (revid:martin.skold@mysql.com-20100617114611-61aqbb52j752y116) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)