summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/handler_ername.h1
-rw-r--r--include/my_base.h6
-rw-r--r--include/my_handler_errors.h3
-rw-r--r--mysql-test/include/wait_until_connected_again.inc6
-rw-r--r--mysql-test/suite/maria/encrypt-no-key.result36
-rw-r--r--mysql-test/suite/maria/encrypt-no-key.test55
-rw-r--r--mysql-test/suite/maria/encrypt-wrong-key.result12
-rw-r--r--mysql-test/suite/maria/encrypt-wrong-key.test7
-rw-r--r--storage/maria/ha_maria.cc3
-rw-r--r--storage/maria/ma_create.c2
-rw-r--r--storage/maria/ma_crypt.c35
-rw-r--r--storage/maria/ma_crypt.h3
-rw-r--r--storage/maria/ma_delete_table.c7
-rw-r--r--storage/maria/ma_open.c3
14 files changed, 135 insertions, 44 deletions
diff --git a/include/handler_ername.h b/include/handler_ername.h
index fe55062e6fb..20e62487c2c 100644
--- a/include/handler_ername.h
+++ b/include/handler_ername.h
@@ -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, "" },
diff --git a/include/my_base.h b/include/my_base.h
index 32ef6f7fe85..cc3d57cb0b1 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -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)
diff --git a/include/my_handler_errors.h b/include/my_handler_errors.h
index 4c3a02dd745..7eab185dd98 100644
--- a/include/my_handler_errors.h
+++ b/include/my_handler_errors.h
@@ -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 */
diff --git a/mysql-test/include/wait_until_connected_again.inc b/mysql-test/include/wait_until_connected_again.inc
index 15a1e5bf847..f644ec8645f 100644
--- a/mysql-test/include/wait_until_connected_again.inc
+++ b/mysql-test/include/wait_until_connected_again.inc
@@ -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
diff --git a/mysql-test/suite/maria/encrypt-no-key.result b/mysql-test/suite/maria/encrypt-no-key.result
index 6745670dfac..32a280d8cbc 100644
--- a/mysql-test/suite/maria/encrypt-no-key.result
+++ b/mysql-test/suite/maria/encrypt-no-key.result
@@ -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
diff --git a/mysql-test/suite/maria/encrypt-no-key.test b/mysql-test/suite/maria/encrypt-no-key.test
index 2d586c50695..b3f2f4b4bf3 100644
--- a/mysql-test/suite/maria/encrypt-no-key.test
+++ b/mysql-test/suite/maria/encrypt-no-key.test
@@ -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
diff --git a/mysql-test/suite/maria/encrypt-wrong-key.result b/mysql-test/suite/maria/encrypt-wrong-key.result
index bc22481296d..4ff057957da 100644
--- a/mysql-test/suite/maria/encrypt-wrong-key.result
+++ b/mysql-test/suite/maria/encrypt-wrong-key.result
@@ -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;
diff --git a/mysql-test/suite/maria/encrypt-wrong-key.test b/mysql-test/suite/maria/encrypt-wrong-key.test
index ca65e1018d0..ac060c4e9dd 100644
--- a/mysql-test/suite/maria/encrypt-wrong-key.test
+++ b/mysql-test/suite/maria/encrypt-wrong-key.test
@@ -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
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 2d6c8f85fe4..f25ba2aa0b3 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -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);
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 8ef3249c2e4..3352a494d16 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -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;
diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c
index 33cf72b0b1e..8cc85d87d28 100644
--- a/storage/maria/ma_crypt.c
+++ b/storage/maria/ma_crypt.c
@@ -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;
diff --git a/storage/maria/ma_crypt.h b/storage/maria/ma_crypt.h
index 811b319bc0c..acaf36ee831 100644
--- a/storage/maria/ma_crypt.h
+++ b/storage/maria/ma_crypt.h
@@ -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);
diff --git a/storage/maria/ma_delete_table.c b/storage/maria/ma_delete_table.c
index 0c78476ad44..250ea9dff89 100644
--- a/storage/maria/ma_delete_table.c
+++ b/storage/maria/ma_delete_table.c
@@ -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
{
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 06183c72895..7b59351e24b 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -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;
}