(original) (raw)

changeset: 103380:0a52c66f31f5 user: Christian Heimes christian@python.org date: Fri Sep 09 00:28:57 2016 +0200 files: Modules/socketmodule.c description: Issue 18550: Check return value of ioctl() / fnctl() in internal_setblocking The function internal_setblocking() of the socket module did not check the return values of ioctl() and fnctl(). CID 1294328 diff -r 4af9d196cd21 -r 0a52c66f31f5 Modules/socketmodule.c --- a/Modules/socketmodule.c Fri Sep 09 00:25:03 2016 +0200 +++ b/Modules/socketmodule.c Fri Sep 09 00:28:57 2016 +0200 @@ -640,24 +640,35 @@ #ifndef MS_WINDOWS #if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)) block = !block; - ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block); + if (ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block) == -1) + goto error; #else delay_flag = fcntl(s->sock_fd, F_GETFL, 0); + if (delay_flag == -1) + goto error; if (block) new_delay_flag = delay_flag & (~O_NONBLOCK); else new_delay_flag = delay_flag | O_NONBLOCK; if (new_delay_flag != delay_flag) - fcntl(s->sock_fd, F_SETFL, new_delay_flag); + if (fcntl(s->sock_fd, F_SETFL, new_delay_flag) == -1) + goto error; #endif #else /* MS_WINDOWS */ arg = !block; - ioctlsocket(s->sock_fd, FIONBIO, &arg); + if (ioctlsocket(s->sock_fd, FIONBIO, &arg) != 0) + goto error; #endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS - /* Since these don't return anything */ - return 1; + return 0; + error: +#ifndef MS_WINDOWS + PyErr_SetFromErrno(PyExc_OSError); +#else + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); +#endif + return -1; } static int @@ -905,7 +916,7 @@ /* Default timeout for new sockets */ static _PyTime_t defaulttimeout = _PYTIME_FROMSECONDS(-1); -static void +static int init_sockobject(PySocketSockObject *s, SOCKET_T fd, int family, int type, int proto) { @@ -922,10 +933,13 @@ #endif { s->sock_timeout = defaulttimeout; - if (defaulttimeout >= 0) - internal_setblocking(s, 0); - } - + if (defaulttimeout >= 0) { + if (internal_setblocking(s, 0) == -1) { + return -1; + } + } + } + return 0; } @@ -940,8 +954,12 @@ PySocketSockObject *s; s = (PySocketSockObject *) PyType_GenericNew(&sock_type, NULL, NULL); - if (s != NULL) - init_sockobject(s, fd, family, type, proto); + if (s == NULL) + return NULL; + if (init_sockobject(s, fd, family, type, proto) == -1) { + Py_DECREF(s); + return NULL; + } return s; } @@ -2423,10 +2441,10 @@ return NULL; s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); - internal_setblocking(s, block); - - Py_INCREF(Py_None); - return Py_None; + if (internal_setblocking(s, block) == -1) { + return NULL; + } + Py_RETURN_NONE; } PyDoc_STRVAR(setblocking_doc, @@ -2492,10 +2510,10 @@ return NULL; s->sock_timeout = timeout; - internal_setblocking(s, timeout < 0); - - Py_INCREF(Py_None); - return Py_None; + if (internal_setblocking(s, timeout < 0) == -1) { + return NULL; + } + Py_RETURN_NONE; } PyDoc_STRVAR(settimeout_doc, @@ -4720,7 +4738,10 @@ } #endif } - init_sockobject(s, fd, family, type, proto); + if (init_sockobject(s, fd, family, type, proto) == -1) { + SOCKETCLOSE(fd); + return -1; + } return 0; /christian@python.org