Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is

greater than FD_SETSIZE.
This commit is contained in:
Charles-François Natali 2011-08-28 16:22:33 +02:00
parent bbabbae114
commit fda7b379ac
6 changed files with 23 additions and 19 deletions

View 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

View file

@ -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.

View 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;

View 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);

View 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 */

View 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*