Commits

xleroy  committed 6f58399

PR#5563: harden Unix.select against file descriptors above FD_SETSIZE
(Picked from r12947 in 4.00 branch)

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@12948f963ae5c-01c2-4b8c-9fe0-0dff7051ff02

  • Participants
  • Parent commits 3617cef

Comments (0)

Files changed (2)

 
 Bug fixes:
 - PR#4019: better documentation of Str.matched_string
+- PR#5563: harden Unix.select against file descriptors above FD_SETSIZE
 - PR#5700: crash with native-code stack backtraces under MacOS 10.8 x86-64
 - PR#5707: AMD64 code generator: do not use r10 and r11 for parameter passing,
   as these registers can be destroyed by the dynamic loader

File otherlibs/unix/select.c

 #endif
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 
-typedef fd_set file_descr_set;
-
-static void fdlist_to_fdset(value fdlist, fd_set *fdset, int *maxfd)
+static int fdlist_to_fdset(value fdlist, fd_set *fdset, int *maxfd)
 {
   value l;
   FD_ZERO(fdset);
   for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
-    int fd = Int_val(Field(l, 0));
-    FD_SET(fd, fdset);
+    long fd = Long_val(Field(l, 0));
+    /* PR#5563: harden against bad fds */
+    if (fd < 0 || fd >= FD_SETSIZE) return -1;
+    FD_SET((int) fd, fdset);
     if (fd > *maxfd) *maxfd = fd;
   }
+  return 0;
 }
 
 static value fdset_to_fdlist(value fdlist, fd_set *fdset)
 
   Begin_roots3 (readfds, writefds, exceptfds);
     maxfd = -1;
-    fdlist_to_fdset(readfds, &read, &maxfd);
-    fdlist_to_fdset(writefds, &write, &maxfd);
-    fdlist_to_fdset(exceptfds, &except, &maxfd);
+    retcode  = fdlist_to_fdset(readfds, &read, &maxfd);
+    retcode += fdlist_to_fdset(writefds, &write, &maxfd);
+    retcode += fdlist_to_fdset(exceptfds, &except, &maxfd);
+    /* PR#5563: if a bad fd was encountered, report EINVAL error */
+    if (retcode != 0) unix_error(EINVAL, "select", Nothing);
     tm = Double_val(timeout);
     if (tm < 0.0)
       tvp = (struct timeval *) NULL;