diff --git a/Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst b/Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst new file mode 100644 index 00000000000000..1e16d28a756296 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-01-27-14-23-10.gh-issue-144206.l0un4U.rst @@ -0,0 +1,2 @@ +Improve error messages for buffer overflow in :func:`fcntl.fcntl` and +:func:`fcntl.ioctl`. diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index e373bf368813ac..ce636c574ed5ff 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -111,7 +111,11 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; } if (memcmp(buf + len, guard, GUARDSZ) != 0) { - PyErr_SetString(PyExc_SystemError, "buffer overflow"); + PyErr_SetString(PyExc_SystemError, + "Possible stack corruption in fcntl() due to " + "buffer overflow. " + "Provide an argument of sufficient size as " + "determined by the operation."); return NULL; } return PyBytes_FromStringAndSize(buf, len); @@ -139,7 +143,11 @@ fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg) return NULL; } if (ptr[len] != '\0') { - PyErr_SetString(PyExc_SystemError, "buffer overflow"); + PyErr_SetString(PyExc_SystemError, + "Memory corruption in fcntl() due to " + "buffer overflow. " + "Provide an argument of sufficient size as " + "determined by the operation."); PyBytesWriter_Discard(writer); return NULL; } @@ -264,7 +272,12 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg, } PyBuffer_Release(&view); if (ptr == buf && memcmp(buf + len, guard, GUARDSZ) != 0) { - PyErr_SetString(PyExc_SystemError, "buffer overflow"); + PyErr_SetString(PyExc_SystemError, + "Possible stack corruption in ioctl() due to " + "buffer overflow. " + "Provide a writable buffer argument of " + "sufficient size as determined by " + "the operation."); return NULL; } return PyLong_FromLong(ret); @@ -293,7 +306,11 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg, return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL; } if (memcmp(buf + len, guard, GUARDSZ) != 0) { - PyErr_SetString(PyExc_SystemError, "buffer overflow"); + PyErr_SetString(PyExc_SystemError, + "Possible stack corruption in ioctl() due to " + "buffer overflow. " + "Provide an argument of sufficient size as " + "determined by the operation."); return NULL; } return PyBytes_FromStringAndSize(buf, len); @@ -321,7 +338,11 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned long code, PyObject *arg, return NULL; } if (ptr[len] != '\0') { - PyErr_SetString(PyExc_SystemError, "buffer overflow"); + PyErr_SetString(PyExc_SystemError, + "Memory corruption in ioctl() due to " + "buffer overflow. " + "Provide an argument of sufficient size as " + "determined by the operation."); PyBytesWriter_Discard(writer); return NULL; }