diff --git a/libmariadb b/libmariadb index bce6c801380..5fa9c4615e7 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit bce6c8013805f203b38e52c979b22b3141334f3c +Subproject commit 5fa9c4615e71b696b84b4c77aefa197466526a13 diff --git a/mysql-test/main/plugin_auth.result b/mysql-test/main/plugin_auth.result index e470cc010c0..eeb65187fea 100644 --- a/mysql-test/main/plugin_auth.result +++ b/mysql-test/main/plugin_auth.result @@ -42,7 +42,13 @@ connection default; disconnect plug_con; ## test bad credentials ERROR 28000: Access denied for user 'plug'@'localhost' (using password: YES) -## test bad default plugin : should get CR_AUTH_PLUGIN_CANNOT_LOAD +## test bad default plugin : nothing bad happens, as that plugin was't required by the server +connect plug_con_wrongp,localhost,plug,plug_dest,,,,,wrong_plugin_name; +select USER(),CURRENT_USER(); +USER() CURRENT_USER() +plug@localhost plug_dest@% +connection default; +disconnect plug_con_wrongp; ## test correct default plugin connect plug_con_rightp,localhost,plug,plug_dest,,,,,auth_test_plugin; connection plug_con_rightp; diff --git a/mysql-test/main/plugin_auth.test b/mysql-test/main/plugin_auth.test index c3c18b7e427..1700a755492 100644 --- a/mysql-test/main/plugin_auth.test +++ b/mysql-test/main/plugin_auth.test @@ -45,13 +45,11 @@ disconnect plug_con; connect(plug_con,localhost,plug,bad_credentials); --enable_query_log ---echo ## test bad default plugin : should get CR_AUTH_PLUGIN_CANNOT_LOAD ---disable_result_log ---disable_query_log ---error 2059 +--echo ## test bad default plugin : nothing bad happens, as that plugin was't required by the server connect(plug_con_wrongp,localhost,plug,plug_dest,,,,,wrong_plugin_name); ---enable_query_log ---enable_result_log +select USER(),CURRENT_USER(); +connection default; +disconnect plug_con_wrongp; --echo ## test correct default plugin connect(plug_con_rightp,localhost,plug,plug_dest,,,,,auth_test_plugin); diff --git a/mysql-test/suite/innodb/r/create_select.result b/mysql-test/suite/innodb/r/create_select.result new file mode 100644 index 00000000000..f5db880816e --- /dev/null +++ b/mysql-test/suite/innodb/r/create_select.result @@ -0,0 +1,10 @@ +connect con1, localhost, root,,; +connection default; +CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000; +connection con1; +KILL QUERY @id; +disconnect con1; +connection default; +ERROR 70100: Query execution was interrupted +CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-virtual-columns-debug.result b/mysql-test/suite/innodb/r/innodb-virtual-columns-debug.result new file mode 100644 index 00000000000..efe43945c69 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-virtual-columns-debug.result @@ -0,0 +1,18 @@ +CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; +INSERT INTO t1 () VALUES (),(); +connect con1,localhost,root,,test; +ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; +SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; +DELETE FROM t1; +connection default; +SET debug_sync= "now WAIT_FOR delete_open"; +SET debug_sync= "ib_open_after_dict_open SIGNAL another_open"; +SELECT a FROM t1; +a +NULL +NULL +connection con1; +disconnect con1; +connection default; +SET debug_sync= "RESET"; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/create_select.test b/mysql-test/suite/innodb/t/create_select.test new file mode 100644 index 00000000000..8103902e5f6 --- /dev/null +++ b/mysql-test/suite/innodb/t/create_select.test @@ -0,0 +1,28 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/count_sessions.inc + +let $ID= `SELECT @id := CONNECTION_ID()`; + +connect (con1, localhost, root,,); +let $ignore= `SELECT @id := $ID`; + +connection default; +send CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000; + +connection con1; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Sending data' + and info = 'CREATE TABLE t1 ENGINE=InnoDB SELECT * FROM seq_1_to_100000000'; +--source include/wait_condition.inc +KILL QUERY @id; +disconnect con1; + +connection default; +--error ER_QUERY_INTERRUPTED +reap; + +CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB; +DROP TABLE t1; +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb-virtual-columns-debug.test b/mysql-test/suite/innodb/t/innodb-virtual-columns-debug.test new file mode 100644 index 00000000000..6de43dd80f8 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-virtual-columns-debug.test @@ -0,0 +1,27 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +# +# MDEV-17005 ASAN heap-use-after-free in innobase_get_computed_value +# +CREATE TABLE t1 (a INT, b INT AS (a), KEY(b)) ENGINE=InnoDB; + +INSERT INTO t1 () VALUES (),(); +--connect (con1,localhost,root,,test) +ALTER TABLE t1 ADD COLUMN x INT as (a), add key(x), ALGORITHM=COPY; +SET debug_sync= "ib_open_after_dict_open SIGNAL delete_open WAIT_FOR another_open"; +--send +DELETE FROM t1; +--connection default +SET debug_sync= "now WAIT_FOR delete_open"; +SET debug_sync= "ib_open_after_dict_open SIGNAL another_open"; +SELECT a FROM t1; +--connection con1 +--reap + +# Cleanup +--disconnect con1 +--connection default +SET debug_sync= "RESET"; +DROP TABLE t1; diff --git a/plugin/auth_ed25519/CMakeLists.txt b/plugin/auth_ed25519/CMakeLists.txt index ff6651c528d..1a3d5cc4bce 100644 --- a/plugin/auth_ed25519/CMakeLists.txt +++ b/plugin/auth_ed25519/CMakeLists.txt @@ -24,8 +24,8 @@ ENDIF() MYSQL_ADD_PLUGIN(auth_ed25519 server_ed25519.c ${REF10_SOURCES} MODULE_ONLY) # client plugin and unit test ed25519-t can use the library -MYSQL_ADD_PLUGIN(client_ed25519 client_ed25519.c MODULE_ONLY - CLIENT LINK_LIBRARIES ref10 mysys_ssl COMPONENT ClientPlugins) +#MYSQL_ADD_PLUGIN(client_ed25519 client_ed25519.c MODULE_ONLY +# CLIENT LINK_LIBRARIES ref10 mysys_ssl COMPONENT ClientPlugins) IF(WITH_UNIT_TESTS) MY_ADD_TESTS(ed25519 LINK_LIBRARIES ref10 mysys_ssl) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5048ba091c6..b23e282ddc8 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5798,6 +5798,7 @@ innobase_build_v_templ( ulint n_v_col = ib_table->n_v_cols; bool marker[REC_MAX_N_FIELDS]; + DBUG_ENTER("innobase_build_v_templ"); ut_ad(ncol < REC_MAX_N_FIELDS); if (add_v != NULL) { @@ -5814,7 +5815,7 @@ innobase_build_v_templ( if (!locked) { mutex_exit(&dict_sys->mutex); } - return; + DBUG_VOID_RETURN; } memset(marker, 0, sizeof(bool) * ncol); @@ -5825,7 +5826,8 @@ innobase_build_v_templ( s_templ->n_col = ncol; s_templ->n_v_col = n_v_col; s_templ->rec_len = table->s->reclength; - s_templ->default_rec = table->s->default_values; + s_templ->default_rec = UT_NEW_ARRAY_NOKEY(uchar, s_templ->rec_len); + memcpy(s_templ->default_rec, table->s->default_values, s_templ->rec_len); /* Mark those columns could be base columns */ for (ulint i = 0; i < ib_table->n_v_cols; i++) { @@ -5924,6 +5926,7 @@ innobase_build_v_templ( s_templ->db_name = table->s->db.str; s_templ->tb_name = table->s->table_name.str; + DBUG_VOID_RETURN; } /** Check consistency between .frm indexes and InnoDB indexes. @@ -6121,6 +6124,8 @@ ha_innobase::open(const char* name, int, uint) ib_table = open_dict_table(name, norm_name, is_part, ignore_err); + DEBUG_SYNC(thd, "ib_open_after_dict_open"); + if (NULL == ib_table) { if (is_part) { @@ -6226,14 +6231,6 @@ no_such_table: mutex_enter(&dict_sys->mutex); if (ib_table->vc_templ == NULL) { ib_table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); - } else if (ib_table->get_ref_count() == 1) { - /* Clean and refresh the template if no one else - get hold on it */ - dict_free_vc_templ(ib_table->vc_templ); - ib_table->vc_templ->vtempl = NULL; - } - - if (ib_table->vc_templ->vtempl == NULL) { innobase_build_v_templ( table, ib_table, ib_table->vc_templ, NULL, true); @@ -20700,6 +20697,7 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) if (table->vc_templ != NULL) { return NULL; } + DBUG_ENTER("innobase_init_vc_templ"); table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); @@ -20707,13 +20705,13 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) ut_ad(mysql_table); if (!mysql_table) { - return NULL; + DBUG_RETURN(NULL); } mutex_enter(&dict_sys->mutex); innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true); mutex_exit(&dict_sys->mutex); - return mysql_table; + DBUG_RETURN(mysql_table); } /** Change dbname and table name in table->vc_templ. @@ -20915,6 +20913,7 @@ innobase_get_computed_value( ut_ad(thd != NULL); ut_ad(mysql_table); + DBUG_ENTER("innobase_get_computed_value"); const mysql_row_templ_t* vctempl = index->table->vc_templ->vtempl[ index->table->vc_templ->n_col + col->v_pos]; @@ -21003,7 +21002,7 @@ innobase_get_computed_value( stderr); dtuple_print(stderr, row); #endif /* INNODB_VIRTUAL_DEBUG */ - return(NULL); + DBUG_RETURN(NULL); } if (vctempl->mysql_null_bit_mask @@ -21011,7 +21010,7 @@ innobase_get_computed_value( & vctempl->mysql_null_bit_mask)) { dfield_set_null(field); field->type.prtype |= DATA_VIRTUAL; - return(field); + DBUG_RETURN(field); } row_mysql_store_col_in_innobase_format( @@ -21043,7 +21042,7 @@ innobase_get_computed_value( dfield_dup(field, heap); } - return(field); + DBUG_RETURN(field); } diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 4820b03b565..4174580c918 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1412,6 +1412,9 @@ void dict_free_vc_templ( dict_vcol_templ_t* vc_templ) { + UT_DELETE_ARRAY(vc_templ->default_rec); + vc_templ->default_rec = NULL; + if (vc_templ->vtempl != NULL) { ut_ad(vc_templ->n_v_col > 0); for (ulint i = 0; i < vc_templ->n_col diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h index fa4c2526ae3..6d0f95cba19 100644 --- a/storage/innobase/include/mem0mem.h +++ b/storage/innobase/include/mem0mem.h @@ -73,7 +73,7 @@ allocations of small buffers. */ /** If a memory heap is allowed to grow into the buffer pool, the following is the maximum size for a single allocated buffer: */ -#define MEM_MAX_ALLOC_IN_BUF (srv_page_size - 200) +#define MEM_MAX_ALLOC_IN_BUF (srv_page_size - 200 + REDZONE_SIZE) /** Space needed when allocating for a user a field of length N. The space is allocated only in multiples of UNIV_MEM_ALIGNMENT. */ diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index bab7c8d71ad..3b4992a1a98 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -183,13 +183,15 @@ mem_heap_alloc( ulint n) { mem_block_t* block; - void* buf; + byte* buf; ulint free; ut_d(mem_block_validate(heap)); block = UT_LIST_GET_LAST(heap->base); + n += REDZONE_SIZE; + ut_ad(!(block->type & MEM_HEAP_BUFFER) || (n <= MEM_MAX_ALLOC_IN_BUF)); /* Check if there is enough space in block. If not, create a new @@ -212,7 +214,8 @@ mem_heap_alloc( mem_block_set_free(block, free + MEM_SPACE_NEEDED(n)); - UNIV_MEM_ALLOC(buf, n); + buf = buf + REDZONE_SIZE; + UNIV_MEM_ALLOC(buf, n - REDZONE_SIZE); return(buf); } @@ -342,6 +345,8 @@ mem_heap_free_top( ut_d(mem_block_validate(heap)); + n += REDZONE_SIZE; + block = UT_LIST_GET_LAST(heap->base); /* Subtract the free field of block */ diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 898e57a5f53..3bc2f57a325 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -61,7 +61,7 @@ Created 9/20/1997 Heikki Tuuri /** Log records are stored in the hash table in chunks at most of this size; this must be less than srv_page_size as it is stored in the buffer pool */ -#define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t)) +#define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t) - REDZONE_SIZE) /** Read-ahead area in applying log records to file pages */ #define RECV_READ_AHEAD_AREA 32 diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 679aa63f9d5..ad6d6330913 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -3418,7 +3418,9 @@ row_drop_table_for_mysql( calling btr_search_drop_page_hash_index() while we hold the InnoDB dictionary lock, we will drop any adaptive hash index entries upfront. */ - bool immune = is_temp_name + const bool immune = is_temp_name + || create_failed + || sqlcom == SQLCOM_CREATE_TABLE || strstr(table->name.m_name, "/FTS"); while (buf_LRU_drop_page_hash_for_tablespace(table)) { diff --git a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test index b39c022fc46..c8c12626139 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/check_ignore_unknown_options.test @@ -1,22 +1,50 @@ -# MariaDB: "xargs" is not present on windows builders. -# we could work around this but this is not a priority. ---source include/not_windows.inc - --disable_warnings let $MYSQLD_DATADIR= `select @@datadir`; let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; let $error_log= $MYSQLTEST_VARDIR/log/my_restart.err; select variable_name, variable_value from information_schema.global_variables where variable_name="rocksdb_ignore_unknown_options"; ---exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i 's/rocksdb_version=.*/rocksdb_version=99.9.9/' {}" ---exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}" +# +# MariaDB: The following shell commands are not portable so we are +# using perl instead: +#--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "sed -i 's/rocksdb_version=.*/rocksdb_version=99.9.9/' {}" +#--exec find $MYSQLD_DATADIR/#rocksdb/OPTIONS* | sort -t- -k 2 -n | tail -1 | xargs -0 -I {} -t sh -c "echo hello=world>>{}" +perl; + my $path=$ENV{MYSQLTEST_VARDIR} . "/mysqld.1/data/\#rocksdb"; + opendir(my $dh, $path) || die "Can't opendir $some_dir: $!"; + my @files = grep { /^OPTIONS/ } readdir($dh); + closedir($dh); + + sub compare_second_as_number { + local $aa= shift; + local $bb= shift; + $aa =~ s/OPTIONS-//; + $bb =~ s/OPTIONS-//; + return $aa <=> $bb; + } + + @sorted_files = sort { compare_second_as_number($a, $b); } @files; + my $last_file= $sorted_files[-1]; + + my $contents=""; + open(my $fh, "<", "$path/$last_file") || die ("Couldn't open $path/$last_file"); + while (<$fh>) { + $_ =~ s/rocksdb_version=.*/rocksdb_version=99.9.9/; + $contents .= $_; + } + close($fh); + $contents .= "hello=world\n"; + open(my $fh, ">", "$path/$last_file") || die("Can't open $path/$file for writing"); + print $fh $contents; + close($fh); +EOF --exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --shutdown_server 10 --error 1 ---exec $MYSQLD_CMD --plugin_load=$HA_ROCKSDB_SO --rocksdb_ignore_unknown_options=0 --loose-console --log-error=$error_log +--exec $MYSQLD_CMD --plugin_load=$HA_ROCKSDB_SO --rocksdb_ignore_unknown_options=0 --log-error=$error_log let SEARCH_FILE= $error_log; let SEARCH_PATTERN= RocksDB: Compatibility check against existing database options failed; diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 18ef364278f..749964284c4 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -78,8 +78,9 @@ IF(UNIX) INSTALL(FILES ${out} DESTINATION ${inst_location}/policy/selinux COMPONENT SupportFiles) ENDFOREACH() IF(RPM) - EXECUTE_PROCESS(COMMAND rpm -q --qf "%{VERSION}-%{RELEASE}" libsepol OUTPUT_VARIABLE LIBSEPOL_VERSION) - IF (LIBSEPOL_VERSION) + EXECUTE_PROCESS(COMMAND rpm -q --qf "%{VERSION}-%{RELEASE}" libsepol + OUTPUT_VARIABLE LIBSEPOL_VERSION RESULT_VARIABLE err) + IF (NOT err) SET(CPACK_RPM_server_PACKAGE_REQUIRES "${CPACK_RPM_server_PACKAGE_REQUIRES} libsepol >= ${LIBSEPOL_VERSION}" PARENT_SCOPE)