Skip to content

Commit 4dee592

Browse files
dingweiqingsvuvova
authored andcommitted
MDEV-9158 Read max size bytes from encryption key file and ignore remain bytes
Previously plugin check aes key file size to make sure its size isn't too large before reading it, this commit change the way to read only max aes key file size bytes. This way can support named pipe as a coproduct .
1 parent e7f7789 commit 4dee592

File tree

7 files changed

+117
-25
lines changed

7 files changed

+117
-25
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Test checks if opening a too large key file, file key plugin will only read max key file size bytes and extra bytes will be ignored.
2+
#Large key file will read max size bytes , which is 1MB
3+
call mtr.add_suppression("Syntax error");
4+
call mtr.add_suppression("Invalid key");
5+
call mtr.add_suppression("Plugin 'file_key_management' init function returned error");
6+
call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
7+
INSTALL SONAME 'file_key_management';
8+
FOUND 1 /read bytes: 1048576B/ in mysqld.1.err
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
INSTALL SONAME 'file_key_management';
2+
Warnings:
3+
Note 1 Read from MYSQL_TMP_DIR/fifo.key , read bytes: 105B, max key file size :1048576B
4+
CREATE TABLE t1(c1 BIGINT NOT NULL, b CHAR(200)) ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
5+
SHOW CREATE TABLE t1;
6+
Table Create Table
7+
t1 CREATE TABLE `t1` (
8+
`c1` bigint(20) NOT NULL,
9+
`b` char(200) DEFAULT NULL
10+
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=1
11+
INSERT t1 VALUES (12345, REPEAT('1234567890', 20));
12+
ALTER TABLE t1 ENCRYPTION_KEY_ID=2;
13+
SHOW CREATE TABLE t1;
14+
Table Create Table
15+
t1 CREATE TABLE `t1` (
16+
`c1` bigint(20) NOT NULL,
17+
`b` char(200) DEFAULT NULL
18+
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=2
19+
ALTER TABLE t1 ENCRYPTION_KEY_ID=3;
20+
SHOW CREATE TABLE t1;
21+
Table Create Table
22+
t1 CREATE TABLE `t1` (
23+
`c1` bigint(20) NOT NULL,
24+
`b` char(200) DEFAULT NULL
25+
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=3
26+
# Reset mysqld
27+
DROP TABLE t1;
28+
UNINSTALL SONAME 'file_key_management';
29+
Warnings:
30+
Warning 1620 Plugin is busy and will be uninstalled on shutdown
31+
# restart
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--loose-file-key-management-filename=$MYSQL_TMP_DIR/filekeys-data-too-large.key
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-- source include/not_embedded.inc
2+
--echo # Test checks if opening a too large key file, file key plugin will only read max key file size bytes and extra bytes will be ignored.
3+
4+
let $k=0;
5+
while($k<1000){
6+
let $content="";
7+
let $i= 1;
8+
while($i <= 100){
9+
let $num= `SELECT $i+$k*100`;
10+
let $content=$content"$num;24e579b00c0f365a11761bdb9286a72a1148fa779d9c23dd55402627d0c87726";
11+
if($i<=99){
12+
let $content=$content"\n";
13+
}
14+
inc $i;
15+
}
16+
exec echo -e $content >> $MYSQL_TMP_DIR/filekeys-data-too-large.key;
17+
inc $k;
18+
}
19+
--echo #Large key file will read max size bytes , which is 1MB
20+
let SEARCH_PATTERN=read bytes: 1048576B;
21+
call mtr.add_suppression("Syntax error");
22+
call mtr.add_suppression("Invalid key");
23+
call mtr.add_suppression("Plugin 'file_key_management' init function returned error");
24+
call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
25+
26+
--disable_result_log
27+
--error 2
28+
INSTALL SONAME 'file_key_management';
29+
--enable_result_log
30+
31+
32+
--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
33+
--source include/search_pattern_in_file.inc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--loose-file-key-management-filename=$MYSQL_TMP_DIR/fifo.key
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#
2+
# Test read key from named pipe
3+
#
4+
write_file $MYSQL_TMP_DIR/fifo.key;
5+
1;11111111111111111111111111111111
6+
2;00000000000000000000000000000000
7+
3;22222222222222222222222222222222
8+
EOF
9+
--sleep 3
10+
11+
--source include/have_innodb.inc
12+
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
13+
INSTALL SONAME 'file_key_management';
14+
15+
CREATE TABLE t1(c1 BIGINT NOT NULL, b CHAR(200)) ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
16+
SHOW CREATE TABLE t1;
17+
INSERT t1 VALUES (12345, REPEAT('1234567890', 20));
18+
19+
ALTER TABLE t1 ENCRYPTION_KEY_ID=2;
20+
SHOW CREATE TABLE t1;
21+
ALTER TABLE t1 ENCRYPTION_KEY_ID=3;
22+
SHOW CREATE TABLE t1;
23+
24+
--echo # Reset mysqld
25+
DROP TABLE t1;
26+
remove_file $MYSQL_TMP_DIR/fifo.key;
27+
UNINSTALL SONAME 'file_key_management';
28+
29+
--source include/restart_mysqld.inc
30+

plugin/file_key_management/parser.cc

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ int Parser::parse_line(char **line_ptr, keyentry *key)
314314
char* Parser::read_and_decrypt_file(const char *secret)
315315
{
316316
int f;
317+
ssize_t file_size= 0;
317318
if (!filename || !filename[0])
318319
{
319320
my_printf_error(EE_CANT_OPEN_STREAM, "file-key-management-filename is not set",
@@ -328,41 +329,28 @@ char* Parser::read_and_decrypt_file(const char *secret)
328329
goto err0;
329330
}
330331

331-
my_off_t file_size;
332-
file_size= lseek(f, 0, SEEK_END);
333-
334-
if (file_size == MY_FILEPOS_ERROR || (my_off_t)lseek(f, 0, SEEK_SET) == MY_FILEPOS_ERROR)
335-
{
336-
my_error(EE_CANT_SEEK, MYF(0), filename, errno);
337-
goto err1;
338-
}
339-
340-
if (file_size > MAX_KEY_FILE_SIZE)
341-
{
342-
my_error(EE_READ, MYF(0), filename, EFBIG);
343-
goto err1;
344-
}
345-
346332
//Read file into buffer
347333
uchar *buffer;
348-
buffer= (uchar*)malloc((size_t)file_size + 1);
334+
buffer= (uchar *) malloc((size_t) MAX_KEY_FILE_SIZE );
349335
if (!buffer)
350336
{
351-
my_error(EE_OUTOFMEMORY, ME_ERROR_LOG| ME_FATAL, file_size);
337+
my_error(EE_OUTOFMEMORY, ME_ERROR_LOG | ME_FATAL, file_size);
352338
goto err1;
353339
}
354-
355-
if (read(f, buffer, (int)file_size) != (int)file_size)
340+
file_size= read(f, buffer, MAX_KEY_FILE_SIZE);
341+
if (file_size < 0)
356342
{
357-
my_printf_error(EE_READ,
358-
"read from %s failed, errno %d",
359-
MYF(ME_ERROR_LOG|ME_FATAL), filename, errno);
343+
my_printf_error(EE_READ, "Read from %s failed, errno %d",
344+
ME_ERROR_LOG , filename, errno);
360345
goto err2;
361346
}
362-
363-
// Check for file encryption
347+
my_printf_error(EE_ERROR_FIRST,
348+
"Read from %s , read bytes: %zdB, max key file size :%dB ",
349+
ME_ERROR_LOG | ME_NOTE, filename, file_size,
350+
MAX_KEY_FILE_SIZE);
351+
// Check for file encryption
364352
uchar *decrypted;
365-
if (file_size > OpenSSL_prefix_len && strncmp((char*)buffer, OpenSSL_prefix, OpenSSL_prefix_len) == 0)
353+
if ((size_t)file_size > OpenSSL_prefix_len && strncmp((char*)buffer, OpenSSL_prefix, OpenSSL_prefix_len) == 0)
366354
{
367355
uchar key[OpenSSL_key_len];
368356
uchar iv[OpenSSL_iv_len];

0 commit comments

Comments
 (0)