[LTP] [PATCH] openposix: timer_*/speculative: Handle SIGSEGV on old glibc
Avinesh Kumar
avinesh.kumar@suse.com
Tue Sep 29 14:47:54 CEST 2026
From: Avinesh Kumar <avinesh.kumar@suse.com>
timer_delete/speculative/5-1, timer_getoverrun/speculative/6-1,
timer_gettime/speculative/6-1, and timer_settime/speculative/12-1 all
pass a bogus BOGUSTIMERID/BOGUSTID value as an invalid timerid.
Commit d377d1cff1ec ("openposix: timer_*/speculative: Don't pass a
stack pointer as timerid") fixed a SIGSEGV on i586, where current
glibc's sign-bit check (timer_is_sigev_thread()) can misread a stack
address as a tagged pointer. A small constant avoids that.
But older glibc (<= 2.31, before this check existed) unconditionally
dereferences timerid as a pointer, so the same small constant now
faults instead, on any architecture:
timer_delete_sp[13131]: segfault at 186a3 ip 00007f15973aed4e sp 00007ffefb52c5a0 error 4 in librt-2.31.so[7f15973aa000+8000]
POSIX defines no required behavior for an invalid timer ID.
Install a handler to accept SIGSEGV.
Fixes: d377d1cff1ec ("openposix: timer_*/speculative: Don't pass a stack pointer as timerid")
Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
---
.../interfaces/timer_delete/speculative/5-1.c | 18 ++++++++++++++++++
.../timer_getoverrun/speculative/6-1.c | 18 ++++++++++++++++++
.../timer_gettime/speculative/6-1.c | 18 ++++++++++++++++++
.../timer_settime/speculative/12-1.c | 19 +++++++++++++++++++
4 files changed, 73 insertions(+)
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c
index dce9277b5d6a..c7a94e1446f7 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_delete/speculative/5-1.c
@@ -13,13 +13,31 @@
#include <time.h>
#include <stdio.h>
#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
#include "posixtest.h"
#define BOGUSTIMERID 99999
+/*
+ * timerid is not a valid timer ID; POSIX defines no required behavior
+ * here (EINVAL is only a recommendation), so SIGSEGV is an equally
+ * valid outcome.
+ */
+static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED)
+{
+ PTS_WRITE_MSG("Got SIGSEGV when calling timer_delete() with an invalid timer ID\n");
+ PTS_WRITE_MSG("Test PASSED\n");
+ _exit(PTS_PASS);
+}
+
int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
{
timer_t tid = (timer_t)BOGUSTIMERID;
+ struct sigaction sa = { .sa_handler = sigsegv_handler };
+
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
if (timer_delete(tid) == -1) {
if (errno == EINVAL) {
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c
index 3a8f1448d4d4..7861e99d4c8d 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_getoverrun/speculative/6-1.c
@@ -13,13 +13,31 @@
#include <time.h>
#include <stdio.h>
#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
#include "posixtest.h"
#define BOGUSTID 9999
+/*
+ * timerid is not a valid timer ID; POSIX defines no required behavior
+ * here (EINVAL is only a recommendation), so SIGSEGV is an equally
+ * valid outcome.
+ */
+static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED)
+{
+ PTS_WRITE_MSG("Got SIGSEGV when calling timer_getoverrun() with an invalid timer ID\n");
+ PTS_WRITE_MSG("Test PASSED\n");
+ _exit(PTS_PASS);
+}
+
int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
{
timer_t tid = (timer_t)BOGUSTID;
+ struct sigaction sa = { .sa_handler = sigsegv_handler };
+
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
if (timer_getoverrun(tid) == -1) {
if (EINVAL == errno) {
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 586b0ed3a2b1..a3a9e080e26c 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
@@ -13,14 +13,32 @@
#include <time.h>
#include <stdio.h>
#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
#include "posixtest.h"
#define BOGUSTID 9999
+/*
+ * timerid is not a valid timer ID; POSIX defines no required behavior
+ * here (EINVAL is only a recommendation), so SIGSEGV is an equally
+ * valid outcome.
+ */
+static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED)
+{
+ PTS_WRITE_MSG("Got SIGSEGV when calling timer_gettime() with an invalid timer ID\n");
+ PTS_WRITE_MSG("Test PASSED\n");
+ _exit(PTS_PASS);
+}
+
int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
{
struct itimerspec its;
timer_t tid = (timer_t)BOGUSTID;
+ struct sigaction sa = { .sa_handler = sigsegv_handler };
+
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
if (timer_gettime(tid, &its) == -1) {
if (EINVAL == errno) {
diff --git a/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c b/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c
index ac7f7bf24c39..953d585b8730 100644
--- a/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c
+++ b/testcases/open_posix_testsuite/conformance/interfaces/timer_settime/speculative/12-1.c
@@ -12,14 +12,33 @@
#include <time.h>
#include <stdio.h>
#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
#include "posixtest.h"
#define BOGUSTID 9999
+/*
+ * timerid is not a valid timer ID; POSIX defines no required behavior
+ * here (EINVAL is only a recommendation), so SIGSEGV is an equally
+ * valid outcome.
+ */
+static void sigsegv_handler(int signum PTS_ATTRIBUTE_UNUSED)
+{
+ PTS_WRITE_MSG("Got SIGSEGV when calling timer_settime() with an invalid timer ID\n");
+ PTS_WRITE_MSG("Test PASSED\n");
+ _exit(PTS_PASS);
+}
+
int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
{
struct itimerspec its;
timer_t tid = (timer_t)BOGUSTID;
+ struct sigaction sa = { .sa_handler = sigsegv_handler };
+
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
+
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
its.it_value.tv_sec = 0;
--
2.55.0
More information about the ltp
mailing list