summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-10-27 14:51:10 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2016-10-29 10:09:06 +0300
commit885577fb10cba63a4a140bd91257a3cd2b402159 (patch)
tree64ad9e60c526db676f470847aa6b1f1eabf510ec /storage
parentbc323727de312b32e80ae9590e2346414746a594 (diff)
downloadmariadb-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.cc18
-rw-r--r--storage/innobase/fil/fil0crypt.cc6
-rw-r--r--storage/innobase/handler/ha_innodb.cc50
-rw-r--r--storage/xtradb/buf/buf0buf.cc11
-rw-r--r--storage/xtradb/fil/fil0crypt.cc6
-rw-r--r--storage/xtradb/handler/ha_innodb.cc36
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);
+ }
}
/********************************************************************//**