Bug #17583 mysql drops connection when stdout is not writable
Submitted: 20 Feb 2006 13:25 Modified: 10 Nov 2006 20:32
Reporter: Marko Mäkelä Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Command-line Clients Severity:S3 (Non-critical)
Version:4.1, 5.0, 5.1 OS:Linux (GNU/Linux)
Assigned to: Chad MILLER CPU Architecture:Any

[20 Feb 2006 13:25] Marko Mäkelä
Description:
I tried a stress test (repeated SELECT COUNT(*) from a table containing 10,000 records). To my surprise, the client would complain:

ERROR 2013 (HY000) at line 70: Lost connection to MySQL server during query

The server would complain:

Packets out of order (Found: 110, expected 0)

How to repeat:
perl -e 'print "create table t(a int)engine=innodb;\n;insert into t values (0)";for($i=1;$i<10000;$i++){print ",\n($i)"}print ";\n"'|mysql test
yes "select count(*) from t;"|mysql test >&-

Observe that the connection is broken after some time. Then try the following, which works:

yes "select count(*) from t;"|mysql test >/dev/null

Suggested fix:
Make the clients complain (to stderr) when stdout does not exist.
[20 Feb 2006 15:43] Jorge del Conde
I was able to reproduce this under FC4 with the attached test case
[27 Mar 2006 15:14] Konstantin Osipov
This might indicate a bug in  the command line client, perhaps a buffer overflow. Brian, could you please reconsider the assignment?
[9 Oct 2006 18:20] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/13352

ChangeSet@1.2554, 2006-10-09 14:20:00-04:00, cmiller@zippy.cornsilk.net +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.
[9 Oct 2006 22:28] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/13360

ChangeSet@1.2554, 2006-10-09 18:28:06-04:00, cmiller@zippy.cornsilk.net +4 -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 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.
[9 Oct 2006 22:50] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/13362

ChangeSet@1.2296, 2006-10-09 18:50:12-04:00, cmiller@zippy.cornsilk.net +2 -0
  Bug#17583: mysql drops connection when stdout is not writable
  
  Porting forward tests to replacement files.
[9 Oct 2006 22:59] Chad MILLER
Sent to mysql-{4.1,5.0,5.1}-maint trees.
[10 Nov 2006 20:32] Paul Dubois
Noted in 4.1.23, 5.0.30 (not 5.0.29), 5.1.13 changelogs.

mysql would lose its connection to the server if its standard output
was not writable.