diff options
author | Marcin Babij <marcin.babij@oracle.com> | 2014-06-27 11:27:27 +0200 |
---|---|---|
committer | Marcin Babij <marcin.babij@oracle.com> | 2014-06-27 11:27:27 +0200 |
commit | 220c9332bf057bc75e1eae490bb3a68c2d7c3341 (patch) | |
tree | ae1a299b1716c636fb370c1adc89cfe1196ba15a /client | |
parent | 5111df08146bcc9f233edada7eecdb1457b09d59 (diff) | |
download | mariadb-git-220c9332bf057bc75e1eae490bb3a68c2d7c3341.tar.gz |
BUG#18779944: MYSQLDUMP BUFFER OVERFLOW
Mysqldump overflows stack buffer when copying table name from commandline arguments resulting in stack corruption and ability to execute arbitrary code.
Fix: Check length of all positional arguments passed to mysqldump is smaller than NAME_LEN.
Note: Mysqldump heavily depends on that database objects (databases, tablespaces, tables, etc) are limited to small size (now it is 64).
Diffstat (limited to 'client')
-rw-r--r-- | client/mysqldump.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index c19b0b1822a..2a873903d60 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -5538,19 +5538,36 @@ int main(int argc, char **argv) dump_all_tablespaces(); dump_all_databases(); } - else if (argc > 1 && !opt_databases) - { - /* Only one database and selected table(s) */ - if (!opt_alltspcs && !opt_notspcs) - dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1)); - dump_selected_tables(*argv, (argv + 1), (argc - 1)); - } else { - /* One or more databases, all tables */ - if (!opt_alltspcs && !opt_notspcs) - dump_tablespaces_for_databases(argv); - dump_databases(argv); + // Check all arguments meet length condition. Currently database and table + // names are limited to NAME_LEN bytes and stack-based buffers assumes + // that escaped name will be not longer than NAME_LEN*2 + 2 bytes long. + int argument; + for (argument= 0; argument < argc; argument++) + { + size_t argument_length= strlen(argv[argument]); + if (argument_length > NAME_LEN) + { + die(EX_CONSCHECK, "[ERROR] Argument '%s' is too long, it cannot be " + "name for any table or database.\n", argv[argument]); + } + } + + if (argc > 1 && !opt_databases) + { + /* Only one database and selected table(s) */ + if (!opt_alltspcs && !opt_notspcs) + dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1)); + dump_selected_tables(*argv, (argv + 1), (argc - 1)); + } + else + { + /* One or more databases, all tables */ + if (!opt_alltspcs && !opt_notspcs) + dump_tablespaces_for_databases(argv); + dump_databases(argv); + } } /* if --dump-slave , start the slave sql thread */ |