Commit 7772c7cd authored by Thirunarayanan Balathandayuthapani's avatar Thirunarayanan Balathandayuthapani Committed by Marko Mäkelä

MDEV-20340 Encrypted temporary tables cannot be read with full_crc32

Problem:
========
Checksum for the encrypted temporary tablespace is not stored in the page
for full crc32 format.

Solution:
========
Made temporary tablespace in full crc32 format irrespective of encryption
parameter.

buf_tmp_page_encrypt(), buf_tmp_page_decrypt() - Both follows full_crc32
format.
parent dc8a20f3
[strict_crc32]
--innodb-checksum-algorithm=strict_crc32
[strict_full_crc32]
--innodb-checksum-algorithm=strict_full_crc32
...@@ -484,7 +484,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) ...@@ -484,7 +484,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame)
} }
/* read space & lsn */ /* read space & lsn */
uint header_len = FIL_PAGE_DATA; uint header_len = FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
/* Copy FIL page header, it is not encrypted */ /* Copy FIL page header, it is not encrypted */
memcpy(tmp_frame, src_frame, header_len); memcpy(tmp_frame, src_frame, header_len);
...@@ -493,7 +493,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) ...@@ -493,7 +493,7 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame)
const byte* src = src_frame + header_len; const byte* src = src_frame + header_len;
byte* dst = tmp_frame + header_len; byte* dst = tmp_frame + header_len;
uint srclen = uint(srv_page_size) uint srclen = uint(srv_page_size)
- header_len - FIL_PAGE_DATA_END; - (header_len + FIL_PAGE_FCRC32_CHECKSUM);
ulint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET); ulint offset = mach_read_from_4(src_frame + FIL_PAGE_OFFSET);
if (!log_tmp_block_decrypt(src, srclen, dst, if (!log_tmp_block_decrypt(src, srclen, dst,
...@@ -501,9 +501,9 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame) ...@@ -501,9 +501,9 @@ static bool buf_tmp_page_decrypt(byte* tmp_frame, byte* src_frame)
return false; return false;
} }
memcpy(tmp_frame + srv_page_size - FIL_PAGE_DATA_END, memcpy(tmp_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
src_frame + srv_page_size - FIL_PAGE_DATA_END, src_frame + srv_page_size - FIL_PAGE_FCRC32_CHECKSUM,
FIL_PAGE_DATA_END); FIL_PAGE_FCRC32_CHECKSUM);
memcpy(src_frame, tmp_frame, srv_page_size); memcpy(src_frame, tmp_frame, srv_page_size);
srv_stats.pages_decrypted.inc(); srv_stats.pages_decrypted.inc();
...@@ -5976,13 +5976,15 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) ...@@ -5976,13 +5976,15 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
&& !bpage->encrypted && !bpage->encrypted
&& fil_space_verify_crypt_checksum(dst_frame, && fil_space_verify_crypt_checksum(dst_frame,
bpage->zip_size()); bpage->zip_size());
ut_ad(space->purpose != FIL_TYPE_TEMPORARY || space->full_crc32());
if (!still_encrypted) { if (!still_encrypted) {
/* If traditional checksums match, we assume that page is /* If traditional checksums match, we assume that page is
not anymore encrypted. */ not anymore encrypted. */
if (space->full_crc32() if (space->full_crc32()
&& !buf_page_is_zeroes(dst_frame, space->physical_size()) && !buf_page_is_zeroes(dst_frame, space->physical_size())
&& (key_version || space->is_compressed())) { && (key_version || space->is_compressed()
|| space->purpose == FIL_TYPE_TEMPORARY)) {
corrupted = buf_page_full_crc32_is_corrupted( corrupted = buf_page_full_crc32_is_corrupted(
space->id, dst_frame, space->id, dst_frame,
space->is_compressed()); space->is_compressed());
...@@ -7427,28 +7429,21 @@ static byte* buf_tmp_page_encrypt( ...@@ -7427,28 +7429,21 @@ static byte* buf_tmp_page_encrypt(
byte* src_frame, byte* src_frame,
byte* dst_frame) byte* dst_frame)
{ {
uint header_len = FIL_PAGE_DATA;
/* FIL page header is not encrypted */
memcpy(dst_frame, src_frame, header_len);
/* Calculate the start offset in a page */ /* Calculate the start offset in a page */
uint unencrypted_bytes = header_len + FIL_PAGE_DATA_END; uint srclen = srv_page_size - (FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
uint srclen = srv_page_size - unencrypted_bytes; + FIL_PAGE_FCRC32_CHECKSUM);
const byte* src = src_frame + header_len; const byte* src = src_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
byte* dst = dst_frame + header_len; byte* dst = dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION;
memcpy(dst_frame, src_frame, FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
if (!log_tmp_block_encrypt(src, srclen, dst, (offset * srv_page_size), if (!log_tmp_block_encrypt(src, srclen, dst, (offset * srv_page_size),
true)) { true)) {
return NULL; return NULL;
} }
memcpy(dst_frame + srv_page_size - FIL_PAGE_DATA_END, const ulint payload = srv_page_size - FIL_PAGE_FCRC32_CHECKSUM;
src_frame + srv_page_size - FIL_PAGE_DATA_END, mach_write_to_4(dst_frame + payload, ut_crc32(dst_frame, payload));
FIL_PAGE_DATA_END);
/* Handle post encryption checksum */
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4,
buf_calc_page_crc32(dst_frame));
srv_stats.pages_encrypted.inc(); srv_stats.pages_encrypted.inc();
srv_stats.n_temp_blocks_encrypted.inc(); srv_stats.n_temp_blocks_encrypted.inc();
......
...@@ -3876,15 +3876,9 @@ static int innodb_init_params() ...@@ -3876,15 +3876,9 @@ static int innodb_init_params()
srv_tmp_space.set_name("innodb_temporary"); srv_tmp_space.set_name("innodb_temporary");
srv_tmp_space.set_path(srv_data_home); srv_tmp_space.set_path(srv_data_home);
switch (srv_checksum_algorithm) { /* Temporary tablespace is in full crc32 format. */
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32: srv_tmp_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32: | FSP_FLAGS_FCRC32_PAGE_SSIZE());
srv_tmp_space.set_flags(FSP_FLAGS_FCRC32_MASK_MARKER
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
break;
default:
srv_tmp_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
}
if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) { if (!srv_tmp_space.parse_params(innobase_temp_data_file_path, false)) {
ib::error() << "Unable to parse innodb_temp_data_file_path=" ib::error() << "Unable to parse innodb_temp_data_file_path="
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment