mirror of https://github.com/python/cpython.git
Issue #27759: Fix selectors incorrectly retain invalid file descriptors.
(Backported to 3.4 as this bug might be exploited to for DoS)
This commit is contained in:
parent
26d998cfdd
commit
cb9424f643
|
@ -399,7 +399,11 @@ def register(self, fileobj, events, data=None):
|
||||||
epoll_events |= select.EPOLLIN
|
epoll_events |= select.EPOLLIN
|
||||||
if events & EVENT_WRITE:
|
if events & EVENT_WRITE:
|
||||||
epoll_events |= select.EPOLLOUT
|
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
|
return key
|
||||||
|
|
||||||
def unregister(self, fileobj):
|
def unregister(self, fileobj):
|
||||||
|
@ -465,14 +469,18 @@ def fileno(self):
|
||||||
|
|
||||||
def register(self, fileobj, events, data=None):
|
def register(self, fileobj, events, data=None):
|
||||||
key = super().register(fileobj, events, data)
|
key = super().register(fileobj, events, data)
|
||||||
if events & EVENT_READ:
|
try:
|
||||||
kev = select.kevent(key.fd, select.KQ_FILTER_READ,
|
if events & EVENT_READ:
|
||||||
select.KQ_EV_ADD)
|
kev = select.kevent(key.fd, select.KQ_FILTER_READ,
|
||||||
self._kqueue.control([kev], 0, 0)
|
select.KQ_EV_ADD)
|
||||||
if events & EVENT_WRITE:
|
self._kqueue.control([kev], 0, 0)
|
||||||
kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
|
if events & EVENT_WRITE:
|
||||||
select.KQ_EV_ADD)
|
kev = select.kevent(key.fd, select.KQ_FILTER_WRITE,
|
||||||
self._kqueue.control([kev], 0, 0)
|
select.KQ_EV_ADD)
|
||||||
|
self._kqueue.control([kev], 0, 0)
|
||||||
|
except BaseException:
|
||||||
|
super().unregister(fileobj)
|
||||||
|
raise
|
||||||
return key
|
return key
|
||||||
|
|
||||||
def unregister(self, fileobj):
|
def unregister(self, fileobj):
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import signal
|
import signal
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
from test import support
|
from test import support
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -447,6 +448,16 @@ class EpollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
|
||||||
|
|
||||||
SELECTOR = getattr(selectors, 'EpollSelector', None)
|
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'),
|
@unittest.skipUnless(hasattr(selectors, 'KqueueSelector'),
|
||||||
"Test needs selectors.KqueueSelector)")
|
"Test needs selectors.KqueueSelector)")
|
||||||
|
@ -454,6 +465,18 @@ class KqueueSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn):
|
||||||
|
|
||||||
SELECTOR = getattr(selectors, 'KqueueSelector', None)
|
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():
|
def test_main():
|
||||||
tests = [DefaultSelectorTestCase, SelectSelectorTestCase,
|
tests = [DefaultSelectorTestCase, SelectSelectorTestCase,
|
||||||
|
|
|
@ -29,6 +29,9 @@ Library
|
||||||
HTTP_PROXY variable when REQUEST_METHOD environment is set, which indicates
|
HTTP_PROXY variable when REQUEST_METHOD environment is set, which indicates
|
||||||
that the script is in CGI mode.
|
that the script is in CGI mode.
|
||||||
|
|
||||||
|
- Issue #27759: Fix selectors incorrectly retain invalid file descriptors.
|
||||||
|
Patch by Mark Williams.
|
||||||
|
|
||||||
Tests
|
Tests
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue