diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-02-06 10:47:55 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-02-06 15:40:16 +0200 |
commit | ddf2fac73381b84114d31c178d9207afc27bfa4d (patch) | |
tree | f177b891fdf6e0ca10cacaf420a9822849eaa9cd /storage/innobase/buf/buf0dblwr.cc | |
parent | bc4686f0f4d17dc57dd727c9f5390caa3022bdca (diff) | |
download | mariadb-git-ddf2fac73381b84114d31c178d9207afc27bfa4d.tar.gz |
MDEV-11759: Encryption code in MariaDB 10.1/10.2 causes
compatibility problems
Pages that are encrypted contain post encryption checksum on
different location that normal checksum fields. Therefore,
we should before decryption check this checksum to avoid
unencrypting corrupted pages. After decryption we can use
traditional checksum check to detect if page is corrupted
or unencryption was done using incorrect key.
Pages that are page compressed do not contain any checksum,
here we need to fist unencrypt, decompress and finally
use tradional checksum check to detect page corruption
or that we used incorrect key in unencryption.
buf0buf.cc: buf_page_is_corrupted() mofified so that
compressed pages are skipped.
buf0buf.h, buf_block_init(), buf_page_init_low():
removed unnecessary page_encrypted, page_compressed,
stored_checksum, valculated_checksum fields from
buf_page_t
buf_page_get_gen(): use new buf_page_check_corrupt() function
to detect corrupted pages.
buf_page_check_corrupt(): If page was not yet decrypted
check if post encryption checksum still matches.
If page is not anymore encrypted, use buf_page_is_corrupted()
traditional checksum method.
If page is detected as corrupted and it is not encrypted
we print corruption message to error log.
If page is still encrypted or it was encrypted and now
corrupted, we will print message that page is
encrypted to error log.
buf_page_io_complete(): use new buf_page_check_corrupt()
function to detect corrupted pages.
buf_page_decrypt_after_read(): Verify post encryption
checksum before tring to decrypt.
fil0crypt.cc: fil_encrypt_buf() verify post encryption
checksum and ind fil_space_decrypt() return true
if we really decrypted the page.
fil_space_verify_crypt_checksum(): rewrite to use
the method used when calculating post encryption
checksum. We also check if post encryption checksum
matches that traditional checksum check does not
match.
fil0fil.ic: Add missed page type encrypted and page
compressed to fil_get_page_type_name()
Note that this change does not yet fix innochecksum tool,
that will be done in separate MDEV.
Fix test failures caused by buf page corruption injection.
Diffstat (limited to 'storage/innobase/buf/buf0dblwr.cc')
-rw-r--r-- | storage/innobase/buf/buf0dblwr.cc | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index e49185f6a1f..02980c80112 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -383,10 +383,11 @@ buf_dblwr_init_or_load_pages( doublewrite = read_buf + TRX_SYS_DOUBLEWRITE; if (mach_read_from_4(read_buf + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) != 0) { + bool decrypted = false; byte* tmp = fil_space_decrypt((ulint)TRX_SYS_SPACE, read_buf + UNIV_PAGE_SIZE, UNIV_PAGE_SIZE, /* page size */ - read_buf); + read_buf, &decrypted); doublewrite = tmp + TRX_SYS_DOUBLEWRITE; } @@ -487,6 +488,7 @@ buf_dblwr_process() byte* read_buf; byte* unaligned_read_buf; recv_dblwr_t& recv_dblwr = recv_sys->dblwr; + fil_space_t* space=NULL; unaligned_read_buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE)); @@ -514,6 +516,10 @@ buf_dblwr_process() continue; } + if (!space) { + space = fil_space_found_by_id(space_id); + } + ulint zip_size = fil_space_get_zip_size(space_id); ut_ad(!buf_page_is_zeroes(page, zip_size)); @@ -548,9 +554,9 @@ buf_dblwr_process() } if (fil_space_verify_crypt_checksum( - read_buf, zip_size) + read_buf, zip_size, NULL, page_no) || !buf_page_is_corrupted( - true, read_buf, zip_size)) { + true, read_buf, zip_size, space)) { /* The page is good; there is no need to consult the doublewrite buffer. */ continue; @@ -573,8 +579,8 @@ buf_dblwr_process() NULL, page, UNIV_PAGE_SIZE, NULL, true); } - if (!fil_space_verify_crypt_checksum(page, zip_size) - && buf_page_is_corrupted(true, page, zip_size)) { + if (!fil_space_verify_crypt_checksum(page, zip_size, NULL, page_no) + && buf_page_is_corrupted(true, page, zip_size, space)) { if (!is_all_zero) { ib_logf(IB_LOG_LEVEL_WARN, "A doublewrite copy of page " |