gh-125118: don't copy arbitrary values to _Bool in the struct module#125169
gh-125118: don't copy arbitrary values to _Bool in the struct module#125169encukou merged 6 commits intopython:mainfrom
Conversation
…odule
memcopy'ing arbitrary values to _Bool variable triggers undefined
behaviour, e.g.:
```c
/* a.c */
int main(void)
{
_Bool x;
char y = 2;
memcpy(&x, &y, 1);
printf("%d\n", x != 0);
return 0;
}
```
```
$ gcc-12 a.c -Wall && ./a.out
2
$ clang-15 a.c -Wall && ./a.out
0
$ gcc-12 a.c -Wall -fsanitize=undefined && ./a.out
a.c:9:5: runtime error: load of value 2, which is not a valid value for type '_Bool'
0
$ clang-15 a.c -Wall -fsanitize=undefined && ./a.out
a.c:9:20: runtime error: load of value 2, which is not a valid value for type '_Bool'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior a.c:9:20 in
0
```
Cridits to Alex Gaynor.
|
Yes, please wait for my review. I'll get to it this week. |
ZeroIntensity
left a comment
There was a problem hiding this comment.
I think this looks fine. Out of curiosity, what bug was this causing in practice?
|
It was triggering UBSAN warnings, because it was UB. AFAIK it wasn't misbehaving on any platform yet, but it'd have been within the compiler's right to rewrite Should we add a |
|
@ZeroIntensity, you could try added tests on gcc-12 (PASS) and clang-17 (FAIL). I suspect specific versions aren't important. |
|
As far as I can see, the safest assumption we can make is that To allow bigger static const _Bool false_bool = 0;
return PyBool_FromLong(memcmp(p, &false_bool, sizeof(_Bool))); |
I don't think that static is needed here. |
Co-authored-by: Sam Gross <colesbury@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Petr Viktorin <encukou@gmail.com>
|
Thank you! |
|
Thanks @skirpichev for the PR, and @encukou for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13. |
|
Thanks @skirpichev for the PR, and @encukou for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12. |
|
Sorry, @skirpichev and @encukou, I could not cleanly backport this to |
|
Sorry, @skirpichev and @encukou, I could not cleanly backport this to |
|
Working on backports... |
…truct module (pythonGH-125169) memcopy'ing arbitrary values to _Bool variable triggers undefined behaviour. Avoid this. We assume that `false` is represented by all zero bytes. Credits to Alex Gaynor. (cherry picked from commit 87d7315) Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com> Co-authored-by: Sam Gross <colesbury@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
|
GH-125263 is a backport of this pull request to the 3.13 branch. |
…truct module (pythonGH-125169) memcopy'ing arbitrary values to _Bool variable triggers undefined behaviour. Avoid this. We assume that `false` is represented by all zero bytes. Credits to Alex Gaynor. (cherry picked from commit 87d7315) Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com> Co-authored-by: Sam Gross <colesbury@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
|
GH-125265 is a backport of this pull request to the 3.12 branch. |
…module (GH-125169) (#125265) memcopy'ing arbitrary values to _Bool variable triggers undefined behaviour. Avoid this. We assume that `false` is represented by all zero bytes. Credits to Alex Gaynor. (cherry picked from commit 87d7315) Co-authored-by: Sam Gross <colesbury@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
…module (GH-125169) (#125263) memcopy'ing arbitrary values to _Bool variable triggers undefined behaviour. Avoid this. We assume that `false` is represented by all zero bytes. Credits to Alex Gaynor. (cherry picked from commit 87d7315) Co-authored-by: Sam Gross <colesbury@gmail.com> Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Petr Viktorin <encukou@gmail.com>
memcopy'ing arbitrary values to _Bool variable triggers undefined behaviour, e.g.:
Cridits to Alex Gaynor.