mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 23:04:20 +01:00
ddf2fac733
compatibility problems Pages that are encrypted contain post encryption checksum on different location that normal checksum fields. Therefore, we should before decryption check this checksum to avoid unencrypting corrupted pages. After decryption we can use traditional checksum check to detect if page is corrupted or unencryption was done using incorrect key. Pages that are page compressed do not contain any checksum, here we need to fist unencrypt, decompress and finally use tradional checksum check to detect page corruption or that we used incorrect key in unencryption. buf0buf.cc: buf_page_is_corrupted() mofified so that compressed pages are skipped. buf0buf.h, buf_block_init(), buf_page_init_low(): removed unnecessary page_encrypted, page_compressed, stored_checksum, valculated_checksum fields from buf_page_t buf_page_get_gen(): use new buf_page_check_corrupt() function to detect corrupted pages. buf_page_check_corrupt(): If page was not yet decrypted check if post encryption checksum still matches. If page is not anymore encrypted, use buf_page_is_corrupted() traditional checksum method. If page is detected as corrupted and it is not encrypted we print corruption message to error log. If page is still encrypted or it was encrypted and now corrupted, we will print message that page is encrypted to error log. buf_page_io_complete(): use new buf_page_check_corrupt() function to detect corrupted pages. buf_page_decrypt_after_read(): Verify post encryption checksum before tring to decrypt. fil0crypt.cc: fil_encrypt_buf() verify post encryption checksum and ind fil_space_decrypt() return true if we really decrypted the page. fil_space_verify_crypt_checksum(): rewrite to use the method used when calculating post encryption checksum. We also check if post encryption checksum matches that traditional checksum check does not match. fil0fil.ic: Add missed page type encrypted and page compressed to fil_get_page_type_name() Note that this change does not yet fix innochecksum tool, that will be done in separate MDEV. Fix test failures caused by buf page corruption injection.
185 lines
5.8 KiB
Text
185 lines
5.8 KiB
Text
/*****************************************************************************
|
|
|
|
Copyright (c) 2015, MariaDB Corporation.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file include/fil0fil.ic
|
|
The low-level file system support functions
|
|
|
|
Created 31/03/2015 Jan Lindström
|
|
*******************************************************/
|
|
|
|
#ifndef fil0fil_ic
|
|
#define fil0fil_ic
|
|
|
|
/*******************************************************************//**
|
|
Return space name */
|
|
UNIV_INLINE
|
|
char*
|
|
fil_space_name(
|
|
/*===========*/
|
|
fil_space_t* space) /*!< in: space */
|
|
{
|
|
return (space->name);
|
|
}
|
|
|
|
/*******************************************************************//**
|
|
Return space flags */
|
|
UNIV_INLINE
|
|
ulint
|
|
fil_space_flags(
|
|
/*===========*/
|
|
fil_space_t* space) /*!< in: space */
|
|
{
|
|
return (space->flags);
|
|
}
|
|
|
|
/*******************************************************************//**
|
|
Return page type name */
|
|
UNIV_INLINE
|
|
const char*
|
|
fil_get_page_type_name(
|
|
/*===================*/
|
|
ulint page_type) /*!< in: FIL_PAGE_TYPE */
|
|
{
|
|
switch(page_type) {
|
|
case FIL_PAGE_PAGE_COMPRESSED:
|
|
return (const char*)"PAGE_COMPRESSED";
|
|
case FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED:
|
|
return (const char*)"PAGE_COMPRESSED_ENCRYPTED";
|
|
case FIL_PAGE_INDEX:
|
|
return (const char*)"INDEX";
|
|
case FIL_PAGE_UNDO_LOG:
|
|
return (const char*)"UNDO LOG";
|
|
case FIL_PAGE_INODE:
|
|
return (const char*)"INODE";
|
|
case FIL_PAGE_IBUF_FREE_LIST:
|
|
return (const char*)"IBUF_FREE_LIST";
|
|
case FIL_PAGE_TYPE_ALLOCATED:
|
|
return (const char*)"ALLOCATED";
|
|
case FIL_PAGE_IBUF_BITMAP:
|
|
return (const char*)"IBUF_BITMAP";
|
|
case FIL_PAGE_TYPE_SYS:
|
|
return (const char*)"SYS";
|
|
case FIL_PAGE_TYPE_TRX_SYS:
|
|
return (const char*)"TRX_SYS";
|
|
case FIL_PAGE_TYPE_FSP_HDR:
|
|
return (const char*)"FSP_HDR";
|
|
case FIL_PAGE_TYPE_XDES:
|
|
return (const char*)"XDES";
|
|
case FIL_PAGE_TYPE_BLOB:
|
|
return (const char*)"BLOB";
|
|
case FIL_PAGE_TYPE_ZBLOB:
|
|
return (const char*)"ZBLOB";
|
|
case FIL_PAGE_TYPE_ZBLOB2:
|
|
return (const char*)"ZBLOB2";
|
|
case FIL_PAGE_TYPE_COMPRESSED:
|
|
return (const char*)"ORACLE PAGE COMPRESSED";
|
|
|
|
/* No default to make compiler generate warning if
|
|
new page type is added but not handled here. */
|
|
}
|
|
|
|
return (const char*)"PAGE TYPE CORRUPTED";
|
|
|
|
}
|
|
|
|
/****************************************************************//**
|
|
Get block size from fil node
|
|
@return block size*/
|
|
UNIV_INLINE
|
|
ulint
|
|
fil_node_get_block_size(
|
|
/*====================*/
|
|
fil_node_t* node) /*!< in: Node where to get block
|
|
size */
|
|
{
|
|
return (node->file_block_size);
|
|
}
|
|
|
|
/****************************************************************//**
|
|
Validate page type.
|
|
@return true if valid, false if not */
|
|
UNIV_INLINE
|
|
bool
|
|
fil_page_type_validate(
|
|
const byte* page) /*!< in: page */
|
|
{
|
|
#ifdef UNIV_DEBUG
|
|
ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
|
|
|
|
/* Validate page type */
|
|
if (!((page_type == FIL_PAGE_PAGE_COMPRESSED ||
|
|
page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED ||
|
|
page_type == FIL_PAGE_INDEX ||
|
|
page_type == FIL_PAGE_UNDO_LOG ||
|
|
page_type == FIL_PAGE_INODE ||
|
|
page_type == FIL_PAGE_IBUF_FREE_LIST ||
|
|
page_type == FIL_PAGE_TYPE_ALLOCATED ||
|
|
page_type == FIL_PAGE_IBUF_BITMAP ||
|
|
page_type == FIL_PAGE_TYPE_SYS ||
|
|
page_type == FIL_PAGE_TYPE_TRX_SYS ||
|
|
page_type == FIL_PAGE_TYPE_FSP_HDR ||
|
|
page_type == FIL_PAGE_TYPE_XDES ||
|
|
page_type == FIL_PAGE_TYPE_BLOB ||
|
|
page_type == FIL_PAGE_TYPE_ZBLOB ||
|
|
page_type == FIL_PAGE_TYPE_ZBLOB2 ||
|
|
page_type == FIL_PAGE_TYPE_COMPRESSED))) {
|
|
|
|
uint key_version = mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
|
|
bool page_compressed = (page_type == FIL_PAGE_PAGE_COMPRESSED);
|
|
bool page_compressed_encrypted = (page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
|
|
ulint space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
|
ulint offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
|
|
ib_uint64_t lsn = mach_read_from_8(page + FIL_PAGE_LSN);
|
|
ulint compressed_len = mach_read_from_2(page + FIL_PAGE_DATA);
|
|
fil_system_enter();
|
|
fil_space_t* rspace = fil_space_get_by_id(space);
|
|
fil_system_exit();
|
|
|
|
|
|
/* Dump out the page info */
|
|
fprintf(stderr, "InnoDB: Space %lu offset %lu name %s page_type %lu page_type_name %s\n"
|
|
"InnoDB: key_version %u page_compressed %d page_compressed_encrypted %d lsn %llu compressed_len %lu\n",
|
|
space, offset, rspace->name, page_type, fil_get_page_type_name(page_type),
|
|
key_version, page_compressed, page_compressed_encrypted, (ulonglong)lsn, compressed_len);
|
|
fflush(stderr);
|
|
|
|
ut_ad(page_type == FIL_PAGE_PAGE_COMPRESSED ||
|
|
page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED ||
|
|
page_type == FIL_PAGE_INDEX ||
|
|
page_type == FIL_PAGE_UNDO_LOG ||
|
|
page_type == FIL_PAGE_INODE ||
|
|
page_type == FIL_PAGE_IBUF_FREE_LIST ||
|
|
page_type == FIL_PAGE_TYPE_ALLOCATED ||
|
|
page_type == FIL_PAGE_IBUF_BITMAP ||
|
|
page_type == FIL_PAGE_TYPE_SYS ||
|
|
page_type == FIL_PAGE_TYPE_TRX_SYS ||
|
|
page_type == FIL_PAGE_TYPE_FSP_HDR ||
|
|
page_type == FIL_PAGE_TYPE_XDES ||
|
|
page_type == FIL_PAGE_TYPE_BLOB ||
|
|
page_type == FIL_PAGE_TYPE_ZBLOB ||
|
|
page_type == FIL_PAGE_TYPE_ZBLOB2 ||
|
|
page_type == FIL_PAGE_TYPE_COMPRESSED);
|
|
return false;
|
|
}
|
|
|
|
#endif /* UNIV_DEBUG */
|
|
return true;
|
|
}
|
|
|
|
#endif /* fil0fil_ic */
|