[LTP] [PATCH v2] openposix: timer_*/speculative: Handle SIGSEGV on invalid timer ID

Avinesh Kumar avinesh.kumar@suse.com
Sat Aug 8 17:03:31 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 value as an invalid timer_t timerid.
On i586, glibc dereferences timer_t as a pointer into
internal state, and the bogus pointer causes a SIGSEGV
instead of the tests' expected EINVAL:

  timer_delete_sp[22499]: segfault at 7f4982f0 ip b7e07824 sp bfa4c140 error 4 in libc.so.6[a4824,b7d87000+191000]

POSIX defines no required behavior for an invalid timer ID (EINVAL is
only a recommendation), so a SIGSEGV is just as valid an outcome.

Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
---
 .../interfaces/timer_delete/speculative/5-1.c | 19 ++++++++++++++++++
 .../timer_getoverrun/speculative/6-1.c        | 19 ++++++++++++++++++
 .../timer_gettime/speculative/6-1.c           | 20 +++++++++++++++++++
 .../timer_settime/speculative/12-1.c          | 20 +++++++++++++++++++
 4 files changed, 78 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 912cf5800e6f..af01f72a59d1 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,16 +13,35 @@
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <signal.h>
+#include <unistd.h>
 #include "posixtest.h"
 
 #define BOGUSTIMERID 99999
 
+/*
+ * when timerid argument does not correspond to a timer ID returned by
+ * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also
+ * 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;
 	int tval = BOGUSTIMERID;
+	struct sigaction sa = { .sa_handler = sigsegv_handler };
+
 	tid = (timer_t) & tval;
 
+	sigfillset(&sa.sa_mask);
+	sigaction(SIGSEGV, &sa, NULL);
+
 	if (timer_delete(tid) == -1) {
 		if (errno == EINVAL) {
 			printf
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 6e18560e5084..faaa4bc09329 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,16 +13,35 @@
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <signal.h>
+#include <unistd.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
+/*
+ * when timerid argument does not correspond to a timer ID returned by
+ * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also
+ * 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;
 	int tval = BOGUSTID;
+	struct sigaction sa = { .sa_handler = sigsegv_handler };
+
 	tid = (timer_t) & tval;
 
+	sigfillset(&sa.sa_mask);
+	sigaction(SIGSEGV, &sa, NULL);
+
 	if (timer_getoverrun(tid) == -1) {
 		if (EINVAL == errno) {
 			printf("fcn returned -1 and errno=EINVAL\n");
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 d09c2f70901d..91c8aaad59c6 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,16 +13,36 @@
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <signal.h>
+#include <unistd.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
+/*
+ * when timerid argument does not correspond to a timer ID returned by
+ * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also
+ * 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)
 {
 	timer_t tid;
 	struct itimerspec its;
 	int tval = BOGUSTID;
+	struct sigaction sa = { .sa_handler = sigsegv_handler };
+
 	tid = (timer_t) & tval;
+
+	sigfillset(&sa.sa_mask);
+	sigaction(SIGSEGV, &sa, NULL);
+
 	if (timer_gettime(tid, &its) == -1) {
 		if (EINVAL == errno) {
 			printf("fcn returned -1 and errno==EINVAL\n");
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 5d4e1dda30ba..092ca723975d 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,16 +12,36 @@
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <signal.h>
+#include <unistd.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
+/*
+ * when timerid argument does not correspond to a timer ID returned by
+ * timer_create(), POSIX recommends EINVAL, but SIGSEGV is also
+ * 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)
 {
 	timer_t tid;
 	struct itimerspec its;
 	int tval = BOGUSTID;
+	struct sigaction sa = { .sa_handler = sigsegv_handler };
+
 	tid = (timer_t) & tval;
+
+	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