Commit cd37e494 authored by Monty's avatar Monty

MDEV-31083 ASAN use-after-poison in myrg_attach_children

The reason for ASAN report was that the MERGE and MYISAM file
had different key definitions, which is not allowed.

Fixed by ensuring that the MERGE code is not copying more key stats
than what is in the MyISAM file.

Other things:
- Give an error if different MyISAM files has different number of
  key parts.
parent c7e04af8
......@@ -71,6 +71,7 @@ typedef struct st_myrg_info
ulong cache_size;
uint merge_insert_method;
uint tables,options,reclength,keys;
uint key_parts;
my_bool cache_in_use;
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
my_bool children_attached;
......
......@@ -3919,3 +3919,15 @@ ERROR HY000: Unable to open underlying table which is differently defined or of
DROP TRIGGER trg1;
DROP TABLE t1;
DROP TABLE m1;
#
# MDEV-31083 ASAN use-after-poison in myrg_attach_children
#
CREATE TABLE t1 (f TEXT, FULLTEXT (f)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE mrg (f TEXT) ENGINE=MERGE, UNION(t1);
SELECT * FROM mrg;
f
foo
bar
DROP TABLE mrg, t1;
End of 10.5 tests
......@@ -2919,3 +2919,15 @@ set global default_storage_engine=@save_default_storage_engine;
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
--echo #
--echo # MDEV-31083 ASAN use-after-poison in myrg_attach_children
--echo #
CREATE TABLE t1 (f TEXT, FULLTEXT (f)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE mrg (f TEXT) ENGINE=MERGE, UNION(t1);
SELECT * FROM mrg;
DROP TABLE mrg, t1;
--echo End of 10.5 tests
......@@ -518,6 +518,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->kfile=kfile;
share->this_process=(ulong) getpid();
share->last_process= share->state.process;
share->base.base_key_parts= base_key_parts;
share->base.key_parts=key_parts;
share->base.all_key_parts=key_parts+unique_key_parts;
if (!(share->last_version=share->state.version))
......
......@@ -132,7 +132,7 @@ typedef struct st_mi_base_info
uint extra_alloc_bytes;
uint extra_alloc_procent;
/* The following are from the header */
uint key_parts, all_key_parts;
uint key_parts, all_key_parts, base_key_parts;
} MI_BASE_INFO;
......
......@@ -432,17 +432,20 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
first_child= FALSE;
m_info->reclength= myisam->s->base.reclength;
min_keys= myisam->s->base.keys;
key_parts= myisam->s->base.key_parts;
key_parts= myisam->s->base.base_key_parts;
if (*need_compat_check && m_info->rec_per_key_part)
{
my_free(m_info->rec_per_key_part);
m_info->rec_per_key_part= NULL;
}
if (!m_info->rec_per_key_part)
if (!m_info->rec_per_key_part || m_info->key_parts != key_parts)
{
if(!(m_info->rec_per_key_part= (ulong*)
my_malloc(rg_key_memory_MYRG_INFO,
key_parts * sizeof(long), MYF(MY_WME))))
m_info->key_parts= key_parts;
/* The +1 is because by my_realloc() don't allow zero length */
if (!(m_info->rec_per_key_part= (ulong*)
my_realloc(rg_key_memory_MYRG_INFO, m_info->rec_per_key_part,
key_parts * sizeof(long) +1,
MYF(MY_WME | MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
goto err; /* purecov: inspected */
errpos= 1;
}
......@@ -457,7 +460,8 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
myisam->open_flag|= HA_OPEN_MERGE_TABLE;
/* Check table definition match. */
if (m_info->reclength != myisam->s->base.reclength)
if (m_info->reclength != myisam->s->base.reclength ||
key_parts != myisam->s->base.base_key_parts)
{
DBUG_PRINT("error", ("definition mismatch table: '%s' repair: %d",
myisam->filename,
......
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