mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
committed by
Marko Mäkelä
parent
dc8a20f3d0
commit
7772c7cd94
@ -0,0 +1,5 @@
|
|||||||
|
[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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
&& !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(
|
|||||||
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()
|
|||||||
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="
|
||||||
|
Reference in New Issue
Block a user