Bug 28458 - pthread_setspecific rejects pseudo pointers
Summary: pthread_setspecific rejects pseudo pointers
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: 2.34
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2021-10-16 07:53 UTC by Jan Kiszka
Modified: 2021-11-04 07:00 UTC (History)
4 users (show)

See Also:
Last reconfirmed: 2021-11-04 00:00:00
fweimer: security-


Note You need to log in before you can comment on or make changes to this bug.
Description Jan Kiszka 2021-10-16 07:53:37 UTC
Since a1561c3bbe8e72c6e44280d1eb5e529d2da4ecd0, pthread_setspecific started to reject pseudo pointers like (const void *)1L:

printf.c:732:9: error: 'pthread_setspecific' expecting 1 byte in a region of size 0 [-Werror=stringop-overread]
  732 |         pthread_setspecific(cleanup_key, (const void *)1);

This breaks existing code that wants to signal special conditions to key readers ("not an object") or want to use pthread_key_create to register a per-thread destructor. These issues can be worked around, but users will be confronted with valid but no longer compiling code first of all.

Reading the Open Group spec on this, I do not find any hint that suggests only NULL or valid pointers must be passed to pthread_setspecific.
Comment 1 Florian Weimer 2021-10-18 13:35:12 UTC
I'm not aware of any reasonable way to suppress this GCC warning.
Comment 2 Florian Weimer 2021-10-18 13:36:54 UTC
Just to be clear, I agree that this warning is wrong because it also happens for MAP_FAILED and other POSIX pointer constants.
Comment 3 Jan Kiszka 2021-10-18 13:46:45 UTC
Then, could someone familiar with the details (also) file a bug report with them? Or did this happen already?
Comment 4 Florian Weimer 2021-10-18 13:50:07 UTC
I found an existing GCC bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102329
Comment 5 Florian Weimer 2021-11-04 07:00:23 UTC
It's not just pseudo-pointers, we get a warning for this as well:

#include <pthread.h>

extern int x[1];

f (pthread_key_t key)
  pthread_setspecific (key, &x[1]);