mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-29409 Buffer overflow in my_wc_mb_filename() on RENAME TABLE
dict_table_rename_in_cache(), dict_table_get_highest_foreign_id(): Reserve sufficient space for the fkid[] buffer, and ensure that the fkid[] will be NUL-terminated. The fkid[] must accommodate both the database name (which is already encoded in my_charset_filename) and the constraint name (which must be converted to my_charset_filename) so that we can check if it is in the format databasename/tablename_ibfk_1 (all encoded in my_charset_filename).
This commit is contained in:
@ -18,6 +18,14 @@ CREATE TABLE `d255`.`d245` (x INT) ENGINE=InnoDB;
|
|||||||
DROP TABLE `d255`.`d250`;
|
DROP TABLE `d255`.`d250`;
|
||||||
RENAME TABLE `d250#`.`d245` TO `d250#`.`d250`;
|
RENAME TABLE `d250#`.`d245` TO `d250#`.`d250`;
|
||||||
RENAME TABLE `d255`.`d250` TO a;
|
RENAME TABLE `d255`.`d250` TO a;
|
||||||
DROP DATABASE `d255`;
|
|
||||||
DROP TABLE a,t;
|
DROP TABLE a,t;
|
||||||
|
#
|
||||||
|
# MDEV-29409 Buffer overflow in my_wc_mb_filename() on RENAME TABLE
|
||||||
|
#
|
||||||
|
CREATE TABLE `d255`.t(a INT PRIMARY KEY)ENGINE=InnoDB;
|
||||||
|
CREATE TABLE `d255`.u(a INT PRIMARY KEY,
|
||||||
|
CONSTRAINT `d320` FOREIGN KEY (a) REFERENCES `d255`.t (a)) ENGINE=InnoDB;
|
||||||
|
RENAME TABLE `d255`.u TO u;
|
||||||
|
DROP TABLE u;
|
||||||
|
DROP DATABASE `d255`;
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
|
@ -54,7 +54,24 @@ eval RENAME TABLE `$d255`.`$d245` TO `$d255`.`$d250`;
|
|||||||
--replace_result $d250 d250 $d255 d255
|
--replace_result $d250 d250 $d255 d255
|
||||||
eval RENAME TABLE `$d255`.`$d250` TO a;
|
eval RENAME TABLE `$d255`.`$d250` TO a;
|
||||||
--replace_result $d255 d255
|
--replace_result $d255 d255
|
||||||
eval DROP DATABASE `$d255`;
|
|
||||||
DROP TABLE a,t;
|
DROP TABLE a,t;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-29409 Buffer overflow in my_wc_mb_filename() on RENAME TABLE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
let $d225=#############################################;
|
||||||
|
let $d320=################################################################;
|
||||||
|
|
||||||
|
--replace_result $d255 d255
|
||||||
|
eval CREATE TABLE `$d255`.t(a INT PRIMARY KEY)ENGINE=InnoDB;
|
||||||
|
--replace_result $d255 d255 $d320 d320
|
||||||
|
eval CREATE TABLE `$d255`.u(a INT PRIMARY KEY,
|
||||||
|
CONSTRAINT `$d320` FOREIGN KEY (a) REFERENCES `$d255`.t (a)) ENGINE=InnoDB;
|
||||||
|
--replace_result $d255 d255
|
||||||
|
eval RENAME TABLE `$d255`.u TO u;
|
||||||
|
DROP TABLE u;
|
||||||
|
--replace_result $d255 d255
|
||||||
|
eval DROP DATABASE `$d255`;
|
||||||
|
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
@ -1595,7 +1595,7 @@ dict_table_rename_in_cache(
|
|||||||
in UTF-8 charset. The variable fkid here is used
|
in UTF-8 charset. The variable fkid here is used
|
||||||
to store foreign key constraint name in charset
|
to store foreign key constraint name in charset
|
||||||
my_charset_filename for comparison further below. */
|
my_charset_filename for comparison further below. */
|
||||||
char fkid[MAX_TABLE_NAME_LEN+20];
|
char fkid[MAX_TABLE_NAME_LEN * 2 + 20];
|
||||||
ibool on_tmp = FALSE;
|
ibool on_tmp = FALSE;
|
||||||
|
|
||||||
/* The old table name in my_charset_filename is stored
|
/* The old table name in my_charset_filename is stored
|
||||||
@ -1629,7 +1629,8 @@ dict_table_rename_in_cache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(fkid, foreign->id, MAX_TABLE_NAME_LEN);
|
strncpy(fkid, foreign->id, (sizeof fkid) - 1);
|
||||||
|
fkid[(sizeof fkid) - 1] = '\0';
|
||||||
|
|
||||||
if (strstr(fkid, TEMP_TABLE_PATH_PREFIX) == NULL) {
|
if (strstr(fkid, TEMP_TABLE_PATH_PREFIX) == NULL) {
|
||||||
innobase_convert_to_filename_charset(
|
innobase_convert_to_filename_charset(
|
||||||
@ -3671,10 +3672,11 @@ dict_table_get_highest_foreign_id(
|
|||||||
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
for (dict_foreign_set::iterator it = table->foreign_set.begin();
|
||||||
it != table->foreign_set.end();
|
it != table->foreign_set.end();
|
||||||
++it) {
|
++it) {
|
||||||
char fkid[MAX_TABLE_NAME_LEN+20];
|
char fkid[MAX_TABLE_NAME_LEN * 2 + 20];
|
||||||
foreign = *it;
|
foreign = *it;
|
||||||
|
|
||||||
strcpy(fkid, foreign->id);
|
strncpy(fkid, foreign->id, (sizeof fkid) - 1);
|
||||||
|
fkid[(sizeof fkid) - 1] = '\0';
|
||||||
/* Convert foreign key identifier on dictionary memory
|
/* Convert foreign key identifier on dictionary memory
|
||||||
cache to filename charset. */
|
cache to filename charset. */
|
||||||
innobase_convert_to_filename_charset(
|
innobase_convert_to_filename_charset(
|
||||||
|
Reference in New Issue
Block a user