1c550d
Description: fix CVE-2012-6687 in bundled libfcgi
1c550d
Origin: https://bugs.launchpad.net/ubuntu/+source/libfcgi/+bug/933417
1c550d
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815840
1c550d
Forwarded: https://rt.cpan.org/Ticket/Display.html?id=118405
1c550d
1c550d
--- a/os_unix.c
1c550d
+++ b/os_unix.c
1c550d
@@ -36,6 +36,7 @@
1c550d
 #include <sys/time.h>
1c550d
 #include <sys/un.h>
1c550d
 #include <signal.h>
1c550d
+#include <poll.h>
1c550d
 
1c550d
 #ifdef HAVE_NETDB_H
1c550d
 #include <netdb.h>
1c550d
@@ -97,6 +98,9 @@
1c550d
 static int shutdownPending = FALSE;
1c550d
 static int shutdownNow = FALSE;
1c550d
 
1c550d
+static int libfcgiOsClosePollTimeout = 2000;
1c550d
+static int libfcgiIsAfUnixKeeperPollTimeout = 2000;
1c550d
+
1c550d
 void OS_ShutdownPending()
1c550d
 {
1c550d
     shutdownPending = TRUE;
1c550d
@@ -162,6 +166,16 @@
1c550d
     if(libInitialized)
1c550d
         return 0;
1c550d
 
1c550d
+    char *libfcgiOsClosePollTimeoutStr = getenv( "LIBFCGI_OS_CLOSE_POLL_TIMEOUT" );
1c550d
+    if(libfcgiOsClosePollTimeoutStr) {
1c550d
+        libfcgiOsClosePollTimeout = atoi(libfcgiOsClosePollTimeoutStr);
1c550d
+    }
1c550d
+
1c550d
+    char *libfcgiIsAfUnixKeeperPollTimeoutStr = getenv( "LIBFCGI_IS_AF_UNIX_KEEPER_POLL_TIMEOUT" );
1c550d
+    if(libfcgiIsAfUnixKeeperPollTimeoutStr) {
1c550d
+        libfcgiIsAfUnixKeeperPollTimeout = atoi(libfcgiIsAfUnixKeeperPollTimeoutStr);
1c550d
+    }
1c550d
+
1c550d
     asyncIoTable = (AioInfo *)malloc(asyncIoTableSize * sizeof(AioInfo));
1c550d
     if(asyncIoTable == NULL) {
1c550d
         errno = ENOMEM;
1c550d
@@ -751,19 +765,16 @@
1c550d
     {
1c550d
         if (shutdown(fd, 1) == 0)
1c550d
         {
1c550d
-            struct timeval tv;
1c550d
-            fd_set rfds;
1c550d
+            struct pollfd pfd;
1c550d
             int rv;
1c550d
             char trash[1024];
1c550d
 
1c550d
-            FD_ZERO(&rfds);
1c550d
+            pfd.fd = fd;
1c550d
+            pfd.events = POLLIN;
1c550d
 
1c550d
             do 
1c550d
             {
1c550d
-                FD_SET(fd, &rfds);
1c550d
-                tv.tv_sec = 2;
1c550d
-                tv.tv_usec = 0;
1c550d
-                rv = select(fd + 1, &rfds, NULL, NULL, &tv;;
1c550d
+                rv = poll(&pfd, 1, libfcgiOsClosePollTimeout);
1c550d
             }
1c550d
             while (rv > 0 && read(fd, trash, sizeof(trash)) > 0);
1c550d
         }
1c550d
@@ -1113,13 +1124,11 @@
1c550d
  */
1c550d
 static int is_af_unix_keeper(const int fd)
1c550d
 {
1c550d
-    struct timeval tval = { READABLE_UNIX_FD_DROP_DEAD_TIMEVAL };
1c550d
-    fd_set read_fds;
1c550d
-
1c550d
-    FD_ZERO(&read_fds);
1c550d
-    FD_SET(fd, &read_fds);
1c550d
+    struct pollfd pfd;
1c550d
+    pfd.fd = fd;
1c550d
+    pfd.events = POLLIN;
1c550d
 
1c550d
-    return select(fd + 1, &read_fds, NULL, NULL, &tval) >= 0 && FD_ISSET(fd, &read_fds);
1c550d
+    return poll(&pfd, 1, libfcgiIsAfUnixKeeperPollTimeout) >= 0 && (pfd.revents & POLLIN);
1c550d
 }
1c550d
 
1c550d
 /*