Skip to content

Commit cd37e49

Browse files
committed
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.
1 parent c7e04af commit cd37e49

File tree

6 files changed

+37
-7
lines changed

6 files changed

+37
-7
lines changed

include/myisammrg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ typedef struct st_myrg_info
7171
ulong cache_size;
7272
uint merge_insert_method;
7373
uint tables,options,reclength,keys;
74+
uint key_parts;
7475
my_bool cache_in_use;
7576
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
7677
my_bool children_attached;

mysql-test/main/merge.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3919,3 +3919,15 @@ ERROR HY000: Unable to open underlying table which is differently defined or of
39193919
DROP TRIGGER trg1;
39203920
DROP TABLE t1;
39213921
DROP TABLE m1;
3922+
#
3923+
# MDEV-31083 ASAN use-after-poison in myrg_attach_children
3924+
#
3925+
CREATE TABLE t1 (f TEXT, FULLTEXT (f)) ENGINE=MyISAM;
3926+
INSERT INTO t1 VALUES ('foo'),('bar');
3927+
CREATE TABLE mrg (f TEXT) ENGINE=MERGE, UNION(t1);
3928+
SELECT * FROM mrg;
3929+
f
3930+
foo
3931+
bar
3932+
DROP TABLE mrg, t1;
3933+
End of 10.5 tests

mysql-test/main/merge.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,3 +2919,15 @@ set global default_storage_engine=@save_default_storage_engine;
29192919
# Check that all connections opened by test cases in this file are really
29202920
# gone so execution of other tests won't be affected by their presence.
29212921
--source include/wait_until_count_sessions.inc
2922+
2923+
--echo #
2924+
--echo # MDEV-31083 ASAN use-after-poison in myrg_attach_children
2925+
--echo #
2926+
2927+
CREATE TABLE t1 (f TEXT, FULLTEXT (f)) ENGINE=MyISAM;
2928+
INSERT INTO t1 VALUES ('foo'),('bar');
2929+
CREATE TABLE mrg (f TEXT) ENGINE=MERGE, UNION(t1);
2930+
SELECT * FROM mrg;
2931+
DROP TABLE mrg, t1;
2932+
2933+
--echo End of 10.5 tests

storage/myisam/mi_open.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
518518
share->kfile=kfile;
519519
share->this_process=(ulong) getpid();
520520
share->last_process= share->state.process;
521+
share->base.base_key_parts= base_key_parts;
521522
share->base.key_parts=key_parts;
522523
share->base.all_key_parts=key_parts+unique_key_parts;
523524
if (!(share->last_version=share->state.version))

storage/myisam/myisamdef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ typedef struct st_mi_base_info
132132
uint extra_alloc_bytes;
133133
uint extra_alloc_procent;
134134
/* The following are from the header */
135-
uint key_parts, all_key_parts;
135+
uint key_parts, all_key_parts, base_key_parts;
136136
} MI_BASE_INFO;
137137

138138

storage/myisammrg/myrg_open.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,17 +432,20 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
432432
first_child= FALSE;
433433
m_info->reclength= myisam->s->base.reclength;
434434
min_keys= myisam->s->base.keys;
435-
key_parts= myisam->s->base.key_parts;
435+
key_parts= myisam->s->base.base_key_parts;
436436
if (*need_compat_check && m_info->rec_per_key_part)
437437
{
438438
my_free(m_info->rec_per_key_part);
439439
m_info->rec_per_key_part= NULL;
440440
}
441-
if (!m_info->rec_per_key_part)
441+
if (!m_info->rec_per_key_part || m_info->key_parts != key_parts)
442442
{
443-
if(!(m_info->rec_per_key_part= (ulong*)
444-
my_malloc(rg_key_memory_MYRG_INFO,
445-
key_parts * sizeof(long), MYF(MY_WME))))
443+
m_info->key_parts= key_parts;
444+
/* The +1 is because by my_realloc() don't allow zero length */
445+
if (!(m_info->rec_per_key_part= (ulong*)
446+
my_realloc(rg_key_memory_MYRG_INFO, m_info->rec_per_key_part,
447+
key_parts * sizeof(long) +1,
448+
MYF(MY_WME | MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
446449
goto err; /* purecov: inspected */
447450
errpos= 1;
448451
}
@@ -457,7 +460,8 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
457460
myisam->open_flag|= HA_OPEN_MERGE_TABLE;
458461

459462
/* Check table definition match. */
460-
if (m_info->reclength != myisam->s->base.reclength)
463+
if (m_info->reclength != myisam->s->base.reclength ||
464+
key_parts != myisam->s->base.base_key_parts)
461465
{
462466
DBUG_PRINT("error", ("definition mismatch table: '%s' repair: %d",
463467
myisam->filename,

0 commit comments

Comments
 (0)