Skip to content

Commit 164cf96

Browse files
author
Nisha Gopalakrishnan
committed
BUG#24595992: NULL POINTER DEREFERENCE IN CHECK_DUPLICATE_KEY()
Analysis: ======== CREATE TABLE using SELECT can cause a null pointer dereference while printing the warning message. During the processing of SELECT in CREATE TABLE, the first element of the global query table_list is pruned. Later while trying to print a warning message, it tries to access the global query table list to get the schema name and table name which is set to NULL. Fix: === Passed the schema name and table name from the upper layer so that it is accessible in check_duplicate_key().
1 parent 138cffd commit 164cf96

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

sql/sql_table.cc

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ static bool check_engine(THD *thd, const char *db_name,
8787
HA_CREATE_INFO *create_info);
8888

8989
static int
90-
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
90+
mysql_prepare_create_table(THD *thd, const char *error_schema_name,
91+
const char *error_table_name,
92+
HA_CREATE_INFO *create_info,
9193
Alter_info *alter_info,
9294
bool tmp_table,
9395
uint *db_options,
@@ -1863,7 +1865,9 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
18631865
strxmov(shadow_frm_name, shadow_path, reg_ext, NullS);
18641866
if (flags & WFRM_WRITE_SHADOW)
18651867
{
1866-
if (mysql_prepare_create_table(lpt->thd, lpt->create_info,
1868+
if (mysql_prepare_create_table(lpt->thd, lpt->db,
1869+
lpt->table_name,
1870+
lpt->create_info,
18671871
lpt->alter_info,
18681872
/*tmp_table*/ 1,
18691873
&lpt->db_options,
@@ -3267,12 +3271,15 @@ void promote_first_timestamp_column(List<Create_field> *column_definitions)
32673271
/**
32683272
Check if there is a duplicate key. Report a warning for every duplicate key.
32693273
3270-
@param thd Thread context.
3271-
@param key Key to be checked.
3272-
@param key_info Key meta-data info.
3273-
@param alter_info List of columns and indexes to create.
3274+
@param thd Thread context.
3275+
@param error_schema_name Schema name of the table used for error reporting.
3276+
@param error_table_name Table name used for error reporting.
3277+
@param key Key to be checked.
3278+
@param key_info Key meta-data info.
3279+
@param alter_info List of columns and indexes to create.
32743280
*/
3275-
static void check_duplicate_key(THD *thd,
3281+
static void check_duplicate_key(THD *thd, const char *error_schema_name,
3282+
const char *error_table_name,
32763283
Key *key, KEY *key_info,
32773284
Alter_info *alter_info)
32783285
{
@@ -3352,8 +3359,8 @@ static void check_duplicate_key(THD *thd,
33523359
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
33533360
ER_DUP_INDEX, ER(ER_DUP_INDEX),
33543361
key_info->name,
3355-
thd->lex->query_tables->db,
3356-
thd->lex->query_tables->table_name);
3362+
error_schema_name,
3363+
error_table_name);
33573364
break;
33583365
}
33593366
}
@@ -3366,6 +3373,10 @@ static void check_duplicate_key(THD *thd,
33663373
SYNOPSIS
33673374
mysql_prepare_create_table()
33683375
thd Thread object.
3376+
error_schema_name Schema name of the table to create/alter,only
3377+
used for error reporting.
3378+
error_table_name Name of table to create/alter, only used for
3379+
error reporting.
33693380
create_info Create information (like MAX_ROWS).
33703381
alter_info List of columns and indexes to create
33713382
tmp_table If a temporary table is to be created.
@@ -3387,7 +3398,9 @@ static void check_duplicate_key(THD *thd,
33873398
*/
33883399

33893400
static int
3390-
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
3401+
mysql_prepare_create_table(THD *thd, const char *error_schema_name,
3402+
const char *error_table_name,
3403+
HA_CREATE_INFO *create_info,
33913404
Alter_info *alter_info,
33923405
bool tmp_table,
33933406
uint *db_options,
@@ -4288,7 +4301,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
42884301
}
42894302

42904303
// Check if a duplicate index is defined.
4291-
check_duplicate_key(thd, key, key_info, alter_info);
4304+
check_duplicate_key(thd, error_schema_name, error_table_name,
4305+
key, key_info, alter_info);
42924306

42934307
key_info++;
42944308
}
@@ -4538,6 +4552,8 @@ static void sp_prepare_create_field(THD *thd, Create_field *sql_field)
45384552
@param thd Thread object
45394553
@param db Database
45404554
@param table_name Table name
4555+
@param error_table_name The real table name in case table_name is a temporary
4556+
table (ALTER). Only used for error messages.
45414557
@param path Path to table (i.e. to its .FRM file without
45424558
the extension).
45434559
@param create_info Create information (like MAX_ROWS)
@@ -4570,6 +4586,7 @@ static void sp_prepare_create_field(THD *thd, Create_field *sql_field)
45704586
static
45714587
bool create_table_impl(THD *thd,
45724588
const char *db, const char *table_name,
4589+
const char *error_table_name,
45734590
const char *path,
45744591
HA_CREATE_INFO *create_info,
45754592
Alter_info *alter_info,
@@ -4816,7 +4833,8 @@ bool create_table_impl(THD *thd,
48164833
}
48174834
#endif
48184835

4819-
if (mysql_prepare_create_table(thd, create_info, alter_info,
4836+
if (mysql_prepare_create_table(thd, db, error_table_name,
4837+
create_info, alter_info,
48204838
internal_tmp_table,
48214839
&db_options, file,
48224840
key_info, key_count,
@@ -5089,9 +5107,9 @@ bool mysql_create_table_no_lock(THD *thd,
50895107
}
50905108
}
50915109

5092-
return create_table_impl(thd, db, table_name, path, create_info, alter_info,
5093-
false, select_field_count, false, is_trans,
5094-
&not_used_1, &not_used_2);
5110+
return create_table_impl(thd, db, table_name, table_name, path, create_info,
5111+
alter_info, false, select_field_count, false,
5112+
is_trans, &not_used_1, &not_used_2);
50955113
}
50965114

50975115

@@ -6253,8 +6271,8 @@ bool mysql_compare_tables(TABLE *table,
62536271
KEY *key_info_buffer= NULL;
62546272

62556273
/* Create the prepared information. */
6256-
if (mysql_prepare_create_table(thd, create_info,
6257-
&tmp_alter_info,
6274+
if (mysql_prepare_create_table(thd, "", "",
6275+
create_info, &tmp_alter_info,
62586276
(table->s->tmp_table != NO_TMP_TABLE),
62596277
&db_options,
62606278
table->file, &key_info_buffer,
@@ -8376,6 +8394,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
83768394

83778395
tmp_disable_binlog(thd);
83788396
error= create_table_impl(thd, alter_ctx.new_db, alter_ctx.tmp_name,
8397+
alter_ctx.table_name,
83798398
alter_ctx.get_tmp_path(),
83808399
create_info, alter_info,
83818400
true, 0, true, NULL,

0 commit comments

Comments
 (0)