Commit 70b82efd authored by Jan Lindström's avatar Jan Lindström

MDEV-8273: InnoDB: Assertion failure in file fil0pagecompress.cc line 532

Analysis: Problem was that actual payload size (page size) after compression
was handled incorrectly on encryption. Additionally, some of the variables
were not initialized.

Fixed by encrypting/decrypting only the actual compressed page size.
parent 4a6a61cb
......@@ -1421,23 +1421,30 @@ buf_pool_free_instance(
hash_table_free(buf_pool->zip_hash);
/* Free all used temporary slots */
for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) {
buf_tmp_buffer_t* slot = &buf_pool->tmp_arr->slots[i];
if (buf_pool->tmp_arr) {
for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) {
buf_tmp_buffer_t* slot = &(buf_pool->tmp_arr->slots[i]);
#ifdef HAVE_LZO
if (slot->lzo_mem) {
ut_free(slot->lzo_mem);
}
if (slot && slot->lzo_mem) {
ut_free(slot->lzo_mem);
slot->lzo_mem = NULL;
}
#endif
if (slot->crypt_buf_free) {
ut_free(slot->crypt_buf_free);
}
if (slot->comp_buf_free) {
ut_free(slot->comp_buf_free);
if (slot && slot->crypt_buf_free) {
ut_free(slot->crypt_buf_free);
slot->crypt_buf_free = NULL;
}
if (slot && slot->comp_buf_free) {
ut_free(slot->comp_buf_free);
slot->comp_buf_free = NULL;
}
}
}
mem_free(buf_pool->tmp_arr->slots);
mem_free(buf_pool->tmp_arr);
buf_pool->tmp_arr = NULL;
}
/********************************************************************//**
......
......@@ -588,20 +588,29 @@ fil_space_encrypt(
}
ibool page_compressed = (orig_page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
ulint header_len = FIL_PAGE_DATA;
if (page_compressed) {
header_len += (FIL_PAGE_COMPRESSED_SIZE + FIL_PAGE_COMPRESSION_METHOD_SIZE);
}
/* FIL page header is not encrypted */
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
memcpy(dst_frame, src_frame, header_len);
/* Store key version */
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, key_version);
/* Calculate the start offset in a page */
ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END;
ulint unencrypted_bytes = header_len + FIL_PAGE_DATA_END;
ulint srclen = page_size - unencrypted_bytes;
const byte* src = src_frame + FIL_PAGE_DATA;
byte* dst = dst_frame + FIL_PAGE_DATA;
const byte* src = src_frame + header_len;
byte* dst = dst_frame + header_len;
uint32 dstlen = 0;
if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);
}
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
space, offset, lsn);
......@@ -717,15 +726,24 @@ fil_space_decrypt(
ulint offset = mach_read_from_4(
src_frame + FIL_PAGE_OFFSET);
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
ulint header_len = FIL_PAGE_DATA;
if (page_compressed) {
header_len += (FIL_PAGE_COMPRESSED_SIZE + FIL_PAGE_COMPRESSION_METHOD_SIZE);
}
/* Copy FIL page header, it is not encrypted */
memcpy(tmp_frame, src_frame, FIL_PAGE_DATA);
memcpy(tmp_frame, src_frame, header_len);
/* Calculate the offset where decryption starts */
const byte* src = src_frame + FIL_PAGE_DATA;
byte* dst = tmp_frame + FIL_PAGE_DATA;
const byte* src = src_frame + header_len;
byte* dst = tmp_frame + header_len;
uint32 dstlen = 0;
ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END);
ulint srclen = page_size - (header_len + FIL_PAGE_DATA_END);
if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);
}
int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
......
......@@ -1496,8 +1496,31 @@ buf_pool_free_instance(
hash_table_free(buf_pool->page_hash);
hash_table_free(buf_pool->zip_hash);
/* Free all used temporary slots */
if (buf_pool->tmp_arr) {
for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) {
buf_tmp_buffer_t* slot = &(buf_pool->tmp_arr->slots[i]);
#ifdef HAVE_LZO
if (slot && slot->lzo_mem) {
ut_free(slot->lzo_mem);
slot->lzo_mem = NULL;
}
#endif
if (slot && slot->crypt_buf_free) {
ut_free(slot->crypt_buf_free);
slot->crypt_buf_free = NULL;
}
if (slot && slot->comp_buf_free) {
ut_free(slot->comp_buf_free);
slot->comp_buf_free = NULL;
}
}
}
mem_free(buf_pool->tmp_arr->slots);
mem_free(buf_pool->tmp_arr);
buf_pool->tmp_arr = NULL;
}
/********************************************************************//**
......
......@@ -588,20 +588,29 @@ fil_space_encrypt(
}
ibool page_compressed = (orig_page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
ulint header_len = FIL_PAGE_DATA;
if (page_compressed) {
header_len += (FIL_PAGE_COMPRESSED_SIZE + FIL_PAGE_COMPRESSION_METHOD_SIZE);
}
/* FIL page header is not encrypted */
memcpy(dst_frame, src_frame, FIL_PAGE_DATA);
memcpy(dst_frame, src_frame, header_len);
/* Store key version */
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, key_version);
/* Calculate the start offset in a page */
ulint unencrypted_bytes = FIL_PAGE_DATA + FIL_PAGE_DATA_END;
ulint unencrypted_bytes = header_len + FIL_PAGE_DATA_END;
ulint srclen = page_size - unencrypted_bytes;
const byte* src = src_frame + FIL_PAGE_DATA;
byte* dst = dst_frame + FIL_PAGE_DATA;
const byte* src = src_frame + header_len;
byte* dst = dst_frame + header_len;
uint32 dstlen = 0;
if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);
}
int rc = encryption_scheme_encrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
space, offset, lsn);
......@@ -717,15 +726,24 @@ fil_space_decrypt(
ulint offset = mach_read_from_4(
src_frame + FIL_PAGE_OFFSET);
ib_uint64_t lsn = mach_read_from_8(src_frame + FIL_PAGE_LSN);
ulint header_len = FIL_PAGE_DATA;
if (page_compressed) {
header_len += (FIL_PAGE_COMPRESSED_SIZE + FIL_PAGE_COMPRESSION_METHOD_SIZE);
}
/* Copy FIL page header, it is not encrypted */
memcpy(tmp_frame, src_frame, FIL_PAGE_DATA);
memcpy(tmp_frame, src_frame, header_len);
/* Calculate the offset where decryption starts */
const byte* src = src_frame + FIL_PAGE_DATA;
byte* dst = tmp_frame + FIL_PAGE_DATA;
const byte* src = src_frame + header_len;
byte* dst = tmp_frame + header_len;
uint32 dstlen = 0;
ulint srclen = page_size - (FIL_PAGE_DATA + FIL_PAGE_DATA_END);
ulint srclen = page_size - (header_len + FIL_PAGE_DATA_END);
if (page_compressed) {
srclen = mach_read_from_2(src_frame + FIL_PAGE_DATA);
}
int rc = encryption_scheme_decrypt(src, srclen, dst, &dstlen,
crypt_data, key_version,
......
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