From 77c4c0f256f3c268d3f72625b04240d24a70513c Mon Sep 17 00:00:00 2001
From: Oleksandr Byelkin <sanja@mariadb.com>
Date: Fri, 7 Jun 2024 12:13:21 +0200
Subject: [PATCH] MDEV-34203 Sandbox mode \- is not compatible with 
 --binary-mode

"Process" sandbox short command put by masqldump to avoid an error.

CVE: CVE-2024-21096
Upstream-Status: Backport [https://github.com/MariaDB/server/commit/77c4c0f256f3c268d3f72625b04240d24a70513c]

Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
 client/mysql.cc              | 30 +++++++++++++++++++++++++-----
 mysql-test/main/mysql.result | 11 +++++++++++
 mysql-test/main/mysql.test   | 16 ++++++++++++++++
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/client/mysql.cc b/client/mysql.cc
index 10f25966..0bb56510 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1112,6 +1112,8 @@ inline int get_command_index(char cmd_char)
 
 static int delimiter_index= -1;
 static int charset_index= -1;
+static int sandbox_index= -1;
+
 static bool real_binary_mode= FALSE;
 
 
@@ -1122,7 +1124,8 @@ int main(int argc,char *argv[])
   MY_INIT(argv[0]);
   DBUG_ENTER("main");
   DBUG_PROCESS(argv[0]);
-  
+
+  sandbox_index= get_command_index('-');
   charset_index= get_command_index('C');
   delimiter_index= get_command_index('d');
   delimiter_str= delimiter;
@@ -2237,8 +2240,9 @@ static int read_and_execute(bool interactive)
 
 /**
    It checks if the input is a short form command. It returns the command's
-   pointer if a command is found, else return NULL. Note that if binary-mode
-   is set, then only \C is searched for.
+   pointer if a command is found, else return NULL.
+
+   Note that if binary-mode is set, then only \C and \- are searched for.
 
    @param cmd_char    A character of one byte.
 
@@ -2253,13 +2257,23 @@ static COMMANDS *find_command(char cmd_char)
   int index= -1;
 
   /*
-    In binary-mode, we disallow all mysql commands except '\C'
-    and DELIMITER.
+    In binary-mode, we disallow all client commands except '\C'
+    DELIMITER (see long comand finding find_command(char *))
+    and  '\-' (sandbox, see following comment).
   */
   if (real_binary_mode)
   {
     if (cmd_char == 'C')
       index= charset_index;
+    /*
+       binary-mode enforces stricter controls compared to sandbox mode.
+       Whether sandbox mode is enabled or not is irrelevant when
+       binary-mode is active.
+       The only purpose of processing sandbox mode here is to avoid error
+       messages on files made by mysqldump.
+    */
+    else if (cmd_char == '-')
+      index= sandbox_index;
   }
   else
     index= get_command_index(cmd_char);
@@ -2315,6 +2329,12 @@ static COMMANDS *find_command(char *name)
     len= (uint) strlen(name);
 
   int index= -1;
+  /*
+    In binary-mode, we disallow all client commands except DELIMITER
+    and short commands '\C' and  '\-' (see short command finding
+    find_command(char)).
+  */
+
   if (real_binary_mode)
   {
     if (is_delimiter_command(name, len))
diff --git a/mysql-test/main/mysql.result b/mysql-test/main/mysql.result
index c2e42fda..b983f009 100644
--- a/mysql-test/main/mysql.result
+++ b/mysql-test/main/mysql.result
@@ -639,3 +639,14 @@ drop table t1;
 WARNING: option '--enable-cleartext-plugin' is obsolete.
 1
 1
+#
+# MDEV-34203: Sandbox mode \- is not compatible with --binary-mode
+#
+create table t1 (a int);
+drop table t1;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+drop table t1;
diff --git a/mysql-test/main/mysql.test b/mysql-test/main/mysql.test
index 0f41add8..553398fd 100644
--- a/mysql-test/main/mysql.test
+++ b/mysql-test/main/mysql.test
@@ -716,3 +716,19 @@ drop table t1;
 #
 --echo
 --exec $MYSQL test --enable-cleartext-plugin -e "select 1"
+
+--echo #
+--echo # MDEV-34203: Sandbox mode \- is not compatible with --binary-mode
+--echo #
+
+create table t1 (a int);
+
+--exec $MYSQL_DUMP test t1 > $MYSQLTEST_VARDIR/tmp/MDEV-34203.sql
+
+drop table t1;
+
+--exec $MYSQL --binary-mode test 2>&1 < $MYSQLTEST_VARDIR/tmp/MDEV-34203.sql
+
+show create table t1;
+drop table t1;
+--remove_file $MYSQLTEST_VARDIR/tmp/MDEV-34203.sql
-- 
2.40.0

