Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5e38aae

Browse files
committed
Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't be updated back after the system call. Original patch by Brian Brazil.
1 parent 7f7561e commit 5e38aae

3 files changed

Lines changed: 31 additions & 6 deletions

File tree

Lib/test/test_ioctl.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import array
12
import unittest
23
from test.support import run_unittest, import_module, get_attribute
34
import os, struct
@@ -34,16 +35,36 @@ def test_ioctl(self):
3435
rpgrp = struct.unpack("i", r)[0]
3536
self.assertIn(rpgrp, ids)
3637

37-
def test_ioctl_mutate(self):
38-
import array
39-
buf = array.array('i', [0])
38+
def _check_ioctl_mutate_len(self, nbytes=None):
39+
buf = array.array('i')
40+
intsize = buf.itemsize
4041
ids = (os.getpgrp(), os.getsid(0))
41-
tty = open("/dev/tty", "r")
42-
r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
42+
# A fill value unlikely to be in `ids`
43+
fill = -12345
44+
if nbytes is not None:
45+
# Extend the buffer so that it is exactly `nbytes` bytes long
46+
buf.extend([fill] * (nbytes // intsize))
47+
self.assertEqual(len(buf) * intsize, nbytes) # sanity check
48+
else:
49+
buf.append(fill)
50+
with open("/dev/tty", "r") as tty:
51+
r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
4352
rpgrp = buf[0]
4453
self.assertEquals(r, 0)
4554
self.assertIn(rpgrp, ids)
4655

56+
def test_ioctl_mutate(self):
57+
self._check_ioctl_mutate_len()
58+
59+
def test_ioctl_mutate_1024(self):
60+
# Issue #9758: a mutable buffer of exactly 1024 bytes wouldn't be
61+
# copied back after the system call.
62+
self._check_ioctl_mutate_len(1024)
63+
64+
def test_ioctl_mutate_2048(self):
65+
# Test with a larger buffer, just for the record.
66+
self._check_ioctl_mutate_len(2048)
67+
4768
def test_ioctl_signed_unsigned_code_param(self):
4869
if not pty:
4970
raise unittest.SkipTest('pty module required')

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ Core and Builtins
1313
Library
1414
-------
1515

16+
- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
17+
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
18+
be updated back after the system call. Original patch by Brian Brazil.
19+
1620
- Updates to the random module:
1721

1822
* Document which parts of the module are guaranteed to stay the same

Modules/fcntlmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
157157
else {
158158
ret = ioctl(fd, code, arg);
159159
}
160-
if (mutate_arg && (len < IOCTL_BUFSZ)) {
160+
if (mutate_arg && (len <= IOCTL_BUFSZ)) {
161161
memcpy(str, buf, len);
162162
}
163163
PyBuffer_Release(&pstr); /* No further access to str below this point */

0 commit comments

Comments
 (0)