]> granicus.if.org Git - python/commitdiff
Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is
authorCharles-François Natali <neologix@free.fr>
Sun, 28 Aug 2011 14:22:33 +0000 (16:22 +0200)
committerCharles-François Natali <neologix@free.fr>
Sun, 28 Aug 2011 14:22:33 +0000 (16:22 +0200)
greater than FD_SETSIZE.

Include/fileobject.h
Misc/NEWS
Modules/_ssl.c
Modules/ossaudiodev.c
Modules/selectmodule.c
Modules/socketmodule.c

index ba506ec0b398747ba9ad491e4238374f323936a0..86ade5a1ac98350bae8cb098a49e9e741bc4eedd 100644 (file)
@@ -84,6 +84,15 @@ int _PyVerify_fd(int fd);
 #define _PyVerify_fd(A) (1) /* dummy */
 #endif
 
+#ifdef HAVE_SELECT
+/* A routine to check if a file descriptor can be select()-ed. */
+#ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
+ #define _PyIsSelectable_fd(FD) (1)
+#else
+ #define _PyIsSelectable_fd(FD) (((FD) >= 0) && ((FD) < FD_SETSIZE))
+#endif
+#endif /* HAVE_SELECT */
+
 #ifdef __cplusplus
 }
 #endif
index 3709142c8fed40eebc18938d4061d22e10b31f1a..204e9ee7fed1331f5314ec3a89754661b29557a1 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -40,6 +40,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is
+  greater than FD_SETSIZE.
+
 - Issue #12839: Fix crash in zlib module due to version mismatch.
   Fix by Richard M. Tew.
 
index 5af5bdeb70f79c624211ebae3de63e64f90a0c2b..80b661f93d3614337cd1842111220155fe71587b 100644 (file)
@@ -1145,10 +1145,8 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
 #endif
 
     /* Guard against socket too large for select*/
-#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
-    if (s->sock_fd >= FD_SETSIZE)
+    if (!_PyIsSelectable_fd(s->sock_fd))
         return SOCKET_TOO_LARGE_FOR_SELECT;
-#endif
 
     /* Construct the arguments to select */
     tv.tv_sec = (int)s->sock_timeout;
index ebf101a2008f24bdab11b34907be2088a24bc2e8..b3dfa6256314babb33a9accb27662af7529429e8 100644 (file)
@@ -425,6 +425,11 @@ oss_writeall(oss_audio_t *self, PyObject *args)
     if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
         return NULL;
 
+    if (!_PyIsSelectable_fd(self->fd)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "file descriptor out of range for select");
+        return NULL;
+    }
     /* use select to wait for audio device to be available */
     FD_ZERO(&write_set_fds);
     FD_SET(self->fd, &write_set_fds);
index ac604b6045453bf2d629e248f5e64fadfc2c92df..5a8580c8ac92381ed367ba9bd0013f9dd1be2e37 100644 (file)
@@ -114,7 +114,7 @@ seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
 #if defined(_MSC_VER)
         max = 0;                             /* not used for Win32 */
 #else  /* !_MSC_VER */
-        if (v < 0 || v >= FD_SETSIZE) {
+        if (!_PyIsSelectable_fd(v)) {
             PyErr_SetString(PyExc_ValueError,
                         "filedescriptor out of range in select()");
             goto finally;
@@ -164,13 +164,6 @@ set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
     for (j = 0; fd2obj[j].sentinel >= 0; j++) {
         fd = fd2obj[j].fd;
         if (FD_ISSET(fd, set)) {
-#ifndef _MSC_VER
-            if (fd > FD_SETSIZE) {
-                PyErr_SetString(PyExc_SystemError,
-               "filedescriptor out of range returned in select()");
-                goto finally;
-            }
-#endif
             o = fd2obj[j].obj;
             fd2obj[j].obj = NULL;
             /* transfer ownership */
index 694259b244a828e707cd2aff9ea8056b25b29a8d..279a09079a89198e81568620fa3e2c71f0bd814c 100644 (file)
@@ -456,18 +456,14 @@ static PyTypeObject sock_type;
 #include <sys/poll.h>
 #endif
 
-#ifdef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
-/* Platform can select file descriptors beyond FD_SETSIZE */
-#define IS_SELECTABLE(s) 1
-#elif defined(HAVE_POLL)
+#ifdef HAVE_POLL
 /* Instead of select(), we'll use poll() since poll() works on any fd. */
 #define IS_SELECTABLE(s) 1
 /* Can we call select() with this socket without a buffer overrun? */
 #else
-/* POSIX says selecting file descriptors beyond FD_SETSIZE
-   has undefined behaviour.  If there's no timeout left, we don't have to
-   call select, so it's a safe, little white lie. */
-#define IS_SELECTABLE(s) ((s)->sock_fd < FD_SETSIZE || s->sock_timeout <= 0.0)
+/* If there's no timeout left, we don't have to call select, so it's a safe,
+ * little white lie. */
+#define IS_SELECTABLE(s) (_PyIsSelectable_fd((s)->sock_fd) || (s)->sock_timeout <= 0.0)
 #endif
 
 static PyObject*