From: Charles-François Natali Date: Sun, 28 Aug 2011 14:22:33 +0000 (+0200) Subject: Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is X-Git-Tag: v2.7.3rc1~483 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fda7b379acde3ad60bbd42acb6da7e7099d25133;p=python Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is greater than FD_SETSIZE. --- diff --git a/Include/fileobject.h b/Include/fileobject.h index ba506ec0b3..86ade5a1ac 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -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 diff --git a/Misc/NEWS b/Misc/NEWS index 3709142c8f..204e9ee7fe 100644 --- 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. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 5af5bdeb70..80b661f93d 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -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; diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index ebf101a200..b3dfa62563 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -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); diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index ac604b6045..5a8580c8ac 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -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 */ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 694259b244..279a09079a 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -456,18 +456,14 @@ static PyTypeObject sock_type; #include #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*