mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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.
This commit is contained in:
@@ -652,6 +652,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||||||
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
|
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
|
||||||
|
|
||||||
pthread_mutex_unlock(&THR_LOCK_myisam);
|
pthread_mutex_unlock(&THR_LOCK_myisam);
|
||||||
|
|
||||||
|
bzero(info.buff, share->base.max_key_block_length * 2);
|
||||||
|
|
||||||
if (myisam_log_file >= 0)
|
if (myisam_log_file >= 0)
|
||||||
{
|
{
|
||||||
intern_filename(name_buff,share->index_file_name);
|
intern_filename(name_buff,share->index_file_name);
|
||||||
|
@@ -86,13 +86,6 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||||||
if ((length=keyinfo->block_length) > IO_SIZE*2 &&
|
if ((length=keyinfo->block_length) > IO_SIZE*2 &&
|
||||||
info->state->key_file_length != page+length)
|
info->state->key_file_length != page+length)
|
||||||
length= ((mi_getint(buff)+IO_SIZE-1) & (uint) ~(IO_SIZE-1));
|
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,
|
DBUG_RETURN((key_cache_write(info->s->key_cache,
|
||||||
info->s->kfile,page, level, (uchar*) buff,length,
|
info->s->kfile,page, level, (uchar*) buff,length,
|
||||||
(uint) keyinfo->block_length,
|
(uint) keyinfo->block_length,
|
||||||
|
@@ -825,7 +825,7 @@ static int _mi_balance_page(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||||||
(size_t) (length=new_left_length - left_length - k_length));
|
(size_t) (length=new_left_length - left_length - k_length));
|
||||||
pos=buff+2+length;
|
pos=buff+2+length;
|
||||||
memcpy((uchar*) father_key_pos,(uchar*) pos,(size_t) k_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
|
else
|
||||||
{ /* Move keys -> buff */
|
{ /* Move keys -> buff */
|
||||||
|
@@ -641,18 +641,12 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
|
|||||||
}
|
}
|
||||||
case 1: /* root was split, grow a new root */
|
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;
|
my_off_t new_root;
|
||||||
uchar *new_key;
|
uchar *new_key;
|
||||||
uint nod_flag = info->s->base.key_reflength;
|
uint nod_flag = info->s->base.key_reflength;
|
||||||
|
|
||||||
DBUG_PRINT("rtree", ("root was split, grow a new root"));
|
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);
|
mi_putint(new_root_buf, 2, nod_flag);
|
||||||
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
if ((new_root = _mi_new(info, keyinfo, DFLT_INIT_HITS)) ==
|
||||||
@@ -680,10 +674,8 @@ static int rtree_insert_level(MI_INFO *info, uint keynr, uchar *key,
|
|||||||
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
|
DBUG_PRINT("rtree", ("new root page: %lu level: %d nod_flag: %u",
|
||||||
(ulong) new_root, 0, mi_test_if_nod(new_root_buf)));
|
(ulong) new_root, 0, mi_test_if_nod(new_root_buf)));
|
||||||
|
|
||||||
my_afree((uchar*)new_root_buf);
|
|
||||||
break;
|
break;
|
||||||
err1:
|
err1:
|
||||||
my_afree((uchar*)new_root_buf);
|
|
||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@@ -258,7 +258,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
|
|||||||
double *old_coord;
|
double *old_coord;
|
||||||
int n_dim;
|
int n_dim;
|
||||||
uchar *source_cur, *cur1, *cur2;
|
uchar *source_cur, *cur1, *cur2;
|
||||||
uchar *new_page;
|
uchar *new_page= info->buff;
|
||||||
int err_code= 0;
|
int err_code= 0;
|
||||||
uint nod_flag= mi_test_if_nod(page);
|
uint nod_flag= mi_test_if_nod(page);
|
||||||
uint full_length= key_length + (nod_flag ? nod_flag :
|
uint full_length= key_length + (nod_flag ? nod_flag :
|
||||||
@@ -304,12 +304,7 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
|
|||||||
goto split_err;
|
goto split_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(new_page = (uchar*)my_alloca((uint)keyinfo->block_length)))
|
info->buff_used= 1;
|
||||||
{
|
|
||||||
err_code= -1;
|
|
||||||
goto split_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
stop = task + (max_keys + 1);
|
stop = task + (max_keys + 1);
|
||||||
cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
|
cur1 = rt_PAGE_FIRST_KEY(page, nod_flag);
|
||||||
cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
|
cur2 = rt_PAGE_FIRST_KEY(new_page, nod_flag);
|
||||||
@@ -345,8 +340,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key,
|
|||||||
DFLT_INIT_HITS, new_page);
|
DFLT_INIT_HITS, new_page);
|
||||||
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
|
DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs));
|
||||||
|
|
||||||
my_afree((uchar*)new_page);
|
|
||||||
|
|
||||||
split_err:
|
split_err:
|
||||||
my_afree((uchar*) coord_buf);
|
my_afree((uchar*) coord_buf);
|
||||||
DBUG_RETURN(err_code);
|
DBUG_RETURN(err_code);
|
||||||
|
Reference in New Issue
Block a user