List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:March 22 2010 12:53pm
Subject:bzr commit into mysql-5.1-bugteam branch (svoj:3402) Bug#47598
View as plain text  
#At file:///home/svoj/devel/bzr-mysql/mysql-5.1-bugteam-bug47598/ based on revid:martin.hansson@stripped

 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.

    modified:
      mysql-test/include/mtr_warnings.sql
      storage/myisam/mi_open.c
      storage/myisam/mi_page.c
      storage/myisam/mi_write.c
      storage/myisam/rt_index.c
      storage/myisam/rt_split.c
=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql	2010-02-03 07:49:20 +0000
+++ b/mysql-test/include/mtr_warnings.sql	2010-03-22 12:53:15 +0000
@@ -179,6 +179,7 @@ INSERT INTO global_suppressions VALUES
  ("==[0-9]*== Memcheck,"),
  ("==[0-9]*== Copyright"),
  ("==[0-9]*== Using"),
+ ("==[0-9]*== Command"),
  ("==[0-9]*== For more details"),
  /* This comes with innodb plugin tests */
  ("==[0-9]*== Warning: set address range perms: large range"),

=== modified file 'storage/myisam/mi_open.c'
--- a/storage/myisam/mi_open.c	2009-10-27 13:20:34 +0000
+++ b/storage/myisam/mi_open.c	2010-03-22 12:53:15 +0000
@@ -652,6 +652,9 @@ MI_INFO *mi_open(const char *name, int m
   myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
 
   pthread_mutex_unlock(&THR_LOCK_myisam);
+
+  bzero(info.buff, share->base.max_key_block_length * 2);
+
   if (myisam_log_file >= 0)
   {
     intern_filename(name_buff,share->index_file_name);

=== modified file 'storage/myisam/mi_page.c'
--- a/storage/myisam/mi_page.c	2008-03-29 08:02:54 +0000
+++ b/storage/myisam/mi_page.c	2010-03-22 12:53:15 +0000
@@ -86,13 +86,6 @@ int _mi_write_keypage(register MI_INFO *
   if ((length=keyinfo->block_length) > IO_SIZE*2 &&
       info->state->key_file_length != page+length)
     length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1));
-#ifdef HAVE_purify
-  {
-    length=mi_getint(buff);
-    bzero((uchar*) buff+length,keyinfo->block_length-length);
-    length=keyinfo->block_length;
-  }
-#endif
   DBUG_RETURN((key_cache_write(info->s->key_cache,
                          info->s->kfile,page, level, (uchar*) buff,length,
 			 (uint) keyinfo->block_length,

=== modified file 'storage/myisam/mi_write.c'
--- a/storage/myisam/mi_write.c	2009-09-17 15:25:52 +0000
+++ b/storage/myisam/mi_write.c	2010-03-22 12:53:15 +0000
@@ -825,7 +825,7 @@ static int _mi_balance_page(register MI_
 	     (size_t) (length=new_left_length - left_length - k_length));
       pos=buff+2+length;
       memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_length);
-      bmove((uchar*) buff+2,(uchar*) pos+k_length,new_right_length);
+      bmove((uchar*) buff + 2, (uchar*) pos + k_length, new_right_length - 2);
     }
     else
     {						/* Move keys -> buff */

=== modified file 'storage/myisam/rt_index.c'
--- a/storage/myisam/rt_index.c	2010-03-08 10:42:01 +0000
+++ b/storage/myisam/rt_index.c	2010-03-22 12:53:15 +0000
@@ -641,18 +641,12 @@ static int rtree_insert_level(MI_INFO *i
     }
     case 1: /* root was split, grow a new root */
     { 
-      uchar *new_root_buf;
+      uchar *new_root_buf= info->buff + info->s->base.max_key_block_length;
       my_off_t new_root;
       uchar *new_key;
       uint nod_flag = info->s->base.key_reflength;
 
       DBUG_PRINT("rtree", ("root was split, grow a new root"));
-      if (!(new_root_buf = (uchar*)my_alloca((uint)keyinfo->block_length + 
-                                             MI_MAX_KEY_BUFF)))
-      {
-        my_errno = HA_ERR_OUT_OF_MEM;
-        DBUG_RETURN(-1); /* purecov: inspected */
-      }
 
       mi_putint(new_root_buf, 2, nod_flag);
       if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
@@ -680,10 +674,8 @@ static int rtree_insert_level(MI_INFO *i
       DBUG_PRINT("rtree", ("new root page: %lu  level: %d  nod_flag: %u",
                            (ulong) new_root, 0, mi_test_if_nod(new_root_buf)));
 
-      my_afree((uchar*)new_root_buf);
       break;
 err1:
-      my_afree((uchar*)new_root_buf);
       DBUG_RETURN(-1); /* purecov: inspected */
     }
     default:

=== modified file 'storage/myisam/rt_split.c'
--- a/storage/myisam/rt_split.c	2007-05-10 09:59:39 +0000
+++ b/storage/myisam/rt_split.c	2010-03-22 12:53:15 +0000
@@ -258,7 +258,7 @@ int rtree_split_page(MI_INFO *info, MI_K
   double *old_coord;
   int n_dim;
   uchar *source_cur, *cur1, *cur2;
-  uchar *new_page;
+  uchar *new_page= info->buff;
   int err_code= 0;
   uint nod_flag= mi_test_if_nod(page);
   uint full_length= key_length + (nod_flag ? nod_flag : 
@@ -304,12 +304,7 @@ int rtree_split_page(MI_INFO *info, MI_K
     goto split_err;
   }
 
-  if (!(new_page = (uchar*)my_alloca((uint)keyinfo->block_length)))
-  {
-    err_code= -1;
-    goto split_err;
-  }
-  
+  info->buff_used= 1;
   stop = task + (max_keys + 1);
   cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
   cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
@@ -345,8 +340,6 @@ int rtree_split_page(MI_INFO *info, MI_K
                                 DFLT_INIT_HITS, new_page);
   DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
 
-  my_afree((uchar*)new_page);
-
 split_err:
   my_afree((uchar*) coord_buf);
   DBUG_RETURN(err_code);


Attachment: [text/bzr-bundle] bzr/svoj@sun.com-20100322125315-w75otgytwbiumdkd.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (svoj:3402) Bug#47598Sergey Vojtovich22 Mar