[LTP] openposix: timer_*/speculative: Skip untestable optional behavior on Linux
Avinesh Kumar
avinesh.kumar@suse.com
Mon Aug 31 18:38:11 CEST 2026
Hi Cyril,
On 8/31/26 12:15 PM, Cyril Hrubis wrote:
> Hi!
>>> openposix: timer_*/speculative: Skip untestable optional behavior on Linux
>>
>>> +#ifdef __linux__
>>> + printf("Linux does not implement this optional behavior\n");
>>> + return PTS_UNSUPPORTED;
>>> +#else
>>
>> Could these branches be removed from all eleven tests? Linux 7.2 uses
>> scoped_timer_get_or_fail() to return -EINVAL for invalid timer IDs in
>> timer_gettime(), timer_getoverrun(), timer_settime(), and timer_delete().
>> The installed man pages document the same EINVAL result.
>>
>> More directly, every pre-patch test reports errno == EINVAL and returns
>> PTS_PASS when built and run on Linux. The platform check therefore replaces
>> working coverage with PTS_UNSUPPORTED, and the quoted runtime message is not
>> accurate.
>
> That's the kernel part, apparently it's more complex in libc.
>
> Libc has two types of timer_t values, either it's a directly kernel
> timer id (small int) or a pointer to a structure that holds the id.
>
> The timer libc functions, before calling the kernel syscall, convert the
> libc timer id into kernel timer id with:
>
> static inline kernel_timer_t
> timerid_to_kernel_timer (timer_t timerid)
> {
> if (timer_is_sigev_thread (timerid))
> return timerid_to_timer (timerid)->ktimerid;
> else
> return (kernel_timer_t) ((uintptr_t) timerid);
> }
>
> The library does a bit of magic with the pointers:
>
> https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/kernel-posix-timers.h.html
>
> But overall it checks the MSB bit of the pointer to figure out if it's
> kernel timer id which should be passed verbatim, or a structure that
> needs to be dereferenced.
>
> Looking at the timer_gettime/speculative/6-1.c we do pass a pointer to
> the stack (instead of the invalid value) which on 32bit may be an
> address with the MSB bit set. So this triggers undefined behavior, since
> glibc thinks it's a pointer to it's internal data structure, but the
> real pointer the glibc exports as the timer is bit-shifted. Hence we
> access random and possibly invalid address. With some luck that address
> is accesible and contains non-zero data and we end up passing invalid
> timer ID to the kernel, but when I straced the test, the value was
> pretty much random.
>
I was also trying to understand the sign bit usage and bit shifting
magic in this glibc code, causing this issue. Thanks for explaining
this clearly. I have send revised patch -
https://lore.kernel.org/ltp/20260831163310.137399-1-avinesh.kumar@suse.com/T/#u
Regards,
Avinesh
> With that in mind, we can fix the test with passing the BOGUSID instead
> of random stack pointer:
>
> diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c
> index d09c2f709..c35dd816f 100644
> --- a/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c
> +++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_gettime/speculative/6-1.c
> @@ -21,8 +21,7 @@ int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
> {
> timer_t tid;
> struct itimerspec its;
> - int tval = BOGUSTID;
> - tid = (timer_t) & tval;
> + tid = (timer_t) BOGUSTID;
> if (timer_gettime(tid, &its) == -1) {
> if (EINVAL == errno) {
> printf("fcn returned -1 and errno==EINVAL\n");
>
More information about the ltp
mailing list