mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-134744: Fix fcntl error handling (#134748)
Fix also reference leak on buffer overflow.
This commit is contained in:
parent
176b059fa0
commit
9300a596d3
3 changed files with 28 additions and 4 deletions
|
@ -11,7 +11,7 @@ from test.support import (
|
||||||
cpython_only, get_pagesize, is_apple, requires_subprocess, verbose
|
cpython_only, get_pagesize, is_apple, requires_subprocess, verbose
|
||||||
)
|
)
|
||||||
from test.support.import_helper import import_module
|
from test.support.import_helper import import_module
|
||||||
from test.support.os_helper import TESTFN, unlink
|
from test.support.os_helper import TESTFN, unlink, make_bad_fd
|
||||||
|
|
||||||
|
|
||||||
# Skip test if no fcntl module.
|
# Skip test if no fcntl module.
|
||||||
|
@ -274,6 +274,17 @@ class TestFcntl(unittest.TestCase):
|
||||||
def test_fcntl_large_buffer(self):
|
def test_fcntl_large_buffer(self):
|
||||||
self._check_fcntl_not_mutate_len(2024)
|
self._check_fcntl_not_mutate_len(2024)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(fcntl, 'F_DUPFD'), 'need fcntl.F_DUPFD')
|
||||||
|
def test_bad_fd(self):
|
||||||
|
# gh-134744: Test error handling
|
||||||
|
fd = make_bad_fd()
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
fcntl.fcntl(fd, fcntl.F_DUPFD, 0)
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
fcntl.fcntl(fd, fcntl.F_DUPFD, b'\0' * 10)
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
fcntl.fcntl(fd, fcntl.F_DUPFD, b'\0' * 2048)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -5,7 +5,7 @@ import sys
|
||||||
import threading
|
import threading
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
from test import support
|
||||||
from test.support import threading_helper
|
from test.support import os_helper, threading_helper
|
||||||
from test.support.import_helper import import_module
|
from test.support.import_helper import import_module
|
||||||
fcntl = import_module('fcntl')
|
fcntl = import_module('fcntl')
|
||||||
termios = import_module('termios')
|
termios = import_module('termios')
|
||||||
|
@ -201,6 +201,17 @@ class IoctlTestsPty(unittest.TestCase):
|
||||||
new_winsz = struct.unpack("HHHH", result)
|
new_winsz = struct.unpack("HHHH", result)
|
||||||
self.assertEqual(new_winsz[:2], (20, 40))
|
self.assertEqual(new_winsz[:2], (20, 40))
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(fcntl, 'FICLONE'), 'need fcntl.FICLONE')
|
||||||
|
def test_bad_fd(self):
|
||||||
|
# gh-134744: Test error handling
|
||||||
|
fd = os_helper.make_bad_fd()
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
fcntl.ioctl(fd, fcntl.FICLONE, fd)
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
fcntl.ioctl(fd, fcntl.FICLONE, b'\0' * 10)
|
||||||
|
with self.assertRaises(OSError):
|
||||||
|
fcntl.ioctl(fd, fcntl.FICLONE, b'\0' * 2048)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -128,7 +128,7 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (async_err) {
|
if (!async_err) {
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
}
|
}
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
@ -136,6 +136,7 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
|
||||||
}
|
}
|
||||||
if (ptr[len] != '\0') {
|
if (ptr[len] != '\0') {
|
||||||
PyErr_SetString(PyExc_SystemError, "buffer overflow");
|
PyErr_SetString(PyExc_SystemError, "buffer overflow");
|
||||||
|
Py_DECREF(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -310,7 +311,7 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg,
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (async_err) {
|
if (!async_err) {
|
||||||
PyErr_SetFromErrno(PyExc_OSError);
|
PyErr_SetFromErrno(PyExc_OSError);
|
||||||
}
|
}
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
@ -318,6 +319,7 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg,
|
||||||
}
|
}
|
||||||
if (ptr[len] != '\0') {
|
if (ptr[len] != '\0') {
|
||||||
PyErr_SetString(PyExc_SystemError, "buffer overflow");
|
PyErr_SetString(PyExc_SystemError, "buffer overflow");
|
||||||
|
Py_DECREF(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue