Bug #33831 mysql_real_connect() connects again if given an already connected MYSQL handle
Submitted: 12 Jan 2008 15:13 Modified: 12 Nov 2009 18:34
Reporter: Hartmut Holzgraefe Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S3 (Non-critical)
Version:5.1.22 OS:Linux
Assigned to: Magne Mæhre CPU Architecture:Any
Tags: libmysql, mysql_real_connect

[12 Jan 2008 15:13] Hartmut Holzgraefe
Description:
Originally reported in the PHP bug system as http://bugs.php.net/39457

It is possible to connect to the server twice using a code snippet like:

  MYSQL mysql;

  mysql_init(&mysql);
  mysql_real_connect(&mysql, "127.0.0.1", "root", "", "test", 3306, NULL, 0);
  mysql_real_connect(&mysql, "127.0.0.1", "root", "", "test", 3306, NULL, 0);
  mysql_close(&mysql);

Both mysql_real_connect() calls will report success and after the 2nd call you'll indeed see a 2nd connection in SHOW PROCESSLIST, mysql_close() will only close the later connection though. So if the program keeps running after the mysql_close() the connection established by the first mysql_real_connect() will be hanging around as long as the program runs with no clean way to terminate it as the MYSQL handle got overwritten by the 2nd mysql_real_connect() call.

This also affects PHP ext/mysqli mysqli_real_connect() (and was originally reported as PHP bug only). In this context it is a DOS attack vector on shared hosts running PHP as apache module as the stale connections will persist as long as the apache process. So the mysql connection resource leak can be abused to consume all connection slots on the associated mysql server.

How to repeat:
See attached test program or http://bugs.php.net/39457 for the PHP aspect of this bug

Suggested fix:
Let mysql_real_connect() check for an already existing connection first and refuse to connect a second time, returning an appropriate error code instead.
[12 Jan 2008 15:23] Hartmut Holzgraefe
test project source

Attachment: bug33831-0.1.tar.gz (application/x-gzip, text), 293.00 KiB.

[12 Jan 2008 15:27] Hartmut Holzgraefe
Compile and run the attached application source project,
it will use real_connect() once, print the connection ID,
then it will real_connect() again successfully without 
warnings and will print the new connection ID it is now
attached to.

After that it will sleep 60 seconds, check SHOW PROCESSLIST
and you'll see that both connection ids are shown as connected.

Then it will mysql_close() and sleep again, check SHOW PROCESSLIST
again to see that the first connection is still active even though
there is no way for the application to still access it though.

Only when the process finally terminates the original connection
vanishes, too.
[14 Jul 2008 17:49] Sveta Smirnova
Bug #38107 was marked as duplicate of this one.
[10 Oct 2008 11:11] 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/56016

2728 Magne Mahre	2008-10-10
      Fix for bug# 33831
      Added a new error message to indicate that the session is already connected.
[16 Oct 2008 10:14] 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/56346

2728 Magne Mahre	2008-10-16
      Fixed Bug#33831 mysql_real_connect() connects again if given an
      already connected MYSQL handle.
[17 Oct 2008 12:40] 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/56468

2733 Magne Mahre	2008-10-17
      Fixed Bug#33831 mysql_real_connect() connects again if given an
      already connected MYSQL handle.
[17 Oct 2008 12:48] Magne Mæhre
Added a new possible error message to mysql_real_connect(...).  Will need to be documented in the C API documentation.
[24 Oct 2008 1:18] Bugs System
Pushed into 6.0.8-alpha  (revid:magne.mahre@sun.com-20081017123934-zo8t7bh19bdn5co6) (version source revid:kostja@sun.com-20081017141621-r9le3w1fuylwgsbw) (pib:5)
[26 Oct 2008 0:40] Paul DuBois
Noted in 6.0.8 changelog.

mysql_real_connect() did not check whether the MYSQL connection
handler was already connected and connected again even if so. Now an
CR_ALREADY_CONNECTED error occurs. 

Setting report to NDI pending push into 5.1.x.
[18 Dec 2008 19:40] Jim Winstead
This change won't be pushed into 5.1.
[9 Oct 2009 12:34] 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/86345

2894 Magne Mahre	2009-10-09
      Bug #33831 mysql_real_connect() connects again if 
                 given an already connected MYSQL handle
      
      mysql_real_connect() did not check whether the MYSQL connection
      handler was already connected and connected again even if so. 
      Now a CR_ALREADY_CONNECTED error is returned.
[9 Oct 2009 12:36] Magne Mæhre
Pushed into 5.5.0
[10 Oct 2009 0:06] Paul DuBois
Noted in 5.5.0 changelog.
[3 Nov 2009 7:16] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091102151658-j9o4wgro47m5v84d) (version source revid:dlenev@mysql.com-20091009152620-weybanb3xbbxxs6h) (merge vers: 6.0.14-alpha) (pib:13)
[3 Nov 2009 15:13] Paul DuBois
Already fixed in earlier 6.0.x release.
[12 Nov 2009 8:16] Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091110093229-0bh5hix780cyeicl) (version source revid:mikael@mysql.com-20091103113702-p61dlwc6ml6fxg18) (merge vers: 5.5.0-beta) (pib:13)