Skip to content

Commit fa22b29

Browse files
author
Yury Selivanov
committed
Issue #28471: Fix crash (GIL state related) in socket.setblocking
1 parent 33bb64f commit fa22b29

3 files changed

Lines changed: 31 additions & 9 deletions

File tree

Lib/test/test_socket.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,6 +4552,18 @@ def testExceptionTree(self):
45524552
self.assertTrue(issubclass(socket.gaierror, OSError))
45534553
self.assertTrue(issubclass(socket.timeout, OSError))
45544554

4555+
def test_setblocking_invalidfd(self):
4556+
# Regression test for issue #28471
4557+
4558+
sock0 = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
4559+
sock = socket.socket(
4560+
socket.AF_INET, socket.SOCK_STREAM, 0, sock0.fileno())
4561+
sock0.close()
4562+
4563+
with self.assertRaises(OSError):
4564+
sock.setblocking(False)
4565+
4566+
45554567
@unittest.skipUnless(sys.platform == 'linux', 'Linux specific test')
45564568
class TestLinuxAbstractNamespace(unittest.TestCase):
45574569

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Core and Builtins
1313
- Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception
1414
loss in PyTraceBack_Here().
1515

16+
- Issue #28471: Fix "Python memory allocator called without holding the GIL"
17+
crash in socket.setblocking.
18+
19+
1620
Library
1721
-------
1822

Modules/socketmodule.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ set_gaierror(int error)
622622
static int
623623
internal_setblocking(PySocketSockObject *s, int block)
624624
{
625+
int result = -1;
625626
#ifdef MS_WINDOWS
626627
u_long arg;
627628
#endif
@@ -641,34 +642,39 @@ internal_setblocking(PySocketSockObject *s, int block)
641642
#if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO))
642643
block = !block;
643644
if (ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block) == -1)
644-
goto error;
645+
goto done;
645646
#else
646647
delay_flag = fcntl(s->sock_fd, F_GETFL, 0);
647648
if (delay_flag == -1)
648-
goto error;
649+
goto done;
649650
if (block)
650651
new_delay_flag = delay_flag & (~O_NONBLOCK);
651652
else
652653
new_delay_flag = delay_flag | O_NONBLOCK;
653654
if (new_delay_flag != delay_flag)
654655
if (fcntl(s->sock_fd, F_SETFL, new_delay_flag) == -1)
655-
goto error;
656+
goto done;
656657
#endif
657658
#else /* MS_WINDOWS */
658659
arg = !block;
659660
if (ioctlsocket(s->sock_fd, FIONBIO, &arg) != 0)
660-
goto error;
661+
goto done;
661662
#endif /* MS_WINDOWS */
663+
664+
result = 0;
665+
666+
done:
662667
Py_END_ALLOW_THREADS
663668

664-
return 0;
665-
error:
669+
if (result) {
666670
#ifndef MS_WINDOWS
667-
PyErr_SetFromErrno(PyExc_OSError);
671+
PyErr_SetFromErrno(PyExc_OSError);
668672
#else
669-
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
673+
PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError());
670674
#endif
671-
return -1;
675+
}
676+
677+
return result;
672678
}
673679

674680
static int

0 commit comments

Comments
 (0)