Kaydet (Commit) 6dbff33b authored tarafından Thomas Wouters's avatar Thomas Wouters

SF bug/patch #1433877: string parameter to ioctl not null terminated

The new char-array used in ioctl calls wasn't explicitly NUL-terminated;
quite probably the cause for the test_pty failures on Solaris that we
circumvented earlier. (I wasn't able to reproduce it with this patch, but it
has been somewhat elusive to start with.)
üst d798a181
......@@ -4,13 +4,6 @@ from test.test_support import verbose, TestFailed, TestSkipped
TEST_STRING_1 = "I wish to buy a fish license.\n"
TEST_STRING_2 = "For my pet fish, Eric.\n"
# Solaris (at least 2.9 and 2.10) seem to have a fickle isatty(). The first
# test below, testing the result of os.openpty() for tty-ness, sometimes
# (but not always) fails. The second isatty test, in the sub-process, always
# works. Allow that fickle first test to fail on these platforms, since it
# doesn't actually affect functionality.
fickle_isatty = ["sunos5"]
if verbose:
def debug(msg):
print msg
......@@ -54,7 +47,7 @@ def test_basic_pty():
# " An optional feature could not be imported " ... ?
raise TestSkipped, "Pseudo-terminals (seemingly) not functional."
if not os.isatty(slave_fd) and sys.platform not in fickle_isatty:
if not os.isatty(slave_fd):
raise TestFailed, "slave_fd is not a tty"
debug("Writing to slave_fd")
......
......@@ -33,6 +33,7 @@ Greg Ball
Luigi Ballabio
Michael J. Barber
Chris Barker
Quentin Barnes
Cesar Eduardo Barros
Des Barry
Ulf Bartelt
......
......@@ -95,6 +95,7 @@ corresponding to the return value of the fcntl call in the C code.");
static PyObject *
fcntl_ioctl(PyObject *self, PyObject *args)
{
#define IOCTL_BUFSZ 1024
int fd;
/* In PyArg_ParseTuple below, use the unsigned int 'I' format for
the signed int 'code' variable, because Python turns 0x8000000
......@@ -106,7 +107,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
char *str;
Py_ssize_t len;
int mutate_arg = 1;
char buf[1024];
char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
conv_descriptor, &fd, &code,
......@@ -114,8 +115,9 @@ fcntl_ioctl(PyObject *self, PyObject *args)
char *arg;
if (mutate_arg) {
if (len <= sizeof buf) {
if (len <= IOCTL_BUFSZ) {
memcpy(buf, str, len);
buf[len] = '\0';
arg = buf;
}
else {
......@@ -123,13 +125,14 @@ fcntl_ioctl(PyObject *self, PyObject *args)
}
}
else {
if (len > sizeof buf) {
if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
else {
memcpy(buf, str, len);
buf[len] = '\0';
arg = buf;
}
}
......@@ -141,7 +144,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
else {
ret = ioctl(fd, code, arg);
}
if (mutate_arg && (len < sizeof buf)) {
if (mutate_arg && (len < IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
if (ret < 0) {
......@@ -159,12 +162,13 @@ fcntl_ioctl(PyObject *self, PyObject *args)
PyErr_Clear();
if (PyArg_ParseTuple(args, "O&Is#:ioctl",
conv_descriptor, &fd, &code, &str, &len)) {
if (len > sizeof buf) {
if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
memcpy(buf, str, len);
buf[len] = '\0';
Py_BEGIN_ALLOW_THREADS
ret = ioctl(fd, code, buf);
Py_END_ALLOW_THREADS
......@@ -195,6 +199,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
return NULL;
}
return PyInt_FromLong((long)ret);
#undef IOCTL_BUFSZ
}
PyDoc_STRVAR(ioctl_doc,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment