diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-10-27 14:51:10 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-10-29 10:09:06 +0300 |
commit | 885577fb10cba63a4a140bd91257a3cd2b402159 (patch) | |
tree | 64ad9e60c526db676f470847aa6b1f1eabf510ec /storage | |
parent | bc323727de312b32e80ae9590e2346414746a594 (diff) | |
download | mariadb-git-885577fb10cba63a4a140bd91257a3cd2b402159.tar.gz |
MDEV-11004: Unable to start (Segfault or os error 2) when encryption key missing
Two problems:
(1) When pushing warning to sql-layer we need to check that thd != NULL
to avoid NULL-pointer reference.
(2) At tablespace key rotation if used key_id is not found from
encryption plugin tablespace should not be rotated.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 18 | ||||
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 6 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 50 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0buf.cc | 11 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0crypt.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 36 |
6 files changed, 83 insertions, 44 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 94913098063..9d098c1caf6 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -317,6 +317,9 @@ on the io_type */ ? (counter##_READ) \ : (counter##_WRITTEN)) +/* prototypes for new functions added to ha_innodb.cc */ +trx_t* innobase_get_trx(); + /********************************************************************//** Check if page is maybe compressed, encrypted or both when we encounter corrupted page. Note that we can't be 100% sure if page is corrupted @@ -4485,7 +4488,6 @@ buf_page_check_corrupt( ulint zip_size = buf_page_get_zip_size(bpage); byte* dst_frame = (zip_size) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - unsigned key_version = bpage->key_version; bool page_compressed = bpage->page_encrypted; ulint stored_checksum = bpage->stored_checksum; ulint calculated_checksum = bpage->stored_checksum; @@ -4495,6 +4497,7 @@ buf_page_check_corrupt( fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id); fil_space_t* space = fil_space_found_by_id(space_id); bool corrupted = true; + ulint key_version = bpage->key_version; if (key_version != 0 || page_compressed_encrypted) { bpage->encrypted = true; @@ -4524,7 +4527,7 @@ buf_page_check_corrupt( stored_checksum, calculated_checksum); } ib_logf(IB_LOG_LEVEL_ERROR, - "Reason could be that key_version %u in page " + "Reason could be that key_version %lu in page " "or in crypt_data %p could not be found.", key_version, crypt_data); ib_logf(IB_LOG_LEVEL_ERROR, @@ -4538,7 +4541,7 @@ buf_page_check_corrupt( "Block in space_id %lu in file %s encrypted.", space_id, space ? space->name : "NULL"); ib_logf(IB_LOG_LEVEL_ERROR, - "However key management plugin or used key_id %u is not found or" + "However key management plugin or used key_id %lu is not found or" " used encryption algorithm or method does not match.", key_version); ib_logf(IB_LOG_LEVEL_ERROR, @@ -4718,6 +4721,7 @@ database_corrupted: return(false); } else { corrupted = buf_page_check_corrupt(bpage); + ulint key_version = bpage->key_version; if (corrupted) { ib_logf(IB_LOG_LEVEL_ERROR, @@ -4726,12 +4730,12 @@ database_corrupted: ut_error; } - ib_push_warning((void *)NULL, DB_DECRYPTION_FAILED, + ib_push_warning(innobase_get_trx(), DB_DECRYPTION_FAILED, "Table in tablespace %lu encrypted." - "However key management plugin or used key_id %u is not found or" + "However key management plugin or used key_id %lu is not found or" " used encryption algorithm or method does not match." " Can't continue opening the table.", - (ulint)bpage->space, bpage->key_version); + (ulint)bpage->space, key_version); if (bpage->space > TRX_SYS_SPACE) { if (corrupted) { @@ -4890,7 +4894,7 @@ buf_all_freed_instance( const buf_block_t* block = buf_chunk_not_freed(chunk); if (UNIV_LIKELY_NULL(block)) { - if (block->page.key_version == 0) { + if (block->page.key_version == 0) { fil_space_t* space = fil_space_get(block->page.space); ib_logf(IB_LOG_LEVEL_ERROR, "Page %u %u still fixed or dirty.", diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index bedaf7cfe49..72e3454cbb5 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1351,6 +1351,12 @@ fil_crypt_space_needs_rotation( } } + /* If used key_id is not found from encryption plugin we can't + continue to rotate the tablespace */ + if (fil_crypt_get_latest_key_version(crypt_data) == ENCRYPTION_KEY_VERSION_INVALID) { + return false; + } + mutex_enter(&crypt_data->mutex); do { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f18ce89fb4c..d790bf4c4b6 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2601,6 +2601,20 @@ check_trx_exists( return(trx); } +/************************************************************************* +Gets current trx. */ +trx_t* +innobase_get_trx() +{ + THD *thd=current_thd; + if (likely(thd != 0)) { + trx_t*& trx = thd_to_trx(thd); + return(trx); + } else { + return(NULL); + } +} + /*********************************************************************//** Note that a transaction has been registered with MySQL. @return true if transaction is registered with MySQL 2PC coordinator */ @@ -20664,15 +20678,17 @@ ib_push_warning( char *buf; #define MAX_BUF_SIZE 4*1024 - va_start(args, format); - buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); - vsprintf(buf,format, args); + if (thd) { + va_start(args, format); + buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); + vsprintf(buf,format, args); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - convert_error_code_to_mysql((dberr_t)error, 0, thd), - buf); - my_free(buf); - va_end(args); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + convert_error_code_to_mysql((dberr_t)error, 0, thd), + buf); + my_free(buf); + va_end(args); + } } /********************************************************************//** @@ -20694,15 +20710,17 @@ ib_push_warning( thd = current_thd; } - va_start(args, format); - buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); - vsprintf(buf,format, args); + if (thd) { + va_start(args, format); + buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); + vsprintf(buf,format, args); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - convert_error_code_to_mysql((dberr_t)error, 0, thd), - buf); - my_free(buf); - va_end(args); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + convert_error_code_to_mysql((dberr_t)error, 0, thd), + buf); + my_free(buf); + va_end(args); + } } /********************************************************************//** diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index e77225a3bd2..f5ac842f4e8 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -4601,7 +4601,6 @@ buf_page_check_corrupt( ulint zip_size = buf_page_get_zip_size(bpage); byte* dst_frame = (zip_size) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; - unsigned key_version = bpage->key_version; bool page_compressed = bpage->page_encrypted; ulint stored_checksum = bpage->stored_checksum; ulint calculated_checksum = bpage->stored_checksum; @@ -4611,6 +4610,7 @@ buf_page_check_corrupt( fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space_id); fil_space_t* space = fil_space_found_by_id(space_id); bool corrupted = true; + ulint key_version = bpage->key_version; if (key_version != 0 || page_compressed_encrypted) { bpage->encrypted = true; @@ -4640,7 +4640,7 @@ buf_page_check_corrupt( stored_checksum, calculated_checksum); } ib_logf(IB_LOG_LEVEL_ERROR, - "Reason could be that key_version %u in page " + "Reason could be that key_version %lu in page " "or in crypt_data %p could not be found.", key_version, crypt_data); ib_logf(IB_LOG_LEVEL_ERROR, @@ -4654,7 +4654,7 @@ buf_page_check_corrupt( "Block in space_id %lu in file %s encrypted.", space_id, space ? space->name : "NULL"); ib_logf(IB_LOG_LEVEL_ERROR, - "However key management plugin or used key_id %u is not found or" + "However key management plugin or used key_id %lu is not found or" " used encryption algorithm or method does not match.", key_version); ib_logf(IB_LOG_LEVEL_ERROR, @@ -4855,6 +4855,7 @@ database_corrupted: return(false); } else { corrupted = buf_page_check_corrupt(bpage); + ulint key_version = bpage->key_version; if (corrupted) { ib_logf(IB_LOG_LEVEL_ERROR, @@ -4865,10 +4866,10 @@ database_corrupted: ib_push_warning(innobase_get_trx(), DB_DECRYPTION_FAILED, "Table in tablespace %lu encrypted." - "However key management plugin or used key_id %u is not found or" + "However key management plugin or used key_id %lu is not found or" " used encryption algorithm or method does not match." " Can't continue opening the table.", - (ulint)bpage->space, bpage->key_version); + (ulint)bpage->space, key_version); if (bpage->space > TRX_SYS_SPACE) { if (corrupted) { diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index bedaf7cfe49..72e3454cbb5 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -1351,6 +1351,12 @@ fil_crypt_space_needs_rotation( } } + /* If used key_id is not found from encryption plugin we can't + continue to rotate the tablespace */ + if (fil_crypt_get_latest_key_version(crypt_data) == ENCRYPTION_KEY_VERSION_INVALID) { + return false; + } + mutex_enter(&crypt_data->mutex); do { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 85bc897efc2..bd76d524e25 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -22245,15 +22245,17 @@ ib_push_warning( char *buf; #define MAX_BUF_SIZE 4*1024 - va_start(args, format); - buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); - vsprintf(buf,format, args); + if (thd) { + va_start(args, format); + buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); + vsprintf(buf,format, args); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - convert_error_code_to_mysql((dberr_t)error, 0, thd), - buf); - my_free(buf); - va_end(args); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + convert_error_code_to_mysql((dberr_t)error, 0, thd), + buf); + my_free(buf); + va_end(args); + } } /********************************************************************//** @@ -22275,15 +22277,17 @@ ib_push_warning( thd = current_thd; } - va_start(args, format); - buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); - vsprintf(buf,format, args); + if (thd) { + va_start(args, format); + buf = (char *)my_malloc(MAX_BUF_SIZE, MYF(MY_WME)); + vsprintf(buf,format, args); - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - convert_error_code_to_mysql((dberr_t)error, 0, thd), - buf); - my_free(buf); - va_end(args); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + convert_error_code_to_mysql((dberr_t)error, 0, thd), + buf); + my_free(buf); + va_end(args); + } } /********************************************************************//** |