[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