summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.cornsilk.net>2006-10-09 18:28:06 -0400
committerunknown <cmiller@zippy.cornsilk.net>2006-10-09 18:28:06 -0400
commit76b353d307a3037e52c309169be644b47655ea0e (patch)
tree1c006a0b771d0d2c43b7ee794ab93d6fc8de48ae /client
parentdc62ff5560fcd8596cba19b767cfb39396309d4f (diff)
downloadmariadb-git-76b353d307a3037e52c309169be644b47655ea0e.tar.gz
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 close explicitly the file descriptor that we *printf() to, so that the libc layer and the OS layer both agree that the file is closed. BitKeeper/etc/collapsed: BitKeeper file /home/cmiller/work/mysql/bug17583/my41-bug17583/BitKeeper/etc/collapsed client/mysql.cc: If standard output is not open (specifically, if dup() of its file number fails) then we explicitly close it so that future uses of the file descriptor behave correctly for a closed file. mysql-test/r/mysql_client.result: Prove that the problem of writing SQL output to the command socket no longer exists. mysql-test/t/mysql_client.test: Prove that the problem of writing SQL output to the command socket no longer exists.
Diffstat (limited to 'client')
-rw-r--r--client/mysql.cc15
1 files changed, 15 insertions, 0 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index f9ca9d4f829..12fa2b56ebf 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -372,6 +372,21 @@ int main(int argc,char *argv[])
else
status.add_to_history=1;
status.exit_status=1;
+
+ {
+ /*
+ The file descriptor-layer may be out-of-sync with the file-number layer,
+ so we make sure that "stdout" is really open. If its file is closed then
+ explicitly close the FD layer.
+ */
+ int stdout_fileno_copy;
+ stdout_fileno_copy= dup(fileno(stdout)); /* Okay if fileno fails. */
+ if (stdout_fileno_copy == -1)
+ fclose(stdout);
+ 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))