Details
Description
DROP TABLE `##################################################_long`.`#################################################_long`; |
Leads to
10.5.25 33e4fbf04578c40c02306b65083c6d9a90ca8b2b (Optimized, UBASAN) |
==3483292==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x14ecb1bd9dc0 at pc 0x55bb2294c593 bp 0x14ecb1bd8f70 sp 0x14ecb1bd8f60
|
WRITE of size 1 at 0x14ecb1bd9dc0 thread T30
|
#0 0x55bb2294c592 in strxnmov /test/10.5_opt_san/strings/strxnmov.c:71
|
#1 0x55bb21487ac6 in frm_file_exists /test/10.5_opt_san/storage/innobase/handler/ha_innodb.cc:13316
|
#2 0x55bb21487ac6 in ha_innobase::delete_table(char const*, enum_sql_command) /test/10.5_opt_san/storage/innobase/handler/ha_innodb.cc:13416
|
#3 0x55bb1fcf98ff in hton_drop_table /test/10.5_opt_san/sql/handler.cc:561
|
#4 0x55bb1fd28bc8 in ha_delete_table(THD*, handlerton*, char const*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, bool) /test/10.5_opt_san/sql/handler.cc:2856
|
#5 0x55bb1fd2a065 in delete_table_force /test/10.5_opt_san/sql/handler.cc:5171
|
#6 0x55bb1e9f6d80 in plugin_foreach_with_mask(THD*, char (*)(THD*, st_plugin_int*, void*), int, unsigned int, void*) /test/10.5_opt_san/sql/sql_plugin.cc:2553
|
#7 0x55bb1fd204b3 in ha_delete_table_force(THD*, char const*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*) /test/10.5_opt_san/sql/handler.cc:5217
|
#8 0x55bb1ee78e58 in mysql_rm_table_no_locks(THD*, TABLE_LIST*, bool, bool, bool, bool, bool, bool) /test/10.5_opt_san/sql/sql_table.cc:2601
|
#9 0x55bb1ee7e915 in mysql_rm_table(THD*, TABLE_LIST*, bool, bool, bool, bool) /test/10.5_opt_san/sql/sql_table.cc:2164
|
#10 0x55bb1e9bc342 in mysql_execute_command(THD*) /test/10.5_opt_san/sql/sql_parse.cc:5072
|
#11 0x55bb1e93a8cd in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /test/10.5_opt_san/sql/sql_parse.cc:8203
|
#12 0x55bb1e999b87 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /test/10.5_opt_san/sql/sql_parse.cc:1891
|
#13 0x55bb1e9a5cd2 in do_command(THD*) /test/10.5_opt_san/sql/sql_parse.cc:1375
|
#14 0x55bb1f1c9c28 in do_handle_one_connection(CONNECT*, bool) /test/10.5_opt_san/sql/sql_connect.cc:1415
|
#15 0x55bb1f1cc29c in handle_one_connection /test/10.5_opt_san/sql/sql_connect.cc:1317
|
#16 0x14ecd8c2b608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
|
#17 0x14ecd7ea0132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)
|
[..]
|
Bug confirmed present in:
MariaDB: 10.5.25 (dbg), 10.5.25 (opt)
Bug (or feature/syntax) confirmed not present in:
MariaDB: 10.6.18 (opt), 10.11.8 (opt), 11.0.6 (opt), 11.1.5 (opt), 11.2.4 (opt), 11.3.3 (opt), 11.4.2 (opt), 11.5.0 (opt), 10.6.18 (dbg), 10.11.8 (dbg), 11.0.6 (dbg), 11.1.5 (dbg), 11.2.4 (dbg), 11.3.3 (dbg), 11.4.2 (dbg), 11.5.0 (dbg)
Attachments
Issue Links
- is caused by
-
MDEV-11412 Ensure that table is truly dropped when using DROP TABLE
-
- Closed
-
- relates to
-
MDEV-25691 Simplify handlerton::drop_database for InnoDB
-
- Closed
-
The following code was added in
MDEV-11412:{
strxnmov(buff, FN_REFLEN, path, reg_ext, NullS);
}
Based on the ASAN report, it looks like we are invoking strnxmov incorrectly, or there is a bug in strnxmov that causes it to exceed the specified size FN_REFLEN (512 bytes). As far as I can tell, the maximum possible name length here is something like 645 bytes (including a path component separator character FN_LIBCHAR and the reg_ext suffix .frm). If there is some ./ prepended, the name could be even longer. We also need to reserve one byte for the terminating NUL character.
If strxnmov() itself did not cause a buffer overflow, the call would still have to be fixed to detect that an overflow would have occurred, to avoid invoking access on a truncated string of 512 characters that is not NUL terminated. Something like this, using a standard library function:
!access(buff, F_OK);
That is, if the file name length exceeds 511 bytes, we assume that the file does not exist. Linux for example limits the path component length to 255 bytes, so 512 bytes are just enough for databasename/filename.frm and a terminating NUL character.