Skip to content

Commit 73ee5aa

Browse files
committed
WL#16482: mysqldump blindly trusting SHOW CREATE TABLE leads
to arbitrary code execution. 9.x version Introduced a --[skip-]system-command command line/config file option for the mysql binary. Type: boolean Default: OFF When a system command or the abbreviated \! is specified, an error will be printed and the command won't be executed. Unless --system-command is passed on the mysql's command line Test case added. Change-Id: Ied3ade8e0a54cf3ce5ce7c328c15341faf5e2f1f
1 parent 3d2cf8b commit 73ee5aa

File tree

5 files changed

+50
-11
lines changed

5 files changed

+50
-11
lines changed

client/mysql.cc

+15-1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ static char *opt_register_factor = nullptr;
251251
static bool opt_tel_plugin = false;
252252
static const char *opt_tel_plugin_name = "telemetry_client";
253253

254+
static bool opt_system_command = false;
255+
254256
static struct my_option my_empty_options[] = {
255257
{nullptr, 0, nullptr, nullptr, nullptr, nullptr, GET_NO_ARG, NO_ARG, 0, 0,
256258
0, nullptr, 0, nullptr}};
@@ -429,7 +431,8 @@ static COMMANDS commands[] = {
429431
"Execute an SQL script file. Takes a file name as an argument."},
430432
{"status", 's', com_status, false,
431433
"Get status information from the server."},
432-
{"system", '!', com_shell, true, "Execute a system shell command."},
434+
{"system", '!', com_shell, true,
435+
"Execute a system shell command, if enabled"},
433436
{"tee", 'T', com_tee, true,
434437
"Set outfile [to_outfile]. Append everything into given outfile."},
435438
{"use", 'u', com_use, true,
@@ -2086,6 +2089,10 @@ static struct my_option my_long_options[] = {
20862089
"Specifies factor for which registration needs to be done for.",
20872090
&opt_register_factor, &opt_register_factor, nullptr, GET_STR, REQUIRED_ARG,
20882091
0, 0, 0, nullptr, 0, nullptr},
2092+
{"system-command", 0,
2093+
"Enable or disable (by default) the 'system' mysql command.",
2094+
&opt_system_command, &opt_system_command, nullptr, GET_BOOL, NO_ARG, 0, 0,
2095+
0, nullptr, 0, nullptr},
20892096
{nullptr, 0, nullptr, nullptr, nullptr, nullptr, GET_NO_ARG, NO_ARG, 0, 0,
20902097
0, nullptr, 0, nullptr}};
20912098

@@ -4501,6 +4508,13 @@ static int com_shell(String *buffer [[maybe_unused]],
45014508
put_info("Usage: \\! shell-command", INFO_ERROR);
45024509
return -1;
45034510
}
4511+
4512+
if (!opt_system_command) {
4513+
return put_info(
4514+
"'system' command received, but the --system-command option is off. "
4515+
"Skipping.",
4516+
INFO_ERROR);
4517+
}
45044518
/*
45054519
The output of the shell command does not
45064520
get directed to the pager or the outfile

mysql-test/r/mysql.result

+10
Original file line numberDiff line numberDiff line change
@@ -603,5 +603,15 @@ what
603603
what
604604
8check if delimiter is restored
605605
# Cleanup
606+
#
607+
# Bug # 36377685: mysqldump blindly trusting SHOW CREATE TABLE leads to
608+
# arbitrary code execution.
609+
#
610+
# Test "system": Must return an error
611+
ERROR at line 1: 'system' command received, but the --system-command option is off. Skipping.
612+
# Test "!": Must return an error
613+
ERROR at line 1: 'system' command received, but the --system-command option is off. Skipping.
614+
# Test "system": Must pass
615+
Hello World
606616

607617
End of tests

mysql-test/t/mysql.test

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#
1+
2+
23
# Testing the MySQL command line client(mysql)
34
#
45

@@ -761,7 +762,21 @@ exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug35290350.sql;
761762
--echo # Cleanup
762763
remove_file $MYSQLTEST_VARDIR/tmp/bug35290350.sql;
763764

765+
--echo #
766+
--echo # Bug # 36377685: mysqldump blindly trusting SHOW CREATE TABLE leads to
767+
--echo # arbitrary code execution.
768+
--echo #
769+
770+
--echo # Test "system": Must return an error
771+
--error 1
772+
--exec $MYSQL test -e "system ls;" 2>&1
773+
774+
--echo # Test "!": Must return an error
775+
--error 1
776+
--exec $MYSQL test -e "\\! ls" 2>&1
764777

778+
--echo # Test "system": Must pass
779+
--exec $MYSQL test --system-command -e "system echo Hello World;" 2>&1
765780

766781
--echo
767782
--echo End of tests

mysql-test/t/mysql_system_cmd_unix.test

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
# Check that the mysql client's system command(\! in short) can execute
44
# commands on the command interpreter through which the client is invoked
55
# and that it can use the latter's STDIN, STDOUT and STDERR streams.
6-
--exec $MYSQL test -e "system echo From_system_to_STDOUT" 2>&1
7-
--exec $MYSQL test -e "\\! echo From_\\\\!_to_STDOUT" 2>&1
8-
--exec $MYSQL test -e "system echo From_system_to_STDERR >> /dev/stderr" 2>&1
9-
--exec $MYSQL test -e "\\! echo From_\\\\!_to_STDERR >> /dev/stderr" 2>&1
10-
--exec echo "From_STDIN_to_system" | $MYSQL test -e "system cat" 2>&1
11-
--exec echo "From_STDIN_to_\\!" | $MYSQL test -e "\\! cat" 2>&1
6+
--exec $MYSQL --system-command test -e "system echo From_system_to_STDOUT" 2>&1
7+
--exec $MYSQL --system-command test -e "\\! echo From_\\\\!_to_STDOUT" 2>&1
8+
--exec $MYSQL --system-command test -e "system echo From_system_to_STDERR >> /dev/stderr" 2>&1
9+
--exec $MYSQL --system-command test -e "\\! echo From_\\\\!_to_STDERR >> /dev/stderr" 2>&1
10+
--exec echo "From_STDIN_to_system" | $MYSQL test --system-command -e "system cat" 2>&1
11+
--exec echo "From_STDIN_to_\\!" | $MYSQL test --system-command -e "\\! cat" 2>&1

mysql-test/t/mysql_win32_system.test

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
--echo # WL#13391: Enable the "system" mysql command line command for windows
55
--echo #
66

7-
--exec $MYSQL test -e "system echo haha" 2>&1
8-
--exec $MYSQL test -e "\\! echo hihi" 2>&1
9-
--exec $MYSQL test -e "system rmdir \\"$MYSQL_TMP_DIR\\non_existent_dir\\"" 2>&1
7+
--exec $MYSQL test --system-command -e "system echo haha" 2>&1
8+
--exec $MYSQL test --system-command -e "\\! echo hihi" 2>&1
9+
--exec $MYSQL test --system-command -e "system rmdir \\"$MYSQL_TMP_DIR\\non_existent_dir\\"" 2>&1
1010

1111
--echo # End of 8.0 tests

0 commit comments

Comments
 (0)