Kaydet (Commit) a84d0b36 authored tarafından Vlad Starostin's avatar Vlad Starostin Kaydeden (comit) Andrew Svetlov

bpo-33263: Fix FD leak in _SelectorSocketTransport (GH-6450)

* bpo-33263 Fix FD leak in _SelectorSocketTransport. (GH-6450)

Under particular circumstances _SelectorSocketTransport can try to add a reader
even the transport is already being closed. This can lead to FD leak and
invalid stated of the following connections. Fixed the SelectorSocketTransport
to add the reader only if the trasport is still active.
üst 4054b172
......@@ -706,6 +706,12 @@ class _SelectorTransport(transports._FlowControlMixin,
def get_write_buffer_size(self):
return len(self._buffer)
def _add_reader(self, fd, callback, *args):
if self._closing:
return
self._loop._add_reader(fd, callback, *args)
class _SelectorSocketTransport(_SelectorTransport):
......@@ -732,7 +738,7 @@ class _SelectorSocketTransport(_SelectorTransport):
self._loop.call_soon(self._protocol.connection_made, self)
# only start reading when connection_made() has been called
self._loop.call_soon(self._loop._add_reader,
self._loop.call_soon(self._add_reader,
self._sock_fd, self._read_ready)
if waiter is not None:
# only wake up the waiter when connection_made() has been called
......@@ -754,7 +760,7 @@ class _SelectorSocketTransport(_SelectorTransport):
if self._closing or not self._paused:
return
self._paused = False
self._loop._add_reader(self._sock_fd, self._read_ready)
self._add_reader(self._sock_fd, self._read_ready)
if self._loop.get_debug():
logger.debug("%r resumes reading", self)
......@@ -930,7 +936,7 @@ class _SelectorDatagramTransport(_SelectorTransport):
self._address = address
self._loop.call_soon(self._protocol.connection_made, self)
# only start reading when connection_made() has been called
self._loop.call_soon(self._loop._add_reader,
self._loop.call_soon(self._add_reader,
self._sock_fd, self._read_ready)
if waiter is not None:
# only wake up the waiter when connection_made() has been called
......
......@@ -871,6 +871,21 @@ class SelectorTransportTests(test_utils.TestCase):
self.assertIsNone(tr._protocol)
self.assertIsNone(tr._loop)
def test__add_reader(self):
tr = self.create_transport()
tr._buffer.extend(b'1')
tr._add_reader(7, mock.sentinel)
self.assertTrue(self.loop.readers)
tr._force_close(None)
self.assertTrue(tr.is_closing())
self.assertFalse(self.loop.readers)
# can not add readers after closing
tr._add_reader(7, mock.sentinel)
self.assertFalse(self.loop.readers)
class SelectorSocketTransportTests(test_utils.TestCase):
......
Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment