Skip to content
Permalink
Browse files
Merge 10.1 into 10.2
Rewrite the MDEV-13818 fix to prevent heap-use-after-free.

Add a test case for MDEV-18272.
  • Loading branch information
dr-m committed Mar 7, 2019
2 parents 2faefe5 + e3adf96 commit 913e33e
Show file tree
Hide file tree
Showing 14 changed files with 79 additions and 65 deletions.
@@ -86,3 +86,11 @@ int main (int argc __attribute__((unused)),
return 0;
#endif /* DBUG_OFF */
}

#ifdef __SANITIZE_ADDRESS__
/* Disable LeakSanitizer in this executable */
const char* __asan_default_options()
{
return "detect_leaks=0";
}
#endif
@@ -693,8 +693,12 @@ extern void my_mutex_end(void);
We need to have at least 256K stack to handle calls to myisamchk_init()
with the current number of keys and key parts.
*/
#ifdef __SANITIZE_ADDRESS__
#define DEFAULT_THREAD_STACK (364*1024L)
#else
#define DEFAULT_THREAD_STACK (292*1024L)
#endif
#endif

#define MY_PTHREAD_LOCK_READ 0
#define MY_PTHREAD_LOCK_WRITE 1
@@ -13,7 +13,7 @@ set sql_mode=ansi_quotes;
set global div_precision_increment=5;

--replace_regex /^\/\S+/PATH/
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_result $MASTER_MYPORT MASTER_MYPORT 372736 299008
select * from information_schema.system_variables
where variable_name not like 'aria%' and
variable_name not like 'debug%' and
@@ -1,17 +1,17 @@
#
# only global
#
--replace_result 196608 262144
--replace_result 372736 299008
select @@global.thread_stack;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
select @@session.thread_stack;
--replace_result 196608 262144
--replace_result 372736 299008
show global variables like 'thread_stack';
--replace_result 196608 262144
--replace_result 372736 299008
show session variables like 'thread_stack';
--replace_result 196608 262144
--replace_result 372736 299008
select * from information_schema.global_variables where variable_name='thread_stack';
--replace_result 196608 262144
--replace_result 372736 299008
select * from information_schema.session_variables where variable_name='thread_stack';

#
@@ -57,7 +57,7 @@ perl;
# fixes for 32-bit
s/\b4294967295\b/18446744073709551615/;
s/\b2146435072\b/9223372036853727232/;
s/\b196608\b/262144/;
s/\b372736\b/299008/;
s/\b4294963200\b/18446744073709547520/;
foreach $var (@env) { s/\Q$ENV{$var}\E/$var/ }
next if /use --skip-(use-)?symbolic-links to disable/; # for valgrind, again
@@ -6198,23 +6198,16 @@ dict_ind_free()
/** Get an index by name.
@param[in] table the table where to look for the index
@param[in] name the index name to look for
@param[in] committed true=search for committed,
false=search for uncommitted
@return index, NULL if does not exist */
dict_index_t*
dict_table_get_index_on_name(
dict_table_t* table,
const char* name,
bool committed)
dict_table_get_index_on_name(dict_table_t* table, const char* name)
{
dict_index_t* index;

index = dict_table_get_first_index(table);

while (index != NULL) {
if (index->is_committed() == committed
&& strcmp(index->name, name) == 0) {

if (index->is_committed() && !strcmp(index->name, name)) {
return(index);
}

@@ -4860,26 +4860,31 @@ prepare_inplace_alter_table_dict(

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

for (int a = 0; a < ctx->num_to_add_index; a++) {

for (ulint a = 0; a < ctx->num_to_add_index; a++) {
if (index_defs[a].ind_type & DICT_VIRTUAL
&& ctx->num_to_drop_vcol > 0 && !new_clustered) {
innodb_v_adjust_idx_col(ha_alter_info, old_table,
ctx->num_to_drop_vcol,
&index_defs[a]);
}

DBUG_EXECUTE_IF(
"create_index_metadata_fail",
if (a + 1 == ctx->num_to_add_index) {
ctx->trx->error_state = DB_OUT_OF_FILE_SPACE;
ctx->add_index[a] = NULL;
goto index_created;
});
ctx->add_index[a] = row_merge_create_index(
ctx->trx, ctx->new_table, &index_defs[a], add_v);

#ifndef DBUG_OFF
index_created:
#endif
add_key_nums[a] = index_defs[a].key_number;

if (!ctx->add_index[a]) {
error = ctx->trx->error_state;
DBUG_ASSERT(error != DB_SUCCESS);
while (--a >= 0) {
dict_mem_index_free(ctx->add_index[a]);
}
goto error_handling;
}

@@ -2,7 +2,7 @@
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2013, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1599,31 +1599,21 @@ dict_tables_have_same_db(
/** Get an index by name.
@param[in] table the table where to look for the index
@param[in] name the index name to look for
@param[in] committed true=search for committed,
false=search for uncommitted
@return index, NULL if does not exist */
dict_index_t*
dict_table_get_index_on_name(
dict_table_t* table,
const char* name,
bool committed=true)
dict_table_get_index_on_name(dict_table_t* table, const char* name)
MY_ATTRIBUTE((warn_unused_result));

/** Get an index by name.
@param[in] table the table where to look for the index
@param[in] name the index name to look for
@param[in] committed true=search for committed,
false=search for uncommitted
@return index, NULL if does not exist */
inline
const dict_index_t*
dict_table_get_index_on_name(
const dict_table_t* table,
const char* name,
bool committed=true)
dict_table_get_index_on_name(const dict_table_t* table, const char* name)
{
return(dict_table_get_index_on_name(
const_cast<dict_table_t*>(table), name, committed));
return dict_table_get_index_on_name(const_cast<dict_table_t*>(table),
name);
}

/***************************************************************
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2018, MariaDB Corporation.
Copyright (c) 2014, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -4310,7 +4310,7 @@ dberr_t
row_merge_create_index_graph(
trx_t* trx,
dict_table_t* table,
dict_index_t* index,
dict_index_t*& index,
const dict_add_v_col_t* add_v)
{
ind_node_t* node; /*!< Index creation node */
@@ -4337,6 +4337,8 @@ row_merge_create_index_graph(

err = trx->error_state;

index = node->index;

que_graph_free((que_t*) que_node_get_parent(thr));

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

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

if (err == DB_SUCCESS) {

index = dict_table_get_index_on_name(table, index_def->name,
index_def->rebuild);

ut_a(index);

ut_ad(index != index_template);
index->parser = index_def->parser;
index->has_new_v_col = has_new_v_col;

/* Note the id of the transaction that created this
index, we use it to restrict readers from accessing
this index, to ensure read consistency. */
ut_ad(index->trx_id == trx->id);
} else {
dict_mem_index_free(index);
ut_ad(!index || index == index_template);
if (index) {
dict_mem_index_free(index);
}
index = NULL;
}

@@ -706,8 +706,7 @@ row_mysql_handle_errors(
switch (err) {
case DB_LOCK_WAIT_TIMEOUT:
if (row_rollback_on_timeout) {
trx_rollback_to_savepoint(trx, NULL);
break;
goto rollback;
}
/* fall through */
case DB_DUPLICATE_KEY:
@@ -726,6 +725,7 @@ row_mysql_handle_errors(
case DB_TABLE_NOT_FOUND:
case DB_DECRYPTION_FAILED:
case DB_COMPUTE_VALUE_FAILED:
rollback_to_savept:
DBUG_EXECUTE_IF("row_mysql_crash_if_error", {
log_buffer_flush_to_disk();
DBUG_SUICIDE(); });
@@ -752,6 +752,7 @@ row_mysql_handle_errors(

case DB_DEADLOCK:
case DB_LOCK_TABLE_FULL:
rollback:
/* Roll back the whole transaction; this resolution was added
to version 3.23.43 */

@@ -773,13 +774,13 @@ row_mysql_handle_errors(
" tablespace. If the mysqld server crashes after"
" the startup or when you dump the tables. "
<< FORCE_RECOVERY_MSG;
break;
goto rollback_to_savept;
case DB_FOREIGN_EXCEED_MAX_CASCADE:
ib::error() << "Cannot delete/update rows with cascading"
" foreign key constraints that exceed max depth of "
<< FK_MAX_CASCADE_DEL << ". Please drop excessive"
" foreign constraints and try again";
break;
goto rollback_to_savept;
default:
ib::fatal() << "Unknown error code " << err << ": "
<< ut_strerr(err);
@@ -3097,10 +3097,18 @@ prepare_inplace_alter_table_dict(
/* Create the indexes in SYS_INDEXES and load into dictionary. */

for (ulint a = 0; a < ctx->num_to_add_index; a++) {

DBUG_EXECUTE_IF(
"create_index_metadata_fail",
if (a + 1 == ctx->num_to_add_index) {
ctx->trx->error_state = DB_OUT_OF_FILE_SPACE;
ctx->add_index[a] = NULL;
goto index_created;
});
ctx->add_index[a] = row_merge_create_index(
ctx->trx, ctx->new_table, &index_defs[a]);

#ifndef DBUG_OFF
index_created:
#endif
add_key_nums[a] = index_defs[a].key_number;

if (!ctx->add_index[a]) {
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -84,7 +85,7 @@ ut_dbg_assertion_failed(
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) do {EXPR;} while (0)
#define ut_d(EXPR) EXPR
#else
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR)
@@ -1,7 +1,7 @@
/*****************************************************************************

Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2018, MariaDB Corporation.
Copyright (c) 2014, 2019, MariaDB Corporation.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -3705,7 +3705,7 @@ row_merge_create_index_graph(
/*=========================*/
trx_t* trx, /*!< in: trx */
dict_table_t* table, /*!< in: table */
dict_index_t* index) /*!< in: index */
dict_index_t*& index) /*!< in,out: index */
{
ind_node_t* node; /*!< Index creation node */
mem_heap_t* heap; /*!< Memory heap */
@@ -3729,6 +3729,8 @@ row_merge_create_index_graph(

err = trx->error_state;

index = node->index;

que_graph_free((que_t*) que_node_get_parent(thr));

return(err);
@@ -3770,20 +3772,21 @@ row_merge_create_index(
ifield->prefix_len);
}

ut_d(const dict_index_t* const index_template = index);
/* Add the index to SYS_INDEXES, using the index prototype. */
err = row_merge_create_index_graph(trx, table, index);

if (err == DB_SUCCESS) {

index = dict_table_get_index_on_name(table, index_def->name);

ut_a(index);

ut_ad(index != index_template);
/* Note the id of the transaction that created this
index, we use it to restrict readers from accessing
this index, to ensure read consistency. */
ut_ad(index->trx_id == trx->id);
} else {
ut_ad(!index || index == index_template);
if (index) {
dict_mem_index_free(index);
}
index = NULL;
}

0 comments on commit 913e33e

Please sign in to comment.