mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-26258 Various crashes/asserts/corruptions when Aria encryption is enabled/used, but the encryption plugin is not loaded
The reason for the MDEV reported failures is that the tests are enabling encryption for Aria but not providing any encryption keys. Fixed by checking if encryption keys exists before creating the table. Other things: - maria.encrypt_wrong-key changed as we now get the error on CREATE instead during insert.
This commit is contained in:
parent
c6ef9b1c1a
commit
1ef22e28ad
14 changed files with 135 additions and 44 deletions
|
@ -79,3 +79,4 @@
|
|||
{ "HA_ERR_ABORTED_BY_USER", HA_ERR_ABORTED_BY_USER, "" },
|
||||
{ "HA_ERR_DISK_FULL", HA_ERR_DISK_FULL, "" },
|
||||
{ "HA_ERR_INCOMPATIBLE_DEFINITION", HA_ERR_INCOMPATIBLE_DEFINITION, "" },
|
||||
{ "HA_ERR_NO_ENCRYPTION", HA_ERR_NO_ENCRYPTION, "" },
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define HA_OPEN_NO_PSI_CALL 1024U /* Don't call/connect PSI */
|
||||
#define HA_OPEN_MERGE_TABLE 2048U
|
||||
#define HA_OPEN_FOR_CREATE 4096U
|
||||
#define HA_OPEN_FOR_DROP (1U << 13) /* Open part of drop */
|
||||
|
||||
/*
|
||||
Allow opening even if table is incompatible as this is for ALTER TABLE which
|
||||
|
@ -516,14 +517,15 @@ enum ha_base_keytype {
|
|||
#define HA_ERR_DISK_FULL 189
|
||||
#define HA_ERR_INCOMPATIBLE_DEFINITION 190
|
||||
#define HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE 191 /* Too many words in a phrase */
|
||||
#define HA_ERR_DECRYPTION_FAILED 192 /* Table encrypted but decypt failed */
|
||||
#define HA_ERR_DECRYPTION_FAILED 192 /* Table encrypted but decrypt failed */
|
||||
#define HA_ERR_FK_DEPTH_EXCEEDED 193 /* FK cascade depth exceeded */
|
||||
#define HA_ERR_TABLESPACE_MISSING 194 /* Missing Tablespace */
|
||||
#define HA_ERR_SEQUENCE_INVALID_DATA 195
|
||||
#define HA_ERR_SEQUENCE_RUN_OUT 196
|
||||
#define HA_ERR_COMMIT_ERROR 197
|
||||
#define HA_ERR_PARTITION_LIST 198
|
||||
#define HA_ERR_LAST 198 /* Copy of last error nr * */
|
||||
#define HA_ERR_NO_ENCRYPTION 199
|
||||
#define HA_ERR_LAST 199 /* Copy of last error nr * */
|
||||
|
||||
/* Number of different errors */
|
||||
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||
|
|
|
@ -109,7 +109,8 @@ static const char *handler_error_messages[]=
|
|||
"Sequence has been run out",
|
||||
"Sequence values are conflicting",
|
||||
"Error during commit",
|
||||
"Cannot select partitions"
|
||||
"Cannot select partitions",
|
||||
"Cannot initialize encryption. Check that all encryption parameters have been set"
|
||||
};
|
||||
|
||||
#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */
|
||||
|
|
|
@ -11,7 +11,7 @@ let $counter= 5000;
|
|||
let $mysql_errno= 9999;
|
||||
while ($mysql_errno)
|
||||
{
|
||||
--error 0,ER_ACCESS_DENIED_ERROR,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013
|
||||
--error 0,ER_ACCESS_DENIED_ERROR,ER_SERVER_SHUTDOWN,ER_CONNECTION_KILLED,ER_LOCK_WAIT_TIMEOUT,2002,2006,2013,HA_ERR_NO_ENCRYPTION
|
||||
show status;
|
||||
|
||||
dec $counter;
|
||||
|
@ -30,6 +30,10 @@ while ($mysql_errno)
|
|||
{
|
||||
let $mysql_errno=0;
|
||||
}
|
||||
if ($mysql_errno == 199)
|
||||
{
|
||||
let $mysql_errno=0;
|
||||
}
|
||||
--sleep 0.1
|
||||
}
|
||||
--enable_query_log
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
call mtr.add_suppression('Unknown key id 1. Can''t continue');
|
||||
call mtr.add_suppression("Initialization of encryption failed.*");
|
||||
set global aria_encrypt_tables= 1;
|
||||
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
|
||||
alter table t1 disable keys;
|
||||
insert into t1 values (1,1);
|
||||
alter table t1 enable keys;
|
||||
ERROR HY000: Unknown key id 1. Can't continue!
|
||||
repair table t1 use_frm;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair warning Number of rows changed from 0 to 1
|
||||
test.t1 repair Error Unknown key id 1. Can't continue!
|
||||
test.t1 repair Error Unknown key id 1. Can't continue!
|
||||
test.t1 repair status OK
|
||||
drop table t1;
|
||||
ERROR HY000: Initialization of encryption failed for ./test/t1
|
||||
set global aria_encrypt_tables= default;
|
||||
#
|
||||
# MDEV-26258 Various crashes/asserts/corruptions when Aria encryption is
|
||||
# enabled/used, but the encryption plugin is not loaded
|
||||
#
|
||||
SET GLOBAL aria_encrypt_tables=ON;
|
||||
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
|
||||
ERROR HY000: Initialization of encryption failed for ./test/t1
|
||||
# Restart with encryption enabled
|
||||
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
|
||||
INSERT INTO t1 VALUES (4,0);
|
||||
LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 preload_keys status OK
|
||||
LOAD INDEX INTO CACHE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 preload_keys status OK
|
||||
SELECT * FROM t1;
|
||||
ERROR HY000: Initialization of encryption failed for ./test/t1.MAD
|
||||
DROP TABLE t1;
|
||||
Warnings:
|
||||
Warning 199 Initialization of encryption failed for ./test/t1.MAD
|
||||
Cleanup
|
||||
|
|
|
@ -1,14 +1,55 @@
|
|||
#
|
||||
# MDEV-18496 Crash when Aria encryption is enabled but plugin not available
|
||||
#
|
||||
call mtr.add_suppression('Unknown key id 1. Can''t continue');
|
||||
call mtr.add_suppression("Initialization of encryption failed.*");
|
||||
|
||||
set global aria_encrypt_tables= 1;
|
||||
--error HA_ERR_NO_ENCRYPTION
|
||||
create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
|
||||
alter table t1 disable keys;
|
||||
insert into t1 values (1,1);
|
||||
error 192;
|
||||
alter table t1 enable keys;
|
||||
repair table t1 use_frm;
|
||||
drop table t1;
|
||||
set global aria_encrypt_tables= default;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-26258 Various crashes/asserts/corruptions when Aria encryption is
|
||||
--echo # enabled/used, but the encryption plugin is not loaded
|
||||
--echo #
|
||||
|
||||
SET GLOBAL aria_encrypt_tables=ON;
|
||||
|
||||
--write_file $MYSQLTEST_VARDIR/keys1.txt
|
||||
1;770A8A65DA156D24EE2A093277530142
|
||||
EOF
|
||||
|
||||
--replace_result \\ /
|
||||
--error HA_ERR_NO_ENCRYPTION
|
||||
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
|
||||
|
||||
--echo # Restart with encryption enabled
|
||||
|
||||
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
--shutdown_server
|
||||
--source include/wait_until_disconnected.inc
|
||||
--exec echo "restart:--aria-encrypt-tables=1 --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
CREATE TABLE t1 (a INT KEY,b INT,KEY(b)) ENGINE=Aria;
|
||||
INSERT INTO t1 VALUES (4,0);
|
||||
LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
|
||||
LOAD INDEX INTO CACHE t1;
|
||||
|
||||
# Restart without encryption. Above table should be unreadable
|
||||
|
||||
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
--shutdown_server
|
||||
--source include/wait_until_disconnected.inc
|
||||
--exec echo "restart:--aria-encrypt-tables=0" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
--replace_result \\ /
|
||||
--error HA_ERR_NO_ENCRYPTION
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo Cleanup
|
||||
--remove_file $MYSQLTEST_VARDIR/keys1.txt
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
call mtr.add_suppression("file_key_management");
|
||||
call mtr.add_suppression("System key id 1 is missing");
|
||||
call mtr.add_suppression("Unknown key id 1");
|
||||
call mtr.add_suppression("Failed to decrypt");
|
||||
call mtr.add_suppression("Initialization of encryption failed.*");
|
||||
CREATE TABLE t1 (i INT, KEY(i)) ENGINE=Aria;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
repair table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 repair info Wrong CRC on datapage at 1
|
||||
test.t1 repair warning Number of rows changed from 1 to 0
|
||||
test.t1 repair status OK
|
||||
test.t1 repair Error Initialization of encryption failed for ./test/t1.MAD
|
||||
test.t1 repair error Corrupt
|
||||
INSERT INTO t1 VALUES (2);
|
||||
ERROR HY000: Initialization of encryption failed for ./test/t1.MAD
|
||||
select * from t1;
|
||||
ERROR HY000: failed to decrypt './test/t1' rc: -1 dstlen: 0 size: 8172
|
||||
|
||||
i
|
||||
1
|
||||
drop table t1;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
call mtr.add_suppression("file_key_management");
|
||||
call mtr.add_suppression("System key id 1 is missing");
|
||||
call mtr.add_suppression("Unknown key id 1");
|
||||
call mtr.add_suppression("Failed to decrypt");
|
||||
call mtr.add_suppression("Initialization of encryption failed.*");
|
||||
|
||||
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
--shutdown_server
|
||||
|
@ -36,8 +36,11 @@ EOF
|
|||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
--replace_result \\ /
|
||||
repair table t1;
|
||||
|
||||
--replace_result \\ /
|
||||
--error HA_ERR_NO_ENCRYPTION
|
||||
INSERT INTO t1 VALUES (2);
|
||||
|
||||
--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||
|
@ -48,8 +51,6 @@ INSERT INTO t1 VALUES (2);
|
|||
--enable_reconnect
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
--replace_result \\ /
|
||||
--error 192
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
--remove_file $MYSQLTEST_VARDIR/keys1.txt
|
||||
|
|
|
@ -292,7 +292,8 @@ static MYSQL_SYSVAR_BOOL(used_for_temp_tables,
|
|||
"Whether temporary tables should be MyISAM or Aria", 0, 0,
|
||||
1);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables, PLUGIN_VAR_OPCMDARG,
|
||||
static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
"Encrypt tables (only for tables with ROW_FORMAT=PAGE (default) "
|
||||
"and not FIXED/DYNAMIC)",
|
||||
0, 0, 0);
|
||||
|
|
|
@ -1062,6 +1062,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
|
|||
|
||||
if (encrypted)
|
||||
{
|
||||
DBUG_ASSERT(share.data_file_name.length == 0);
|
||||
share.data_file_name.str= (char*) name; /* For error reporting */
|
||||
if (ma_crypt_create(&share) ||
|
||||
ma_crypt_write(&share, file))
|
||||
goto err;
|
||||
|
|
|
@ -100,6 +100,7 @@ static void crypt_data_scheme_locker(struct st_encryption_scheme *scheme,
|
|||
int
|
||||
ma_crypt_create(MARIA_SHARE* share)
|
||||
{
|
||||
uint key_version;
|
||||
MARIA_CRYPT_DATA *crypt_data=
|
||||
(MARIA_CRYPT_DATA*)my_malloc(sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL));
|
||||
crypt_data->scheme.type= CRYPT_SCHEME_1;
|
||||
|
@ -110,6 +111,16 @@ ma_crypt_create(MARIA_SHARE* share)
|
|||
my_random_bytes((uchar*)&crypt_data->space, sizeof(crypt_data->space));
|
||||
share->crypt_data= crypt_data;
|
||||
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
|
||||
|
||||
key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id);
|
||||
if (unlikely(key_version == ENCRYPTION_KEY_VERSION_INVALID))
|
||||
{
|
||||
my_errno= HA_ERR_NO_ENCRYPTION;
|
||||
my_printf_error(HA_ERR_NO_ENCRYPTION,
|
||||
"Initialization of encryption failed for %s", MYF(0),
|
||||
share->data_file_name.str);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -145,7 +156,7 @@ ma_crypt_write(MARIA_SHARE* share, File file)
|
|||
}
|
||||
|
||||
uchar*
|
||||
ma_crypt_read(MARIA_SHARE* share, uchar *buff)
|
||||
ma_crypt_read(MARIA_SHARE* share, uchar *buff, my_bool silent)
|
||||
{
|
||||
uchar type= buff[0];
|
||||
uchar iv_length= buff[1];
|
||||
|
@ -155,9 +166,9 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
|
|||
iv_length != sizeof(((MARIA_CRYPT_DATA*)1)->scheme.iv) + 4)
|
||||
{
|
||||
my_printf_error(HA_ERR_UNSUPPORTED,
|
||||
"Unsupported crypt scheme! type: %d iv_length: %d\n",
|
||||
MYF(ME_FATAL|ME_ERROR_LOG),
|
||||
type, iv_length);
|
||||
"Unsupported crypt scheme type: %d iv_length: %d\n",
|
||||
MYF(ME_ERROR_LOG | (silent ? ME_WARNING : ME_FATAL)),
|
||||
type, iv_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -166,6 +177,7 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
|
|||
/* opening a table */
|
||||
MARIA_CRYPT_DATA *crypt_data=
|
||||
(MARIA_CRYPT_DATA*)my_malloc(sizeof(MARIA_CRYPT_DATA), MYF(MY_ZEROFILL));
|
||||
uint key_version;
|
||||
|
||||
crypt_data->scheme.type= type;
|
||||
mysql_mutex_init(key_CRYPT_DATA_lock, &crypt_data->lock,
|
||||
|
@ -175,6 +187,17 @@ ma_crypt_read(MARIA_SHARE* share, uchar *buff)
|
|||
crypt_data->space= uint4korr(buff + 2);
|
||||
memcpy(crypt_data->scheme.iv, buff + 6, sizeof(crypt_data->scheme.iv));
|
||||
share->crypt_data= crypt_data;
|
||||
|
||||
key_version= encryption_key_get_latest_version(crypt_data->scheme.key_id);
|
||||
if (unlikely(key_version == ENCRYPTION_KEY_VERSION_INVALID))
|
||||
{
|
||||
my_errno= HA_ERR_NO_ENCRYPTION;
|
||||
my_printf_error(HA_ERR_NO_ENCRYPTION,
|
||||
"Initialization of encryption failed for %s",
|
||||
MYF(ME_ERROR_LOG | (silent ? ME_WARNING : ME_FATAL)),
|
||||
share->data_file_name.str);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
share->crypt_page_header_space= CRYPT_SCHEME_1_KEY_VERSION_SIZE;
|
||||
|
@ -462,7 +485,7 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
|
|||
uint32 dstlen= 0; /* Must be set because of error message */
|
||||
|
||||
*key_version = encryption_key_get_latest_version(crypt_data->scheme.key_id);
|
||||
if (*key_version == ENCRYPTION_KEY_VERSION_INVALID)
|
||||
if (unlikely(*key_version == ENCRYPTION_KEY_VERSION_INVALID))
|
||||
{
|
||||
/*
|
||||
We use this error for both encryption and decryption, as in normal
|
||||
|
@ -470,7 +493,7 @@ static int ma_encrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data,
|
|||
*/
|
||||
my_errno= HA_ERR_DECRYPTION_FAILED;
|
||||
my_printf_error(HA_ERR_DECRYPTION_FAILED,
|
||||
"Unknown key id %u. Can't continue!",
|
||||
"Unknown encryption key id %u. Can't continue!",
|
||||
MYF(ME_FATAL|ME_ERROR_LOG),
|
||||
crypt_data->scheme.key_id);
|
||||
return 1;
|
||||
|
|
|
@ -26,7 +26,8 @@ uint ma_crypt_get_index_page_header_space(struct st_maria_share *);
|
|||
uint ma_crypt_get_file_length(); /* bytes needed in file */
|
||||
int ma_crypt_create(struct st_maria_share *); /* create encryption data */
|
||||
int ma_crypt_write(struct st_maria_share *, File); /* write encryption data */
|
||||
uchar* ma_crypt_read(struct st_maria_share *, uchar *buff); /* read crypt data*/
|
||||
uchar* ma_crypt_read(struct st_maria_share *, uchar *buff,
|
||||
my_bool silent); /* read crypt data*/
|
||||
|
||||
void ma_crypt_set_data_pagecache_callbacks(struct st_pagecache_file *file,
|
||||
struct st_maria_share *share);
|
||||
|
|
|
@ -43,12 +43,13 @@ int maria_delete_table(const char *name)
|
|||
'open_for_repair' to be able to open even a crashed table.
|
||||
*/
|
||||
my_errno= 0;
|
||||
if (!(info= maria_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
|
||||
if (!(info= maria_open(name, O_RDONLY, (HA_OPEN_FOR_DROP | HA_OPEN_FOR_REPAIR))))
|
||||
{
|
||||
sync_dir= 0;
|
||||
/* Ignore not found errors and wrong symlink errors */
|
||||
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION)
|
||||
got_error= my_errno;;
|
||||
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION &&
|
||||
my_errno != HA_ERR_NO_ENCRYPTION)
|
||||
got_error= my_errno;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -863,7 +863,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
|
|||
|
||||
if (MY_TEST(share->base.extra_options & MA_EXTRA_OPTIONS_ENCRYPTED))
|
||||
{
|
||||
if (!(disk_pos= ma_crypt_read(share, disk_pos)))
|
||||
if (!(disk_pos= ma_crypt_read(share, disk_pos,
|
||||
MY_TEST(open_flags & HA_OPEN_FOR_DROP))))
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue