diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2010-11-08 19:06:26 +0300 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2010-11-08 19:06:26 +0300 |
commit | 7b33534b472b8f8f0579a3f18d361bd6fa02543c (patch) | |
tree | 86ce1d1449ee18011900732137d832d9ff3471ff | |
parent | c670b9021e782ead4cdd0d20ead2421367626ea5 (diff) | |
download | mariadb-git-7b33534b472b8f8f0579a3f18d361bd6fa02543c.tar.gz |
[Patch from Monty] Fix stack-overrun crash in subselect_notembedded.test
- Make mi_open() use less stack space
-rw-r--r-- | storage/myisam/mi_open.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 9fc82846e91..994df663d4a 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -85,12 +85,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) uchar *disk_cache, *disk_pos, *end_pos; MI_INFO info,*m_info,*old_info; MYISAM_SHARE share_buff,*share; - ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*HA_MAX_KEY_SEG]; - my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE]; + ulong *rec_per_key_part; + my_off_t *key_root, *key_del; ulonglong max_key_file_length, max_data_file_length; DBUG_ENTER("mi_open"); LINT_INIT(m_info); + LINT_INIT(rec_per_key_part); kfile= -1; lock_error=1; errpos=0; @@ -111,9 +112,6 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) { share= &share_buff; bzero((uchar*) &share_buff,sizeof(share_buff)); - share_buff.state.rec_per_key_part=rec_per_key_part; - share_buff.state.key_root=key_root; - share_buff.state.key_del=key_del; share_buff.key_cache= multi_key_cache_search((uchar*) name_buff, strlen(name_buff), dflt_key_cache); @@ -213,7 +211,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) } share->state_diff_length=len-MI_STATE_INFO_SIZE; - mi_state_info_read(disk_cache, &share->state); + if (!mi_state_info_read(disk_cache, &share->state)) + goto err; + rec_per_key_part= share->state.rec_per_key_part; + key_root= share->state.key_root; + key_del= share->state.key_del; + len= mi_uint2korr(share->state.header.base_info_length); if (len != MI_BASE_INFO_SIZE) { @@ -666,6 +669,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) pthread_mutex_unlock(&THR_LOCK_myisam); bzero(info.buff, share->base.max_key_block_length * 2); + my_free(rec_per_key_part, MYF(0)); if (myisam_log_file >= 0) { @@ -695,6 +699,8 @@ err: case 3: if (! lock_error) VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE))); + if (rec_per_key_part) + my_free(rec_per_key_part, MYF(MY_ALLOW_ZERO_PTR)); /* fall through */ case 2: my_afree(disk_cache); @@ -982,6 +988,16 @@ uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state) ptr+= state->state_diff_length; + if (!state->rec_per_key_part) + { + if (!my_multi_malloc(MY_WME, + &state->rec_per_key_part,sizeof(long)*key_parts, + &state->key_root, keys*sizeof(my_off_t), + &state->key_del, key_blocks*sizeof(my_off_t), + NullS)) + return(0); + } + for (i=0; i < keys; i++) { state->key_root[i]= mi_sizekorr(ptr); ptr +=8; |