]> xenbits.xensource.com Git - libvirt.git/commitdiff
Remove & ban use of select() for waiting for I/O
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 13 May 2013 13:43:20 +0000 (14:43 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 13 May 2013 16:32:43 +0000 (17:32 +0100)
Use of the select() system call is inherantly dangerous since
applications will hit a buffer overrun if any FD number exceeds
the size of the select set size (typically 1024). Replace the
two uses of select() with poll() and use cfg.mk to ban any
future use of select().

NB: This changes the phyp driver so that it uses an infinite
timeout, instead of busy-waiting for 1ms at a time.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
cfg.mk
src/phyp/phyp_driver.c
src/util/virnetlink.c

diff --git a/cfg.mk b/cfg.mk
index 0bf5bfc1b629b65cd70a8124c43a3593674a292d..bb93c6abb9455cd36b18dee859d226b22be015aa 100644 (file)
--- a/cfg.mk
+++ b/cfg.mk
@@ -444,6 +444,11 @@ sc_prohibit_nonreentrant:
        done ; \
        exit $$fail
 
+sc_prohibit_select:
+       @prohibit="\\<select *\\("                                      \
+       halt="use poll(), not se""lect()"                               \
+         $(_sc_search_regexp)
+
 # Prohibit the inclusion of <ctype.h>.
 sc_prohibit_ctype_h:
        @prohibit='^# *include  *<ctype\.h>'                            \
index f0007c08a08229290a92d1c8cef292cae31579e1..4594cbf22e84ddadd771dd988149aeb317c1e5ee 100644 (file)
@@ -40,6 +40,7 @@
 #include <netdb.h>
 #include <fcntl.h>
 #include <domain_event.h>
+#include <poll.h>
 
 #include "internal.h"
 #include "virauth.h"
@@ -72,29 +73,22 @@ static unsigned const int PHYP_MAC_SIZE= 12;
 static int
 waitsocket(int socket_fd, LIBSSH2_SESSION * session)
 {
-    struct timeval timeout;
-    fd_set fd;
-    fd_set *writefd = NULL;
-    fd_set *readfd = NULL;
+    struct pollfd fds[1];
     int dir;
 
-    timeout.tv_sec = 0;
-    timeout.tv_usec = 1000;
-
-    FD_ZERO(&fd);
-
-    FD_SET(socket_fd, &fd);
+    memset(fds, 0, sizeof(fds));
+    fds[0].fd = socket_fd;
 
     /* now make sure we wait in the correct direction */
     dir = libssh2_session_block_directions(session);
 
     if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
-        readfd = &fd;
+        fds[0].events |= POLLIN;
 
     if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
-        writefd = &fd;
+        fds[0].events |= POLLOUT;
 
-    return select(socket_fd + 1, readfd, writefd, NULL, &timeout);
+    return poll(fds, ARRAY_CARDINALITY(fds), -1);
 }
 
 /* this function is the layer that manipulates the ssh channel itself
index d340eda39a108191cbc93c7cd254bc662a7bad61..b2ba9df5485a0664bb96db05bee40e4dd900fe71 100644 (file)
@@ -48,7 +48,7 @@
 
 #define VIR_FROM_THIS VIR_FROM_NET
 
-#define NETLINK_ACK_TIMEOUT_S  2
+#define NETLINK_ACK_TIMEOUT_S  (2*1000)
 
 #if defined(__linux__) && defined(HAVE_LIBNL)
 /* State for a single netlink event handle */
@@ -185,10 +185,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
             .nl_groups = 0,
     };
     ssize_t nbytes;
-    struct timeval tv = {
-        .tv_sec = NETLINK_ACK_TIMEOUT_S,
-    };
-    fd_set readfds;
+    struct pollfd fds[1];
     int fd;
     int n;
     struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
@@ -242,14 +239,15 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
         goto error;
     }
 
-    FD_ZERO(&readfds);
-    FD_SET(fd, &readfds);
+    memset(fds, 0, sizeof(fds));
+    fds[0].fd = fd;
+    fds[0].events = POLLIN;
 
-    n = select(fd + 1, &readfds, NULL, NULL, &tv);
+    n = poll(fds, ARRAY_CARDINALITY(fds), NETLINK_ACK_TIMEOUT_S);
     if (n <= 0) {
         if (n < 0)
             virReportSystemError(errno, "%s",
-                                 _("error in select call"));
+                                 _("error in poll call"));
         if (n == 0)
             virReportSystemError(ETIMEDOUT, "%s",
                                  _("no valid netlink response was received"));