-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
PyTupleObject::ob_item[1] with out-of-bounds access => undefined behavior #94250
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
Comments
This usage of a length 1 array as the pseudo-flexible array member was to allow compiling the code as either C or C++; C++ has never had a concept of a flexible array member, and while yes, it's undefined behavior, it's one of those weird cases of "technically undefined but actually works everywhere" behavior; it worked in C90, C99 and every C++ compiler available when the code was written, while using I can't say whether this decision needs revisiting, but it would be a major change that would break huge swathes of third-party extension modules written in C++ rather than C. |
…after -fstrict-flex-arrays change Before C99 introduced flexible array member, common practice uses size-1 array to emulate FAM, e.g. python/cpython#94250 As a result, -fsanitize=array-bounds instrumentation skipped such structures as a workaround (from 539e4a7). D126864 accidentally dropped the workaround. Add it back with tests.
While P1039 I got you, FAM: Flexible Array Members for C++ has been rejected, GCC and Clang seem to support |
We need to account for way more compilers in existance (Visual Studio's msvc, Intel C++, Oracle C++ - that's what I've worked with while my parallel systems university course; IBM XLC++, and more). |
This is a duplicate of #84301. The discussion can be continued there. |
Include/cpython/tupleobject.h
hasCPython may allocate the object with trailing elements, then access it with something like
PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
wherei > 0
.This out-of-bounds access is UB. (https://stackoverflow.com/questions/44745677/flexible-array-members-can-lead-to-undefined-behavior mentioned that before C99 TC2 there was a non-normative example which suggested that
[1]
can be used. That was incorrect and was removed by TC2.)The 2022-06-24 Clang
-fstrict-flex-arrays commit
(https://reviews.llvm.org/D126864 https://reviews.llvm.org/rG886715af962de2c92fac4bd37104450345711e4a) made-fsanitize=array-bounds
stricter and would catch such UB. Note: the Clang patch appears non-comprehensive. It misses many similar UB cases but catches the CPython UB.Reproduce (with clang compiled from latest llvm-project):
See also https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html GCC appears to be more permissive, at least til now: "Although using one-element arrays this way is discouraged, GCC handles accesses to trailing one-element array members analogously to zero-length arrays."
There are multiple suspicious places in CPython:
The text was updated successfully, but these errors were encountered: