Commit 2a3003e9 authored by serg@serg.mysql.com's avatar serg@serg.mysql.com

more propection in mi_open against badly corrupted MYI headers

parent 4b402e6d
...@@ -68,7 +68,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -68,7 +68,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
int lock_error,kfile,open_mode,save_errno; int lock_error,kfile,open_mode,save_errno;
uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys, uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys,
key_parts,unique_key_parts,tmp_length,uniques; key_parts,unique_key_parts,tmp_length,uniques;
char name_buff[FN_REFLEN],*disk_cache,*disk_pos; char name_buff[FN_REFLEN],*disk_cache,*disk_pos, *end_pos;
MI_INFO info,*m_info,*old_info; MI_INFO info,*m_info,*old_info;
MYISAM_SHARE share_buff,*share; MYISAM_SHARE share_buff,*share;
ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]; ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
...@@ -129,11 +129,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -129,11 +129,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
} }
info_length=mi_uint2korr(share->state.header.header_length); info_length=mi_uint2korr(share->state.header.header_length);
base_pos=mi_uint2korr(share->state.header.base_pos); base_pos=mi_uint2korr(share->state.header.base_pos);
if (!(disk_cache=(char*) my_alloca(info_length))) if (!(disk_cache=(char*) my_alloca(info_length+128)))
{ {
my_errno=ENOMEM; my_errno=ENOMEM;
goto err; goto err;
} }
end_pos=disk_cache+info_length;
errpos=2; errpos=2;
VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0))); VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
...@@ -269,17 +270,28 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -269,17 +270,28 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->state.header.max_block_size)); share->state.header.max_block_size));
strmov(share->filename,name_buff); strmov(share->filename,name_buff);
#define disk_pos_assert do \
{ \
if (disk_pos > end_pos) \
{ \
my_errno=HA_ERR_CRASHED; \
goto err; \
} \
} while(0)
share->blocksize=min(IO_SIZE,myisam_block_size); share->blocksize=min(IO_SIZE,myisam_block_size);
{ {
MI_KEYSEG *pos=share->keyparts; MI_KEYSEG *pos=share->keyparts;
for (i=0 ; i < keys ; i++) for (i=0 ; i < keys ; i++)
{ {
disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]); disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
disk_pos_assert;
set_if_smaller(share->blocksize,share->keyinfo[i].block_length); set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
share->keyinfo[i].seg=pos; share->keyinfo[i].seg=pos;
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++) for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
{ {
disk_pos=mi_keyseg_read(disk_pos, pos); disk_pos=mi_keyseg_read(disk_pos, pos);
disk_pos_assert;
if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT) if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT)
{ {
if (!pos->language) if (!pos->language)
...@@ -306,10 +318,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -306,10 +318,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
for (i=0 ; i < uniques ; i++) for (i=0 ; i < uniques ; i++)
{ {
disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]); disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
disk_pos_assert;
share->uniqueinfo[i].seg=pos; share->uniqueinfo[i].seg=pos;
for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++) for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++)
{ {
disk_pos=mi_keyseg_read(disk_pos, pos); disk_pos=mi_keyseg_read(disk_pos, pos);
disk_pos_assert;
if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT) if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT)
{ {
if (!pos->language) if (!pos->language)
...@@ -334,6 +348,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -334,6 +348,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
for (i=j=offset=0 ; i < share->base.fields ; i++) for (i=j=offset=0 ; i < share->base.fields ; i++)
{ {
disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]); disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]);
disk_pos_assert;
share->rec[i].pack_type=0; share->rec[i].pack_type=0;
share->rec[i].huff_tree=0; share->rec[i].huff_tree=0;
share->rec[i].offset=offset; share->rec[i].offset=offset;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment