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