Skip to content

Commit a76f96c

Browse files
committed
Reject a bad subprocess pipe protocol owner with TypeError.
The constructor only checked proc and fd under UVLOOP_DEBUG, then cast proc and segfaulted. That check now always runs. Fixes #765.
1 parent e8efea4 commit a76f96c

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import unittest
2+
3+
from uvloop.loop import ReadSubprocessPipeProto, WriteSubprocessPipeProto
4+
5+
6+
class TestSubprocessPipeProto(unittest.TestCase):
7+
def test_rejects_non_process_owner(self):
8+
with self.assertRaises(TypeError):
9+
ReadSubprocessPipeProto(1, 7)
10+
with self.assertRaises(TypeError):
11+
WriteSubprocessPipeProto(1, 7)
12+
13+
def test_rejects_non_int_fd(self):
14+
# Owner is checked first. A non-process still must not segfault.
15+
with self.assertRaises(TypeError):
16+
WriteSubprocessPipeProto(object(), 'nope')

‎uvloop/handles/process.pyx‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -706,11 +706,18 @@ cdef class UVProcessTransport(UVProcess):
706706
class WriteSubprocessPipeProto(aio_BaseProtocol):
707707

708708
def __init__(self, proc, fd):
709-
if UVLOOP_DEBUG:
710-
if type(proc) is not UVProcessTransport:
711-
raise TypeError
712-
if not isinstance(fd, int):
713-
raise TypeError
709+
# Release builds used to cast `proc` and segfault. Reject a bad owner
710+
# here so a mistaken constructor argument is a TypeError.
711+
if type(proc) is not UVProcessTransport:
712+
raise TypeError(
713+
'proc must be a UVProcessTransport, not {!r}'.format(
714+
type(proc).__name__,
715+
),
716+
)
717+
if not isinstance(fd, int):
718+
raise TypeError(
719+
'fd must be an int, not {!r}'.format(type(fd).__name__),
720+
)
714721
self.proc = proc
715722
self.fd = fd
716723
self.pipe = None

0 commit comments

Comments
 (0)