[Python-checkins] cpython (3.4): Issue #27759: Fix selectors incorrectly retain invalid file descriptors.
yury.selivanov
python-checkins at python.org
Thu Oct 6 14:06:36 EDT 2016
https://hg.python.org/cpython/rev/8cc1fca83fb8
changeset: 104337:8cc1fca83fb8
branch: 3.4
parent: 103949:ccfea26e6582
user: Yury Selivanov <yury at magic.io>
date: Thu Oct 06 14:03:03 2016 -0400
summary:
Issue #27759: Fix selectors incorrectly retain invalid file descriptors.
(Backported to 3.4 as this bug might be exploited to for DoS)
files:
Lib/selectors.py | 26 +++++++++++++++++---------
Lib/test/test_selectors.py | 23 +++++++++++++++++++++++
Misc/NEWS | 3 +++
3 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/Lib/selectors.py b/Lib/selectors.py
--- a/Lib/selectors.py
+++ b/Lib/selectors.py
@@ -399,7 +399,11 @@
epoll_events |= select.EPOLLIN
if events & EVENT_WRITE:
epoll_events |= select.EPOLLOUT
- self._epoll.register(key.fd, epoll_events)
+ try:
+ self._epoll.register(key.fd, epoll_events)
+ except BaseException:
+ super().unregister(fileobj)
+ raise
return key
def unregister(self, fileobj):
@@ -465,14 +469,18 @@
def register(self, fileobj, events, data=None):
key = super().register(fileobj, events, data)
- if events & EVENT_READ:
- kev = select.kevent(key.fd, select.KQ_FILTER_READ,
- select.KQ_EV_ADD)
- self._kqueue.control([kev], 0, 0)
- if events & EVENT_WRITE:
- kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
- select.KQ_EV_ADD)
- self._kqueue.control([kev], 0, 0)
+ try:
+ if events & EVENT_READ:
+ kev = select.kevent(key.fd, select.KQ_FILTER_READ,
+ select.KQ_EV_ADD)
+ self._kqueue.control([kev], 0, 0)
+ if events & EVENT_WRITE:
+ kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
+ select.KQ_EV_ADD)
+ self._kqueue.control([kev], 0, 0)
+ except BaseException:
+ super().unregister(fileobj)
+ raise
return key
def unregister(self, fileobj):
diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py
--- a/Lib/test/test_selectors.py
+++ b/Lib/test/test_selectors.py
@@ -5,6 +5,7 @@
import signal
import socket
import sys
+import tempfile
from test import support
from time import sleep
import unittest
@@ -447,6 +448,16 @@
SELECTOR = getattr(selectors, 'EpollSelector', None)
+ def test_register_file(self):
+ # epoll(7) returns EPERM when given a file to watch
+ s = self.SELECTOR()
+ with tempfile.NamedTemporaryFile() as f:
+ with self.assertRaises(IOError):
+ s.register(f, selectors.EVENT_READ)
+ # the SelectorKey has been removed
+ with self.assertRaises(KeyError):
+ s.get_key(f)
+
@unittest.skipUnless(hasattr(selectors, 'KqueueSelector'),
"Test needs selectors.KqueueSelector)")
@@ -454,6 +465,18 @@
SELECTOR = getattr(selectors, 'KqueueSelector', None)
+ def test_register_bad_fd(self):
+ # a file descriptor that's been closed should raise an OSError
+ # with EBADF
+ s = self.SELECTOR()
+ bad_f = support.make_bad_fd()
+ with self.assertRaises(OSError) as cm:
+ s.register(bad_f, selectors.EVENT_READ)
+ self.assertEqual(cm.exception.errno, errno.EBADF)
+ # the SelectorKey has been removed
+ with self.assertRaises(KeyError):
+ s.get_key(bad_f)
+
def test_main():
tests = [DefaultSelectorTestCase, SelectSelectorTestCase,
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -29,6 +29,9 @@
HTTP_PROXY variable when REQUEST_METHOD environment is set, which indicates
that the script is in CGI mode.
+- Issue #27759: Fix selectors incorrectly retain invalid file descriptors.
+ Patch by Mark Williams.
+
Tests
-----
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list