[DRE-maint] Bug#770891: ruby-mysql2: possible openssl infinite loop

Cédric Boutillier boutil at debian.org
Mon Nov 24 23:04:08 UTC 2014


Package: ruby-mysql2
Severity: important
Tags: patch upstream

Hi,

Currently, the dummy socket used to absorb wirtes in invalidate_fd
function may not absorb all writes and yield an infinite openssl loop.

This can be avoided, by replacing the dummy socket with /dev/null, as
proposed in upstream commit:

fc30a7c056e63517f5f66702016941b3902ec0b6
    Use /dev/null in invalidate_fd to avoid infinite loop in OpenSSL

Reproduced below:

------8<------------------

    Use /dev/null in invalidate_fd to avoid infinite loop in OpenSSL

    Thanks to Andy Bakun / @thwarted for identifying the issue and
    suggesting the /dev/null workaround.
---
 ext/mysql2/client.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c
index 71a7a35..3743d93 100644
--- a/ext/mysql2/client.c
+++ b/ext/mysql2/client.c
@@ -169,26 +169,30 @@ static void *nogvl_connect(void *ptr) {

 #ifndef _WIN32
 /*
- * Redirect clientfd to a dummy socket for mysql_close to
- * write, shutdown, and close on as a no-op.
- * We do this hack because we want to call mysql_close to release
- * memory, but do not want mysql_close to drop connections in the
- * parent if the socket got shared in fork.
+ * Redirect clientfd to /dev/null for mysql_close and SSL_close to write,
+ * shutdown, and close. The hack is needed to prevent shutdown() from breaking
+ * a socket that may be in use by the parent or other processes after fork.
+ *
+ * /dev/null is used to absorb writes; previously a dummy socket was used, but
+ * it could not abosrb writes and caused openssl to go into an infinite loop.
+ *
  * Returns Qtrue or Qfalse (success or failure)
+ *
+ * Note: if this function is needed on Windows, use "nul" instead of "/dev/null"
  */
 static VALUE invalidate_fd(int clientfd)
 {
 #ifdef SOCK_CLOEXEC
   /* Atomically set CLOEXEC on the new FD in case another thread forks */
-  int sockfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+  int sockfd = open("/dev/null", O_RDWR | O_CLOEXEC);
   if (sockfd < 0) {
     /* Maybe SOCK_CLOEXEC is defined but not available on this kernel */
-    int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+    int sockfd = open("/dev/null", O_RDWR);
     fcntl(sockfd, F_SETFD, FD_CLOEXEC);
   }
 #else
   /* Well we don't have SOCK_CLOEXEC, so just set FD_CLOEXEC quickly */
-  int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+  int sockfd = open("/dev/null", O_RDWR);
   fcntl(sockfd, F_SETFD, FD_CLOEXEC);
 #endif

----------------------------8<-----------------------

-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (990, 'unstable'), (500, 'testing'), (100, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.alioth.debian.org/pipermail/pkg-ruby-extras-maintainers/attachments/20141125/650d364b/attachment.sig>


More information about the Pkg-ruby-extras-maintainers mailing list