List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:October 9 2006 8:20pm
Subject:bk commit into 4.1 tree (cmiller:1.2554) BUG#17583
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of cmiller. When cmiller does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-10-09 14:20:00-04:00, cmiller@stripped +3 -0
  Bug#17583: mysql drops connection when stdout is not writable
  
  When the client program had its stdout file descriptor closed by the calling
  shell, after some amount of work (enough to fill a socket buffer) the server 
  would complain about a packet error and then disconnect the client.
  
  This is a serious security problem.  If stdout is closed before the mysql is
  exec()d, then the first socket() call allocates file number 1 to communicate
  with the server.  Subsequent write()s to that file number (as when printing
  results that come back from the database) go back to the server instead in 
  the command channel.  So, one should be able to craft data which, upon being
  selected back from the server to the client, and injected into the command
  stream become valid MySQL protocol to do something nasty when sent /back/ to 
  the server.
  
  The solution is to re-open the file descriptor that we printf() to, as 
  pointing to a black-hole, which simulates what the user wanted and allows us
  to print our output there with impunity.

  client/mysql.cc@stripped, 2006-10-09 14:19:58-04:00, cmiller@stripped +24 -0
    If standard output is not open (specifically, if dup() fails) then reopen
    the stdout file descriptor to write to the system's black-hole pseudofile.

  mysql-test/r/mysql_client.result@stripped, 2006-10-09 14:19:59-04:00,
cmiller@stripped +14 -0
    Prove that the problem of writing SQL output to the command socket no longer
    exists.

  mysql-test/t/mysql_client.test@stripped, 2006-10-09 14:19:59-04:00,
cmiller@stripped +19 -0
    Prove that the problem of writing SQL output to the command socket no longer
    exists.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	cmiller
# Host:	zippy.cornsilk.net
# Root:	/home/cmiller/work/mysql/bug17583/my41-bug17583

--- 1.220/client/mysql.cc	2006-10-09 14:20:04 -04:00
+++ 1.221/client/mysql.cc	2006-10-09 14:20:04 -04:00
@@ -173,6 +173,12 @@ static char *shared_memory_base_name=0;
 static uint opt_protocol=0;
 static CHARSET_INFO *charset_info= &my_charset_latin1;
 
+#ifdef __WIN__
+static const char *null_pseudofile= "NUL";
+#else
+static const char *null_pseudofile= "/dev/null";
+#endif
+
 #include "sslopt-vars.h"
 
 const char *default_dbug_option="d:t:o,/tmp/mysql.trace";
@@ -372,6 +378,24 @@ int main(int argc,char *argv[])
   else
     status.add_to_history=1;
   status.exit_status=1;
+
+  {
+    /* Make sure that stdout is open.  Open it, if it's not already open. */
+    int stdout_fileno_copy;
+    stdout_fileno_copy= dup(STDOUT_FILENO);
+    if (stdout_fileno_copy == -1)
+    {
+      if (freopen(null_pseudofile, "w", stdout) == NULL)
+      {
+        fprintf(stderr, "Could not open %s for stdout.\n", null_pseudofile);
+        exit(1);
+      }
+      /* else, successfully opened stdout as black-hole. */
+    }
+    else
+      close(stdout_fileno_copy);  /* clean up dup() */
+  }
+
   load_defaults("my",load_default_groups,&argc,&argv);
   defaults_argv=argv;
   if (get_options(argc, (char **) argv))

--- 1.3/mysql-test/r/mysql_client.result	2006-10-09 14:20:04 -04:00
+++ 1.4/mysql-test/r/mysql_client.result	2006-10-09 14:20:04 -04:00
@@ -2,3 +2,17 @@
 1
 ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '' at line 1
 ERROR at line 1: USE must be followed by a database name
+create table t17583 (a int);
+insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+select count(*) from t17583;
+count(*)
+1280
+drop table t17583;
+End of 4.1 tests.

--- 1.3/mysql-test/t/mysql_client.test	2006-10-09 14:20:04 -04:00
+++ 1.4/mysql-test/t/mysql_client.test	2006-10-09 14:20:04 -04:00
@@ -33,3 +33,22 @@
 #
 --exec echo 'help' | $MYSQL   >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
 --exec echo 'help ' | $MYSQL  >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
+
+#
+# Bug#17583: mysql drops connection when stdout is not writable
+#
+create table t17583 (a int);
+insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+insert into t17583 select a from t17583;
+# Close to the minimal data needed to exercise bug.
+select count(*) from t17583;
+--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; select count(*) from t17583; select count(*) from t17583; select count(*)
from t17583; " |$MYSQL test >&-
+drop table t17583;
+
+--echo End of 4.1 tests.
Thread
bk commit into 4.1 tree (cmiller:1.2554) BUG#17583Chad MILLER9 Oct