New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Py_BuildValue("(s#O)", ...) segfaults if entered with exception raised #83094
Comments
The following code results in a segmentation fault in CPython 3.8 while executes fines (raises a SystemError) in CPython 3.7. PyObject* debug(PyObject *self, PyObject *args)
{
const char * debug = "debug";
PyErr_SetString(PyExc_ValueError, "debug!");
return Py_BuildValue("(s#O)", debug, strlen(debug), Py_None);
} It seems necessary for the format string to contain both an instance of "s#" and "O" to trigger the bug. I'm attaching a C module that reproduces the problem. |
seen with the current 3.8 branch. |
Does it depend on whether PY_SSIZE_T_CLEAN is defined? |
It is not reproducible with PY_SSIZE_T_CLEAN defined. |
The problem arises from this code in do_mktuple(), staring at line 394 in modsupport.c: if (**p_format == '#') {
++*p_format;
if (flags & FLAG_SIZE_T)
n = va_arg(*p_va, Py_ssize_t);
else {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
return NULL;
}
n = va_arg(*p_va, int);
}
} If this is entered with an exception raised, PyErr_WarnEx() return NULL, thus this function return NULL without consuming the argument relative to the string length for the "s#" specifier. This argument is then consumed at the next iteration for the "O" specifier, resulting in a segmentation fault when the string length is interpreted as an object pointer. I don't know what is the best solution: either ignoring the return value of PyErr_WarnEx or swapping the lines from if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
return NULL;
}
n = va_arg(*p_va, int); to n = va_arg(*p_va, int);
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
return NULL;
} The handling of the "y#" just below suffers from the same problem. |
Note: this is going to miss Python 3.8.1 as I'm releasing 3.8.1rc1 right now. Please address this before 3.8.2 (due in February). |
Sadly, this missed the train for 3.8.2 as well. |
After this change, the arm64 buildbots are reporting reference leaks: 1:03:24 load avg: 0.95 Re-running failed tests in verbose mode e.g. https://buildbot.python.org/all/#/builders/563/builds/25 |
Actually there is a leak in PyErr_WarnEx(). |
Opened bpo-39831. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: