summaryrefslogtreecommitdiff
path: root/storage/innobase/fil/fil0crypt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fil/fil0crypt.cc')
-rw-r--r--storage/innobase/fil/fil0crypt.cc193
1 files changed, 46 insertions, 147 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index b0333cd294f..667562e0bd0 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -662,7 +662,7 @@ fil_encrypt_buf(
// store the post-encryption checksum after the key-version
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
- ut_ad(fil_space_verify_crypt_checksum(dst_frame, zip_size, NULL, offset));
+ ut_ad(fil_space_verify_crypt_checksum(dst_frame, zip_size));
srv_stats.pages_encrypted.inc();
@@ -2568,167 +2568,66 @@ encrypted, or corrupted.
@param[in] page Page to verify
@param[in] zip_size zip size
-@param[in] space Tablespace
-@param[in] pageno Page no
-@return true if page is encrypted AND OK, false otherwise */
+@return whether the encrypted page is OK */
UNIV_INTERN
-bool
-fil_space_verify_crypt_checksum(
- byte* page,
- ulint zip_size,
-#ifndef UNIV_INNOCHECKSUM
- const fil_space_t* space,
-#else
- const void* space,
-#endif
- ulint pageno)
+bool fil_space_verify_crypt_checksum(const byte* page, ulint zip_size)
{
- uint key_version = mach_read_from_4(page+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
-
- /* If page is not encrypted, return false */
- if (key_version == 0) {
- return(false);
- }
-
- srv_checksum_algorithm_t algorithm =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- /* If no checksum is used, can't continue checking. */
- if (algorithm == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(true);
- }
-
- /* Read stored post encryption checksum. */
- ib_uint32_t checksum = mach_read_from_4(
- page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4);
-
- /* Declare empty pages non-corrupted */
- if (checksum == 0
- && *reinterpret_cast<const ib_uint64_t*>(page + FIL_PAGE_LSN) == 0
- && buf_page_is_zeroes(page, zip_size)) {
- return(true);
- }
+ ut_ad(mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION));
/* Compressed and encrypted pages do not have checksum. Assume not
corrupted. Page verification happens after decompression in
buf_page_io_complete() using buf_page_is_corrupted(). */
- if (mach_read_from_2(page+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
- return (true);
+ if (mach_read_from_2(page + FIL_PAGE_TYPE)
+ == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ return true;
}
- ib_uint32_t cchecksum1 = 0;
- ib_uint32_t cchecksum2 = 0;
-
- /* Calculate checksums */
- if (zip_size) {
- cchecksum1 = page_zip_calc_checksum(
- page, zip_size, SRV_CHECKSUM_ALGORITHM_CRC32);
-
- cchecksum2 = (cchecksum1 == checksum)
- ? 0
- : page_zip_calc_checksum(
- page, zip_size,
- SRV_CHECKSUM_ALGORITHM_INNODB);
- } else {
- cchecksum1 = buf_calc_page_crc32(page);
- cchecksum2 = (cchecksum1 == checksum)
- ? 0
- : buf_calc_page_new_checksum(page);
- }
+ /* Read stored post encryption checksum. */
+ const ib_uint32_t checksum = mach_read_from_4(
+ page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4);
/* If stored checksum matches one of the calculated checksums
page is not corrupted. */
+ srv_checksum_algorithm_t algorithm = srv_checksum_algorithm_t(
+ srv_checksum_algorithm);
+
+ switch (algorithm) {
+ case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
+ if (zip_size) {
+ return checksum == page_zip_calc_checksum(
+ page, zip_size, SRV_CHECKSUM_ALGORITHM_CRC32);
+ }
- bool encrypted = (checksum == cchecksum1 || checksum == cchecksum2
- || checksum == BUF_NO_CHECKSUM_MAGIC);
-
- /* MySQL 5.6 and MariaDB 10.0 and 10.1 will write an LSN to the
- first page of each system tablespace file at
- FIL_PAGE_FILE_FLUSH_LSN offset. On other pages and in other files,
- the field might have been uninitialized until MySQL 5.5. In MySQL 5.7
- (and MariaDB Server 10.2.2) WL#7990 stopped writing the field for other
- than page 0 of the system tablespace.
-
- Starting from MariaDB 10.1 the field has been repurposed for
- encryption key_version.
-
- Starting with MySQL 5.7 (and MariaDB Server 10.2), the
- field has been repurposed for SPATIAL INDEX pages for
- FIL_RTREE_SPLIT_SEQ_NUM.
-
- Note that FIL_PAGE_FILE_FLUSH_LSN is not included in the InnoDB page
- checksum.
-
- Thus, FIL_PAGE_FILE_FLUSH_LSN could contain any value. While the
- field would usually be 0 for pages that are not encrypted, we cannot
- assume that a nonzero value means that the page is encrypted.
- Therefore we must validate the page both as encrypted and unencrypted
- when FIL_PAGE_FILE_FLUSH_LSN does not contain 0.
- */
-
- uint32_t checksum1 = mach_read_from_4(page + FIL_PAGE_SPACE_OR_CHKSUM);
- uint32_t checksum2;
-
- bool valid = false;
-
- if (zip_size) {
- valid = (checksum1 == cchecksum1);
- checksum2 = checksum1;
- } else {
- checksum2 = mach_read_from_4(
- page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM);
- switch (algorithm) {
- case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
- valid = buf_page_is_checksum_valid_crc32(page, checksum1,
- checksum2);
- break;
- case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
- valid = buf_page_is_checksum_valid_innodb(page, checksum1,
- checksum2);
- break;
- case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
- valid = buf_page_is_checksum_valid_none(page, checksum1,
- checksum2);
- break;
- case SRV_CHECKSUM_ALGORITHM_CRC32:
- case SRV_CHECKSUM_ALGORITHM_INNODB:
- valid = buf_page_is_checksum_valid_crc32(
- page, checksum1, checksum2)
- || buf_page_is_checksum_valid_innodb(
- page, checksum1, checksum2);
- break;
- case SRV_CHECKSUM_ALGORITHM_NONE:
- ut_error;
+ return checksum == buf_calc_page_crc32(page);
+ case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
+ if (zip_size) {
+ return checksum == page_zip_calc_checksum(
+ page, zip_size, SRV_CHECKSUM_ALGORITHM_INNODB);
}
- }
+ return checksum == buf_calc_page_new_checksum(page);
+ case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
+ return checksum == BUF_NO_CHECKSUM_MAGIC;
+ case SRV_CHECKSUM_ALGORITHM_NONE:
+ return true;
+ case SRV_CHECKSUM_ALGORITHM_INNODB:
+ case SRV_CHECKSUM_ALGORITHM_CRC32:
+ if (checksum == BUF_NO_CHECKSUM_MAGIC) {
+ return true;
+ }
+ if (zip_size) {
+ if (checksum == page_zip_calc_checksum(
+ page, zip_size, algorithm)) {
+ return true;
+ }
- if (encrypted && valid) {
- /* If page is encrypted and traditional checksums match,
- page could be still encrypted, or not encrypted and valid or
- corrupted. */
-#ifndef UNIV_INNOCHECKSUM
- ib_logf(IB_LOG_LEVEL_ERROR,
- " Page " ULINTPF " in space %s (" ULINTPF ") maybe corrupted."
- " Post encryption checksum %u stored [%u:%u] key_version %u",
- pageno,
- space ? space->name : "N/A",
- mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID),
- checksum, checksum1, checksum2, key_version);
-#else
- if (log_file) {
- fprintf(log_file,
- "Page " ULINTPF ":" ULINTPF " may be corrupted."
- " Post encryption checksum %u"
- " stored [%u:%u] key_version %u\n",
- pageno,
- mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID),
- checksum, checksum1, checksum2,
- key_version);
+ algorithm = algorithm == SRV_CHECKSUM_ALGORITHM_INNODB
+ ? SRV_CHECKSUM_ALGORITHM_CRC32
+ : SRV_CHECKSUM_ALGORITHM_INNODB;
+ return checksum == page_zip_calc_checksum(
+ page, zip_size, algorithm);
}
-#endif /* UNIV_INNOCHECKSUM */
- encrypted = false;
+ return checksum == buf_calc_page_crc32(page)
+ || checksum == buf_calc_page_new_checksum(page);
}
-
- return(encrypted);
}