diff options
author | Eugene Kosov <claprix@yandex.ru> | 2021-11-01 23:51:58 +0600 |
---|---|---|
committer | Eugene Kosov <claprix@yandex.ru> | 2021-11-17 15:49:22 +0600 |
commit | ed0a224b3d42423699d977c338e3da05fccafaf2 (patch) | |
tree | e4d99482e862f9cafd3d3c90b2d325fc530b12cb /storage | |
parent | 8f24f5fee267706c0a5f475140a19a9304e224b4 (diff) | |
download | mariadb-git-ed0a224b3d42423699d977c338e3da05fccafaf2.tar.gz |
MDEV-26747 improve corruption check for encrypted tables on ALTER IMPORTbb-10.2-MDEV-26747-corruption-check
fil_space_decrypt(): change signature to return status via dberr_t only.
Also replace impossible condition with an assertion and prove it via
test cases.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 42 | ||||
-rw-r--r-- | storage/innobase/include/fil0crypt.h | 8 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 21 |
3 files changed, 26 insertions, 45 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index ff6294e85b7..46fc12ee6b0 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -668,16 +668,14 @@ fil_space_encrypt( @param[in] tmp_frame Temporary buffer @param[in] page_size Page size @param[in,out] src_frame Page to decrypt -@param[out] err DB_SUCCESS or DB_DECRYPTION_FAILED -@return true if page decrypted, false if not.*/ +@return DB_SUCCESS or error */ UNIV_INTERN -bool +dberr_t fil_space_decrypt( fil_space_crypt_t* crypt_data, byte* tmp_frame, const page_size_t& page_size, - byte* src_frame, - dberr_t* err) + byte* src_frame) { ulint page_type = mach_read_from_2(src_frame+FIL_PAGE_TYPE); uint key_version = mach_read_from_4(src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); @@ -686,12 +684,7 @@ fil_space_decrypt( uint space = mach_read_from_4(src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN); - *err = DB_SUCCESS; - - if (key_version == ENCRYPTION_KEY_NOT_ENCRYPTED) { - return false; - } - + ut_a(key_version != ENCRYPTION_KEY_NOT_ENCRYPTED); ut_a(crypt_data != NULL && crypt_data->is_encrypted()); /* read space & lsn */ @@ -722,8 +715,7 @@ fil_space_decrypt( if (! ((rc == MY_AES_OK) && ((ulint) dstlen == srclen))) { if (rc == -1) { - *err = DB_DECRYPTION_FAILED; - return false; + return DB_DECRYPTION_FAILED; } ib::fatal() << "Unable to decrypt data-block " @@ -748,7 +740,7 @@ fil_space_decrypt( srv_stats.pages_decrypted.inc(); - return true; /* page was decrypted */ + return DB_SUCCESS; /* page was decrypted */ } /** @@ -765,27 +757,21 @@ fil_space_decrypt( byte* tmp_frame, byte* src_frame) { - dberr_t err = DB_SUCCESS; - byte* res = NULL; const page_size_t page_size(space->flags); ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted()); ut_ad(space->n_pending_ios > 0); - bool encrypted = fil_space_decrypt(space->crypt_data, tmp_frame, - page_size, src_frame, &err); - - if (err == DB_SUCCESS) { - if (encrypted) { - /* Copy the decrypted page back to page buffer, not - really any other options. */ - memcpy(src_frame, tmp_frame, page_size.physical()); - } - - res = src_frame; + if (DB_SUCCESS != fil_space_decrypt(space->crypt_data, tmp_frame, + page_size, src_frame)) { + return NULL; } - return res; + /* Copy the decrypted page back to page buffer, not + really any other options. */ + memcpy(src_frame, tmp_frame, page_size.physical()); + + return src_frame; } /****************************************************************** diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index af6c930659b..42b38c395d8 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -359,16 +359,14 @@ Decrypt a page. @param[in] tmp_frame Temporary buffer @param[in] page_size Page size @param[in,out] src_frame Page to decrypt -@param[out] err DB_SUCCESS or error -@return true if page decrypted, false if not.*/ +@return DB_SUCCESS or error */ UNIV_INTERN -bool +dberr_t fil_space_decrypt( fil_space_crypt_t* crypt_data, byte* tmp_frame, const page_size_t& page_size, - byte* src_frame, - dberr_t* err); + byte* src_frame); /****************************************************************** Decrypt a page diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index f4df44b3e2b..b7f73bc8e19 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -3502,9 +3502,12 @@ page_corrupted: if (!fil_space_verify_crypt_checksum(readptr, get_page_size())) goto page_corrupted; - if (!fil_space_decrypt(iter.crypt_data, readptr, - get_page_size(), readptr, &err) || - err != DB_SUCCESS) + if (ENCRYPTION_KEY_NOT_ENCRYPTED == + mach_read_from_4(readptr + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)) + goto page_corrupted; + + if ((err = fil_space_decrypt(iter.crypt_data, readptr, + get_page_size(), readptr))) goto func_exit; } @@ -3647,7 +3650,6 @@ page_corrupted: } else if (!mach_read_from_4( FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + src)) { -not_encrypted: if (block->page.id.page_no() == 0 && block->page.zip.data) { block->page.zip.data = src; @@ -3666,18 +3668,13 @@ not_encrypted: goto page_corrupted; } - decrypted = fil_space_decrypt( + if ((err = fil_space_decrypt( iter.crypt_data, dst, - callback.get_page_size(), src, &err); - - if (err != DB_SUCCESS) { + callback.get_page_size(), src))) { goto func_exit; } - if (!decrypted) { - goto not_encrypted; - } - + decrypted = true; updated = true; } |