[LTP] openposix: timer_*/speculative: Skip untestable optional behavior on Linux
Cyril Hrubis
chrubis@suse.cz
Mon Aug 31 12:15:35 CEST 2026
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.
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");
--
Cyril Hrubis
chrubis@suse.cz
More information about the ltp
mailing list