Skip to content

Commit 44696d6

Browse files
Allen Laibjornmu
authored andcommitted
Fixed TDE bugs:
bug#22514564 TDE:INNODB:ASSERTION FAILURE IN THREAD 139878949578496 IN FILE UT0UT.CC LINE 920 bug#22522122 TWO TYPOS IN ERROR ER_INVALID_ENCRYPTION_OPTION Reviewed-by: Jimmy Yang<[email protected]> RB: 11462 (cherry picked from commit bd2e8ce2075ed29fe24c28d14e764e43426be02b)
1 parent 58c2ff5 commit 44696d6

File tree

10 files changed

+106
-65
lines changed

10 files changed

+106
-65
lines changed

mysql-test/suite/innodb/r/table_encrypt_1.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ERROR HY000: This tablespace can't be encrypted.
3131
CREATE TEMPORARY TABLE t1(c int) ENCRYPTION="N";
3232
DROP TABLE t1;
3333
CREATE TABLE t1(c int) ENCRYPTION="R" ENGINE = InnoDB;
34-
ERROR HY000: Invaild encyption option.
34+
ERROR HY000: Invalid encryption option.
3535
CREATE TABLE t1(c1 INT, c2 char(20)) ENCRYPTION="Y" ENGINE = InnoDB;
3636
SHOW CREATE TABLE t1;
3737
Table Create Table
@@ -108,7 +108,7 @@ c1 c2
108108
8 iiiii
109109
9 jjjjj
110110
ALTER TABLE t1 ENCRYPTION="N", algorithm=inplace;
111-
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Invaild encyption option.. Try ALGORITHM=COPY.
111+
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Invalid encryption option.. Try ALGORITHM=COPY.
112112
ALTER TABLE t1 TABLESPACE=`innodb_system`;
113113
ERROR HY000: This tablespace can't be encrypted.
114114
ALTER TABLE t1 ENCRYPTION="N", algorithm=copy;

mysql-test/suite/innodb/r/table_encrypt_3.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ SELECT @@innodb_file_per_table;
9898
1
9999
CREATE TABLE tde_db.t_encrypt(c1 INT, c2 char(20), c3 BLOB) ENCRYPTION="Y" ENGINE = InnoDB;
100100
CREATE TABLE tde_db.t_encrypt_1(c1 INT, c2 char(20)) ENCRYPTION="Yes" ENGINE = InnoDB;
101-
ERROR HY000: Invaild encyption option.
101+
ERROR HY000: Invalid encryption option.
102102
CREATE TABLE tde_db.t_encrypt_1(c1 INT, c2 char(20)) ENCRYPTION="y" ENGINE = InnoDB;
103103
DROP TABLE tde_db.t_encrypt_1;
104104
CREATE TABLE tde_db.t_encrypt_1(c1 INT, c2 char(20),c3 BLOB) ENGINE = InnoDB;

sql/share/errmsg-utf8.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7634,7 +7634,7 @@ ER_TABLESPACE_CANNOT_ENCRYPT
76347634
eng "This tablespace can't be encrypted."
76357635

76367636
ER_INVALID_ENCRYPTION_OPTION
7637-
eng "Invaild encyption option."
7637+
eng "Invalid encryption option."
76387638

76397639
ER_CANNOT_FIND_KEY_IN_KEYRING
76407640
eng "Can't find master key from keyring, please check keyring plugin is loaded."

storage/innobase/dict/dict0crea.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,13 @@ dict_build_tablespace(
435435
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); */
436436
ut_a(!FSP_FLAGS_GET_TEMPORARY(tablespace->flags()));
437437

438-
fsp_header_init(space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
439-
438+
bool ret = fsp_header_init(space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
440439
mtr_commit(&mtr);
441440

441+
if (!ret) {
442+
return(DB_ERROR);
443+
}
444+
442445
return(err);
443446
}
444447

@@ -539,9 +542,14 @@ dict_build_tablespace_for_table(
539542
mtr.set_named_space(table->space);
540543
dict_disable_redo_if_temporary(table, &mtr);
541544

542-
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
545+
bool ret = fsp_header_init(table->space,
546+
FIL_IBD_FILE_INITIAL_SIZE,
547+
&mtr);
543548

544549
mtr_commit(&mtr);
550+
if (!ret) {
551+
return(DB_ERROR);
552+
}
545553
} else {
546554
/* We do not need to build a tablespace for this table. It
547555
is already built. Just find the correct tablespace ID. */

storage/innobase/fsp/fsp0file.cc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ Datafile::free_first_page()
386386
space ID and flags. The file should exist and be successfully opened
387387
in order for this function to validate it.
388388
@param[in] space_id The expected tablespace ID.
389-
@param[in] flags The expected tablespace flags.
389+
@param[in] flags The expected tablespace flags.
390390
@retval DB_SUCCESS if tablespace is valid, DB_ERROR if not.
391391
m_is_valid is also set true on success, else false. */
392392
dberr_t
@@ -540,7 +540,7 @@ m_is_valid is set true on success, else false.
540540
@retval DB_CORRUPTION if the datafile is not readable
541541
@retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */
542542
dberr_t
543-
Datafile::validate_first_page(lsn_t* flush_lsn)
543+
Datafile::validate_first_page(lsn_t* flush_lsn)
544544
{
545545
char* prev_name;
546546
char* prev_filepath;
@@ -634,9 +634,9 @@ Datafile::validate_first_page(lsn_t* flush_lsn)
634634
can't be open. */
635635
if (FSP_FLAGS_GET_ENCRYPTION(m_flags)) {
636636
m_encryption_key = static_cast<byte*>(
637-
ut_malloc_nokey(ENCRYPTION_KEY_LEN));
637+
ut_zalloc_nokey(ENCRYPTION_KEY_LEN));
638638
m_encryption_iv = static_cast<byte*>(
639-
ut_malloc_nokey(ENCRYPTION_KEY_LEN));
639+
ut_zalloc_nokey(ENCRYPTION_KEY_LEN));
640640
#ifdef UNIV_ENCRYPT_DEBUG
641641
fprintf(stderr, "Got from file %lu:", m_space_id);
642642
#endif
@@ -660,6 +660,16 @@ Datafile::validate_first_page(lsn_t* flush_lsn)
660660
m_encryption_iv = NULL;
661661
return(DB_CORRUPTION);
662662
}
663+
664+
if (recv_recovery_is_on()
665+
&& memcmp(m_encryption_key,
666+
m_encryption_iv,
667+
ENCRYPTION_KEY_LEN) == 0) {
668+
ut_free(m_encryption_key);
669+
ut_free(m_encryption_iv);
670+
m_encryption_key = NULL;
671+
m_encryption_iv = NULL;
672+
}
663673
}
664674

665675
if (fil_space_read_name_and_filepath(

storage/innobase/fsp/fsp0fsp.cc

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,8 @@ fsp_header_fill_encryption_info(
893893
lint elen;
894894
ulint master_key_id;
895895
byte* master_key;
896+
byte key_info[ENCRYPTION_KEY_LEN * 2];
897+
ulint crc;
896898
#ifdef UNIV_ENCRYPT_DEBUG
897899
const byte* data;
898900
ulint i;
@@ -905,6 +907,8 @@ fsp_header_fill_encryption_info(
905907
}
906908

907909
memset(encrypt_info, 0, ENCRYPTION_INFO_SIZE);
910+
memset(key_info, 0, ENCRYPTION_KEY_LEN * 2);
911+
908912
/* Use the new master key to encrypt the tablespace
909913
key. */
910914
ut_ad(encrypt_info != NULL);
@@ -916,52 +920,38 @@ fsp_header_fill_encryption_info(
916920

917921
/* Write master key id. */
918922
mach_write_to_4(ptr, master_key_id);
923+
ptr += sizeof(ulint);
924+
925+
/* Write tablespace key to temp space. */
926+
memcpy(key_info,
927+
space->encryption_key,
928+
ENCRYPTION_KEY_LEN);
929+
930+
/* Write tablespace iv to temp space. */
931+
memcpy(key_info + ENCRYPTION_KEY_LEN,
932+
space->encryption_iv,
933+
ENCRYPTION_KEY_LEN);
919934

920935
#ifdef UNIV_ENCRYPT_DEBUG
921936
fprintf(stderr, "Set %lu:%lu ",space->id,
922937
Encryption::master_key_id);
923938
for (data = (const byte*) master_key, i = 0;
924939
i < ENCRYPTION_KEY_LEN; i++)
925940
fprintf(stderr, "%02lx", (ulong)*data++);
926-
#endif
927-
mach_write_to_4(ptr, master_key_id);
928-
929-
ptr += sizeof(ulint);
930-
931-
/* Encrypt tablespace key. */
932-
#ifdef UNIV_ENCRYPT_DEBUG
933941
fprintf(stderr, " ");
934942
for (data = (const byte*) space->encryption_key,
935943
i = 0; i < ENCRYPTION_KEY_LEN; i++)
936944
fprintf(stderr, "%02lx", (ulong)*data++);
937-
#endif
938-
elen = my_aes_encrypt(
939-
space->encryption_key,
940-
ENCRYPTION_KEY_LEN,
941-
ptr,
942-
master_key,
943-
ENCRYPTION_KEY_LEN,
944-
my_aes_256_ecb,
945-
NULL, false);
946-
947-
if (elen == MY_AES_BAD_DATA) {
948-
my_free(master_key);
949-
return(false);
950-
}
951-
952-
ptr += ENCRYPTION_KEY_LEN;
953-
954-
/* Encrypt tablespace data iv. */
955-
#ifdef UNIV_ENCRYPT_DEBUG
956945
fprintf(stderr, " ");
957946
for (data = (const byte*) space->encryption_iv,
958947
i = 0; i < ENCRYPTION_KEY_LEN; i++)
959948
fprintf(stderr, "%02lx", (ulong)*data++);
960949
fprintf(stderr, "\n");
961950
#endif
951+
/* Encrypt tablespace key and iv. */
962952
elen = my_aes_encrypt(
963-
space->encryption_iv,
964-
ENCRYPTION_KEY_LEN,
953+
key_info,
954+
ENCRYPTION_KEY_LEN * 2,
965955
ptr,
966956
master_key,
967957
ENCRYPTION_KEY_LEN,
@@ -973,6 +963,12 @@ fsp_header_fill_encryption_info(
973963
return(false);
974964
}
975965

966+
ptr += ENCRYPTION_KEY_LEN * 2;
967+
968+
/* Write checksum bytes. */
969+
crc = ut_crc32(key_info, ENCRYPTION_KEY_LEN * 2);
970+
mach_write_to_4(ptr, crc);
971+
976972
my_free(master_key);
977973
return(true);
978974
}
@@ -1098,7 +1094,7 @@ fsp_header_init(
10981094

10991095
/* For encryption tablespace, we need to save the encryption
11001096
info to the page 0. */
1101-
if (space->encryption_type != Encryption::NONE) {
1097+
if (FSP_FLAGS_GET_ENCRYPTION(space->flags)) {
11021098
ulint offset = fsp_header_get_encryption_offset(page_size);
11031099
byte encryption_info[ENCRYPTION_INFO_SIZE];
11041100

@@ -1107,6 +1103,9 @@ fsp_header_init(
11071103

11081104
if (!fsp_header_fill_encryption_info(space,
11091105
encryption_info)) {
1106+
space->encryption_type = Encryption::NONE;
1107+
memset(space->encryption_key, 0, ENCRYPTION_KEY_LEN);
1108+
memset(space->encryption_iv, 0, ENCRYPTION_KEY_LEN);
11101109
return(false);
11111110
}
11121111

@@ -1181,6 +1180,9 @@ fsp_header_decode_encryption_info(
11811180
ulint master_key_id;
11821181
byte* master_key = NULL;
11831182
lint elen;
1183+
byte key_info[ENCRYPTION_KEY_LEN * 2];
1184+
ulint crc1;
1185+
ulint crc2;
11841186
#ifdef UNIV_ENCRYPT_DEBUG
11851187
const byte* data;
11861188
ulint i;
@@ -1207,6 +1209,7 @@ fsp_header_decode_encryption_info(
12071209
ptr += sizeof(ulint);
12081210

12091211
/* Get master key by key id. */
1212+
memset(key_info, 0, ENCRYPTION_KEY_LEN * 2);
12101213
Encryption::get_master_key(master_key_id, &master_key);
12111214
if (master_key == NULL) {
12121215
return(false);
@@ -1222,8 +1225,8 @@ fsp_header_decode_encryption_info(
12221225
/* Decrypt tablespace key and iv. */
12231226
elen = my_aes_decrypt(
12241227
ptr,
1225-
ENCRYPTION_KEY_LEN,
1226-
key,
1228+
ENCRYPTION_KEY_LEN * 2,
1229+
key_info,
12271230
master_key,
12281231
ENCRYPTION_KEY_LEN,
12291232
my_aes_256_ecb, NULL, false);
@@ -1232,29 +1235,31 @@ fsp_header_decode_encryption_info(
12321235
my_free(master_key);
12331236
return(NULL);
12341237
}
1235-
#ifdef UNIV_ENCRYPT_DEBUG
1236-
fprintf(stderr, " ");
1237-
for (data = (const byte*) key,
1238-
i = 0; i < ENCRYPTION_KEY_LEN; i++)
1239-
fprintf(stderr, "%02lx", (ulong)*data++);
1240-
#endif
12411238

1242-
ptr += ENCRYPTION_KEY_LEN;
1243-
1244-
elen = my_aes_decrypt(
1245-
ptr,
1246-
ENCRYPTION_KEY_LEN,
1247-
iv,
1248-
master_key,
1249-
ENCRYPTION_KEY_LEN,
1250-
my_aes_256_ecb, NULL, false);
1239+
/* Check checksum bytes. */
1240+
ptr += ENCRYPTION_KEY_LEN * 2;
12511241

1252-
if (elen == MY_AES_BAD_DATA) {
1253-
my_free(master_key);
1242+
crc1 = mach_read_from_4(ptr);
1243+
crc2 = ut_crc32(key_info, ENCRYPTION_KEY_LEN * 2);
1244+
if (crc1 != crc2) {
1245+
ib::error() << "Failed to decrpt encryption information,"
1246+
<< " please check key file is not changed!";
12541247
return(false);
12551248
}
1249+
1250+
/* Get tablespace key */
1251+
memcpy(key, key_info, ENCRYPTION_KEY_LEN);
1252+
1253+
/* Get tablespace iv */
1254+
memcpy(iv, key_info + ENCRYPTION_KEY_LEN,
1255+
ENCRYPTION_KEY_LEN);
1256+
12561257
#ifdef UNIV_ENCRYPT_DEBUG
12571258
fprintf(stderr, " ");
1259+
for (data = (const byte*) key,
1260+
i = 0; i < ENCRYPTION_KEY_LEN; i++)
1261+
fprintf(stderr, "%02lx", (ulong)*data++);
1262+
fprintf(stderr, " ");
12581263
for (data = (const byte*) iv,
12591264
i = 0; i < ENCRYPTION_KEY_LEN; i++)
12601265
fprintf(stderr, "%02lx", (ulong)*data++);

storage/innobase/handler/ha_innodb.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3413,6 +3413,11 @@ innobase_encryption_key_rotation()
34133413

34143414
my_free(master_key);
34153415

3416+
/* If rotation failure, return error */
3417+
if (ret) {
3418+
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING, MYF(0));
3419+
}
3420+
34163421
/* Release the mutex. */
34173422
mutex_exit(&master_key_id_mutex);
34183423

storage/innobase/include/fsp0file.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ class Datafile {
266266
@retval DB_SUCCESS on if the datafile is valid
267267
@retval DB_CORRUPTION if the datafile is not readable
268268
@retval DB_TABLESPACE_EXISTS if there is a duplicate space_id */
269-
dberr_t validate_first_page(lsn_t* flush_lsn = 0)
269+
dberr_t validate_first_page(lsn_t* flush_lsn = 0)
270270
__attribute__((warn_unused_result));
271271

272272
/** Get Datafile::m_name.

storage/innobase/include/os0file.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,10 @@ static const char ENCRYPTION_KEY_MAGIC[ENCRYPTION_MAGIC_SIZE] = {
310310
/** Encryption master key prifix size */
311311
#define ENCRYPTION_MASTER_KEY_NAME_MAX_LEN 100
312312

313-
/** Encryption information total size */
313+
/** Encryption information total size: magic number + master_key_id +
314+
key + iv + checksum */
314315
#define ENCRYPTION_INFO_SIZE (ENCRYPTION_MAGIC_SIZE \
315-
+ (ENCRYPTION_KEY_LEN * 2) + sizeof(ulint))
316+
+ (ENCRYPTION_KEY_LEN * 2) + 2 * sizeof(ulint))
316317

317318
class IORequest;
318319

storage/innobase/log/log0recv.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,11 +1059,23 @@ recv_sys_debug_free(void)
10591059
}
10601060

10611061
if (recv_sys->encryption_list != NULL) {
1062-
while (recv_sys->encryption_list
1063-
&& !recv_sys->encryption_list->empty()) {
1064-
recv_sys->encryption_list->pop_back();
1062+
encryption_list_t::iterator it;
1063+
1064+
for (it = recv_sys->encryption_list->begin();
1065+
it != recv_sys->encryption_list->end();
1066+
it++) {
1067+
if (it->key != NULL) {
1068+
ut_free(it->key);
1069+
it->key = NULL;
1070+
}
1071+
if (it->iv != NULL) {
1072+
ut_free(it->iv);
1073+
it->iv = NULL;
1074+
}
10651075
}
10661076

1077+
recv_sys->encryption_list->swap(*recv_sys->encryption_list);
1078+
10671079
UT_DELETE(recv_sys->encryption_list);
10681080
recv_sys->encryption_list = NULL;
10691081
}

0 commit comments

Comments
 (0)