summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorMarcin Babij <marcin.babij@oracle.com>2014-06-27 11:27:27 +0200
committerMarcin Babij <marcin.babij@oracle.com>2014-06-27 11:27:27 +0200
commit220c9332bf057bc75e1eae490bb3a68c2d7c3341 (patch)
treeae1a299b1716c636fb370c1adc89cfe1196ba15a /client
parent5111df08146bcc9f233edada7eecdb1457b09d59 (diff)
downloadmariadb-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.c39
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 */