Skip to content

Commit

Permalink
Bug#26243264 ALTER TABLE ON ENCRYPTED TABLE CAUSES FRM OUT OF SYNC AN…
Browse files Browse the repository at this point in the history
…D DECRYPTS DATA

This bug is cased by that we didn't set the encryption attribuite properly in altering table.

Approved by Jimmy Yang <[email protected]>

(cherry picked from commit 2ef1a5d1b626e1f5ae6a35c69f8a221f95a266f4)
  • Loading branch information
Allen Lai authored and bkandasa committed Jun 14, 2017
1 parent 4099666 commit 68c7d04
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
15 changes: 15 additions & 0 deletions mysql-test/suite/innodb/r/table_encrypt_1.result
Original file line number Diff line number Diff line change
Expand Up @@ -252,5 +252,20 @@ CREATE TABLE t1 (c1 int);
ALTER TABLE t1 COMPRESSION='zlib';
ALTER TABLE t1 ENCRYPTION='Y',ALGORITHM=COPY;
ERROR HY000: This tablespace can't be encrypted.
DROP TABLE t1;
SET GLOBAL innodb_file_per_table=ON;
CREATE TABLE t1 (id int unsigned NOT NULL auto_increment PRIMARY KEY, val varchar(20) NOT NULL) ENGINE=InnoDB;
INSERT INTO t1 (val) VALUES ('Sydney'), ('Melbourne'), ('Brisbane'), ('Perth'), ('Adelaide');
ALTER TABLE t1 ENCRYPTION = 'Y';
ALTER TABLE t1 ADD COLUMN is_capital char(1) NOT NULL DEFAULT 'N' AFTER val;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`val` varchar(20) NOT NULL,
`is_capital` char(1) NOT NULL DEFAULT 'N',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 ENCRYPTION='Y'
Pattern "Sydney" not found
SET GLOBAL innodb_file_per_table=1;
DROP TABLE t1;
21 changes: 21 additions & 0 deletions mysql-test/suite/innodb/t/table_encrypt_1.test
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,27 @@ ALTER TABLE t1 COMPRESSION='zlib';
--error ER_TABLESPACE_CANNOT_ENCRYPT
ALTER TABLE t1 ENCRYPTION='Y',ALGORITHM=COPY;

# Cleanup
DROP TABLE t1;

# Test encryption works fine after alter table.
SET GLOBAL innodb_file_per_table=ON;

CREATE TABLE t1 (id int unsigned NOT NULL auto_increment PRIMARY KEY, val varchar(20) NOT NULL) ENGINE=InnoDB;

INSERT INTO t1 (val) VALUES ('Sydney'), ('Melbourne'), ('Brisbane'), ('Perth'), ('Adelaide');

ALTER TABLE t1 ENCRYPTION = 'Y';

ALTER TABLE t1 ADD COLUMN is_capital char(1) NOT NULL DEFAULT 'N' AFTER val;
SHOW CREATE TABLE t1;

LET $MYSQLD_DATADIR = `select @@datadir`;
let SEARCH_FILE = $MYSQLD_DATADIR/test/t1.ibd;
let SEARCH_PATTERN=Sydney;
# The string should not be found, since it's encrypted.
--source include/search_pattern.inc

# Cleanup
eval SET GLOBAL innodb_file_per_table=$innodb_file_per_table;
DROP TABLE t1;
35 changes: 34 additions & 1 deletion storage/innobase/handler/handler0alter.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
Expand Down Expand Up @@ -4576,6 +4576,39 @@ prepare_inplace_alter_table_dict(
compression = NULL;
}

const char* encrypt;
encrypt = ha_alter_info->create_info->encrypt_type.str;

if (!(ctx->new_table->flags2 & DICT_TF2_USE_FILE_PER_TABLE)
&& ha_alter_info->create_info->encrypt_type.length > 0
&& !Encryption::is_none(encrypt)) {

dict_mem_table_free( ctx->new_table);
my_error(ER_TABLESPACE_CANNOT_ENCRYPT, MYF(0));
goto new_clustered_failed;
} else if (!Encryption::is_none(encrypt)) {
/* Set the encryption flag. */
byte* master_key = NULL;
ulint master_key_id;
Encryption::Version version;

/* Check if keyring is ready. */
Encryption::get_master_key(&master_key_id,
&master_key,
&version);

if (master_key == NULL) {
dict_mem_table_free(ctx->new_table);
my_error(ER_CANNOT_FIND_KEY_IN_KEYRING,
MYF(0));
goto new_clustered_failed;
} else {
my_free(master_key);
DICT_TF2_FLAG_SET(ctx->new_table,
DICT_TF2_ENCRYPTION);
}
}

error = row_create_table_for_mysql(
ctx->new_table, compression, ctx->trx, false);

Expand Down

0 comments on commit 68c7d04

Please sign in to comment.