Skip to content

Commit 913e33e

Browse files
committed
Merge 10.1 into 10.2
Rewrite the MDEV-13818 fix to prevent heap-use-after-free. Add a test case for MDEV-18272.
2 parents 2faefe5 + e3adf96 commit 913e33e

File tree

14 files changed

+79
-65
lines changed

14 files changed

+79
-65
lines changed

dbug/tests.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,11 @@ int main (int argc __attribute__((unused)),
8686
return 0;
8787
#endif /* DBUG_OFF */
8888
}
89+
90+
#ifdef __SANITIZE_ADDRESS__
91+
/* Disable LeakSanitizer in this executable */
92+
const char* __asan_default_options()
93+
{
94+
return "detect_leaks=0";
95+
}
96+
#endif

include/my_pthread.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,8 +693,12 @@ extern void my_mutex_end(void);
693693
We need to have at least 256K stack to handle calls to myisamchk_init()
694694
with the current number of keys and key parts.
695695
*/
696+
#ifdef __SANITIZE_ADDRESS__
697+
#define DEFAULT_THREAD_STACK (364*1024L)
698+
#else
696699
#define DEFAULT_THREAD_STACK (292*1024L)
697700
#endif
701+
#endif
698702

699703
#define MY_PTHREAD_LOCK_READ 0
700704
#define MY_PTHREAD_LOCK_WRITE 1

mysql-test/suite/sys_vars/inc/sysvars_server.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ set sql_mode=ansi_quotes;
1313
set global div_precision_increment=5;
1414

1515
--replace_regex /^\/\S+/PATH/
16-
--replace_result $MASTER_MYPORT MASTER_MYPORT
16+
--replace_result $MASTER_MYPORT MASTER_MYPORT 372736 299008
1717
select * from information_schema.system_variables
1818
where variable_name not like 'aria%' and
1919
variable_name not like 'debug%' and

mysql-test/suite/sys_vars/t/thread_stack_basic.test

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
#
22
# only global
33
#
4-
--replace_result 196608 262144
4+
--replace_result 372736 299008
55
select @@global.thread_stack;
66
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
77
select @@session.thread_stack;
8-
--replace_result 196608 262144
8+
--replace_result 372736 299008
99
show global variables like 'thread_stack';
10-
--replace_result 196608 262144
10+
--replace_result 372736 299008
1111
show session variables like 'thread_stack';
12-
--replace_result 196608 262144
12+
--replace_result 372736 299008
1313
select * from information_schema.global_variables where variable_name='thread_stack';
14-
--replace_result 196608 262144
14+
--replace_result 372736 299008
1515
select * from information_schema.session_variables where variable_name='thread_stack';
1616

1717
#

mysql-test/t/mysqld--help.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ perl;
5757
# fixes for 32-bit
5858
s/\b4294967295\b/18446744073709551615/;
5959
s/\b2146435072\b/9223372036853727232/;
60-
s/\b196608\b/262144/;
60+
s/\b372736\b/299008/;
6161
s/\b4294963200\b/18446744073709547520/;
6262
foreach $var (@env) { s/\Q$ENV{$var}\E/$var/ }
6363
next if /use --skip-(use-)?symbolic-links to disable/; # for valgrind, again

storage/innobase/dict/dict0dict.cc

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6198,23 +6198,16 @@ dict_ind_free()
61986198
/** Get an index by name.
61996199
@param[in] table the table where to look for the index
62006200
@param[in] name the index name to look for
6201-
@param[in] committed true=search for committed,
6202-
false=search for uncommitted
62036201
@return index, NULL if does not exist */
62046202
dict_index_t*
6205-
dict_table_get_index_on_name(
6206-
dict_table_t* table,
6207-
const char* name,
6208-
bool committed)
6203+
dict_table_get_index_on_name(dict_table_t* table, const char* name)
62096204
{
62106205
dict_index_t* index;
62116206

62126207
index = dict_table_get_first_index(table);
62136208

62146209
while (index != NULL) {
6215-
if (index->is_committed() == committed
6216-
&& strcmp(index->name, name) == 0) {
6217-
6210+
if (index->is_committed() && !strcmp(index->name, name)) {
62186211
return(index);
62196212
}
62206213

storage/innobase/handler/handler0alter.cc

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4860,26 +4860,31 @@ prepare_inplace_alter_table_dict(
48604860

48614861
/* Create the indexes in SYS_INDEXES and load into dictionary. */
48624862

4863-
for (int a = 0; a < ctx->num_to_add_index; a++) {
4864-
4863+
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
48654864
if (index_defs[a].ind_type & DICT_VIRTUAL
48664865
&& ctx->num_to_drop_vcol > 0 && !new_clustered) {
48674866
innodb_v_adjust_idx_col(ha_alter_info, old_table,
48684867
ctx->num_to_drop_vcol,
48694868
&index_defs[a]);
48704869
}
48714870

4871+
DBUG_EXECUTE_IF(
4872+
"create_index_metadata_fail",
4873+
if (a + 1 == ctx->num_to_add_index) {
4874+
ctx->trx->error_state = DB_OUT_OF_FILE_SPACE;
4875+
ctx->add_index[a] = NULL;
4876+
goto index_created;
4877+
});
48724878
ctx->add_index[a] = row_merge_create_index(
48734879
ctx->trx, ctx->new_table, &index_defs[a], add_v);
4874-
4880+
#ifndef DBUG_OFF
4881+
index_created:
4882+
#endif
48754883
add_key_nums[a] = index_defs[a].key_number;
48764884

48774885
if (!ctx->add_index[a]) {
48784886
error = ctx->trx->error_state;
48794887
DBUG_ASSERT(error != DB_SUCCESS);
4880-
while (--a >= 0) {
4881-
dict_mem_index_free(ctx->add_index[a]);
4882-
}
48834888
goto error_handling;
48844889
}
48854890

storage/innobase/include/dict0dict.h

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
44
Copyright (c) 2012, Facebook Inc.
5-
Copyright (c) 2013, 2018, MariaDB Corporation.
5+
Copyright (c) 2013, 2019, MariaDB Corporation.
66
77
This program is free software; you can redistribute it and/or modify it under
88
the terms of the GNU General Public License as published by the Free Software
@@ -1599,31 +1599,21 @@ dict_tables_have_same_db(
15991599
/** Get an index by name.
16001600
@param[in] table the table where to look for the index
16011601
@param[in] name the index name to look for
1602-
@param[in] committed true=search for committed,
1603-
false=search for uncommitted
16041602
@return index, NULL if does not exist */
16051603
dict_index_t*
1606-
dict_table_get_index_on_name(
1607-
dict_table_t* table,
1608-
const char* name,
1609-
bool committed=true)
1604+
dict_table_get_index_on_name(dict_table_t* table, const char* name)
16101605
MY_ATTRIBUTE((warn_unused_result));
16111606

16121607
/** Get an index by name.
16131608
@param[in] table the table where to look for the index
16141609
@param[in] name the index name to look for
1615-
@param[in] committed true=search for committed,
1616-
false=search for uncommitted
16171610
@return index, NULL if does not exist */
16181611
inline
16191612
const dict_index_t*
1620-
dict_table_get_index_on_name(
1621-
const dict_table_t* table,
1622-
const char* name,
1623-
bool committed=true)
1613+
dict_table_get_index_on_name(const dict_table_t* table, const char* name)
16241614
{
1625-
return(dict_table_get_index_on_name(
1626-
const_cast<dict_table_t*>(table), name, committed));
1615+
return dict_table_get_index_on_name(const_cast<dict_table_t*>(table),
1616+
name);
16271617
}
16281618

16291619
/***************************************************************

storage/innobase/row/row0merge.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22
33
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2014, 2018, MariaDB Corporation.
4+
Copyright (c) 2014, 2019, MariaDB Corporation.
55
66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -4310,7 +4310,7 @@ dberr_t
43104310
row_merge_create_index_graph(
43114311
trx_t* trx,
43124312
dict_table_t* table,
4313-
dict_index_t* index,
4313+
dict_index_t*& index,
43144314
const dict_add_v_col_t* add_v)
43154315
{
43164316
ind_node_t* node; /*!< Index creation node */
@@ -4337,6 +4337,8 @@ row_merge_create_index_graph(
43374337

43384338
err = trx->error_state;
43394339

4340+
index = node->index;
4341+
43404342
que_graph_free((que_t*) que_node_get_parent(thr));
43414343

43424344
DBUG_RETURN(err);
@@ -4400,25 +4402,23 @@ row_merge_create_index(
44004402
dict_mem_index_add_field(index, name, ifield->prefix_len);
44014403
}
44024404

4405+
ut_d(const dict_index_t* const index_template = index);
44034406
/* Add the index to SYS_INDEXES, using the index prototype. */
44044407
err = row_merge_create_index_graph(trx, table, index, add_v);
44054408

44064409
if (err == DB_SUCCESS) {
4407-
4408-
index = dict_table_get_index_on_name(table, index_def->name,
4409-
index_def->rebuild);
4410-
4411-
ut_a(index);
4412-
4410+
ut_ad(index != index_template);
44134411
index->parser = index_def->parser;
44144412
index->has_new_v_col = has_new_v_col;
4415-
44164413
/* Note the id of the transaction that created this
44174414
index, we use it to restrict readers from accessing
44184415
this index, to ensure read consistency. */
44194416
ut_ad(index->trx_id == trx->id);
44204417
} else {
4421-
dict_mem_index_free(index);
4418+
ut_ad(!index || index == index_template);
4419+
if (index) {
4420+
dict_mem_index_free(index);
4421+
}
44224422
index = NULL;
44234423
}
44244424

storage/innobase/row/row0mysql.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,7 @@ row_mysql_handle_errors(
706706
switch (err) {
707707
case DB_LOCK_WAIT_TIMEOUT:
708708
if (row_rollback_on_timeout) {
709-
trx_rollback_to_savepoint(trx, NULL);
710-
break;
709+
goto rollback;
711710
}
712711
/* fall through */
713712
case DB_DUPLICATE_KEY:
@@ -726,6 +725,7 @@ row_mysql_handle_errors(
726725
case DB_TABLE_NOT_FOUND:
727726
case DB_DECRYPTION_FAILED:
728727
case DB_COMPUTE_VALUE_FAILED:
728+
rollback_to_savept:
729729
DBUG_EXECUTE_IF("row_mysql_crash_if_error", {
730730
log_buffer_flush_to_disk();
731731
DBUG_SUICIDE(); });
@@ -752,6 +752,7 @@ row_mysql_handle_errors(
752752

753753
case DB_DEADLOCK:
754754
case DB_LOCK_TABLE_FULL:
755+
rollback:
755756
/* Roll back the whole transaction; this resolution was added
756757
to version 3.23.43 */
757758

@@ -773,13 +774,13 @@ row_mysql_handle_errors(
773774
" tablespace. If the mysqld server crashes after"
774775
" the startup or when you dump the tables. "
775776
<< FORCE_RECOVERY_MSG;
776-
break;
777+
goto rollback_to_savept;
777778
case DB_FOREIGN_EXCEED_MAX_CASCADE:
778779
ib::error() << "Cannot delete/update rows with cascading"
779780
" foreign key constraints that exceed max depth of "
780781
<< FK_MAX_CASCADE_DEL << ". Please drop excessive"
781782
" foreign constraints and try again";
782-
break;
783+
goto rollback_to_savept;
783784
default:
784785
ib::fatal() << "Unknown error code " << err << ": "
785786
<< ut_strerr(err);

0 commit comments

Comments
 (0)