diff options
author | Alexey Kopytov <Alexey.Kopytov@sun.com> | 2009-07-10 17:34:03 +0600 |
---|---|---|
committer | Alexey Kopytov <Alexey.Kopytov@sun.com> | 2009-07-10 17:34:03 +0600 |
commit | 2b26729eceeebe6c19349d5a4d0010241bf92847 (patch) | |
tree | 491fcfae5d84cff9f10b2ea29d4687328e86f5ba /storage/myisammrg | |
parent | 05e498ea3db8bcb99a3f3781ce3e400addecdba9 (diff) | |
download | mariadb-git-2b26729eceeebe6c19349d5a4d0010241bf92847.tar.gz |
Bug #45796: invalid memory reads and writes when altering merge
and base tables
myrg_attach_children() could reuse a buffer that was allocated
previously based on a definition of a child table. The problem
was that the child's definition might have been changed, so
reusing the buffer could lead to crashes or valgrind errors
under some circumstances.
Fixed by changing myrg_attach_children() so that the
rec_per_key_part buffer is reused only when the child table
have not changed, and reallocated otherwise (the old buffer is
deallocated if necessary).
include/myisammrg.h:
Added a pointer to need_compat_check as an argument to
myrg_attach_children().
mysql-test/r/merge.result:
Added a test case for bug #45796.
mysql-test/t/merge.test:
Added a test case for bug #45796.
storage/myisammrg/ha_myisammrg.cc:
Pass a pointer to need_compat_check to myrg_attach_children().
storage/myisammrg/myrg_open.c:
Changed myrg_attach_children() so that the
rec_per_key_part buffer is reused only when the child table
have not changed, and reallocated otherwise (the old buffer
is deallocated if necessary).
Diffstat (limited to 'storage/myisammrg')
-rw-r--r-- | storage/myisammrg/ha_myisammrg.cc | 3 | ||||
-rw-r--r-- | storage/myisammrg/myrg_open.c | 20 |
2 files changed, 16 insertions, 7 deletions
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 1e82983b97c..19510d0eae1 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -545,7 +545,8 @@ int ha_myisammrg::attach_children(void) if (myrg_attach_children(this->file, this->test_if_locked | current_thd->open_options, - myisammrg_attach_children_callback, this)) + myisammrg_attach_children_callback, this, + (my_bool *) &need_compat_check)) { DBUG_PRINT("error", ("my_errno %d", my_errno)); DBUG_RETURN(my_errno ? my_errno : -1); diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 14ba2853b22..01420f47a0c 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -365,11 +365,14 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, The callback returns the MyISAM table handle of the child table. Check table definition match. - @param[in] m_info MERGE parent table structure - @param[in] handle_locking if contains HA_OPEN_FOR_REPAIR, warn about - incompatible child tables, but continue - @param[in] callback function to call for each child table - @param[in] callback_param data pointer to give to the callback + @param[in] m_info MERGE parent table structure + @param[in] handle_locking if contains HA_OPEN_FOR_REPAIR, warn about + incompatible child tables, but continue + @param[in] callback function to call for each child table + @param[in] callback_param data pointer to give to the callback + @param[in] need_compat_check pointer to ha_myisammrg::need_compat_check + (we need this one to decide if previously + allocated buffers can be reused). @return status @retval 0 OK @@ -382,7 +385,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, MI_INFO *(*callback)(void*), - void *callback_param) + void *callback_param, my_bool *need_compat_check) { ulonglong file_offset; MI_INFO *myisam; @@ -423,6 +426,11 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, m_info->reclength= myisam->s->base.reclength; min_keys= myisam->s->base.keys; key_parts= myisam->s->base.key_parts; + if (*need_compat_check && m_info->rec_per_key_part) + { + my_free((char *) m_info->rec_per_key_part, MYF(0)); + m_info->rec_per_key_part= NULL; + } if (!m_info->rec_per_key_part) { if(!(m_info->rec_per_key_part= (ulong*) |