Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH] openposix: timer_*/speculative: Handle SIGSEGV on old glibc
@ 2026-09-29 12:47 Avinesh Kumar via ltp
  2026-09-29 17:50 ` [LTP] " linuxtestproject.agent
  2026-09-29 19:31 ` [LTP] [PATCH v2] openposix: timer_*/speculative: fork() to isolate the " Avinesh Kumar via ltp
  0 siblings, 2 replies; 9+ messages in thread
From: Avinesh Kumar via ltp @ 2026-09-29 12:47 UTC (permalink / raw)
  To: ltp

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


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [LTP] openposix: timer_*/speculative: Handle SIGSEGV on old glibc
  2026-09-29 12:47 [LTP] [PATCH] openposix: timer_*/speculative: Handle SIGSEGV on old glibc Avinesh Kumar via ltp
@ 2026-09-29 17:50 ` linuxtestproject.agent
  2026-09-29 19:31 ` [LTP] [PATCH v2] openposix: timer_*/speculative: fork() to isolate the " Avinesh Kumar via ltp
  1 sibling, 0 replies; 9+ messages in thread
From: linuxtestproject.agent @ 2026-09-29 17:50 UTC (permalink / raw)
  To: Avinesh Kumar; +Cc: ltp

Hi Avinesh,

On Tue Sep 29 14:47:54 2026 +0200, Avinesh Kumar wrote:
> openposix: timer_*/speculative: Handle SIGSEGV on old glibc

> 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 dce9277b5..c7a94e144 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);

Catching SIGSEGV and exiting with PTS_PASS circumvents the check for
errno=EINVAL and masks faults instead of verifying the interface. Use
"static int tval = BOGUSTIMERID; timer_t tid = (timer_t)&tval;" without a
signal handler instead; this provides a readable pointer for older glibc
(<= 2.31) while keeping the MSB clear so glibc >= 2.34 and musl do not
treat it as a SIGEV_THREAD timer.

> 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 3a8f1448d..7861e99d4 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);

Same issue here; pass a pointer to a static int variable instead of
handling SIGSEGV.

> 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 586b0ed3a..a3a9e080e 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);

Same issue here; pass a pointer to a static int variable instead of
handling SIGSEGV.

> 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 ac7f7bf24..953d585b8 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);

Same issue here; pass a pointer to a static int variable instead of
handling SIGSEGV.

Verdict - Needs revision

---
Note:

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v2] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-29 12:47 [LTP] [PATCH] openposix: timer_*/speculative: Handle SIGSEGV on old glibc Avinesh Kumar via ltp
  2026-09-29 17:50 ` [LTP] " linuxtestproject.agent
@ 2026-09-29 19:31 ` Avinesh Kumar via ltp
  2026-09-29 22:04   ` [LTP] " linuxtestproject.agent
  1 sibling, 1 reply; 9+ messages in thread
From: Avinesh Kumar via ltp @ 2026-09-29 19:31 UTC (permalink / raw)
  To: ltp

From: Avinesh Kumar <avinesh.kumar@suse.com>

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:

  timer_delete_sp[13131]: segfault at 186a3 ip 00007f15973aed4e sp 00007ffefb52c5a0 error 4 in librt-2.31.so[7f15973aa000+8000]

fork() a child to make the call, then inspect the child's exit status.
POSIX defines no required behavior for an invalid timer ID (EINVAL is
only a recommendation), so the child dying from any signal is treated
as success.

Fixes: d377d1cff1ec ("openposix: timer_*/speculative: Don't pass a stack pointer as timerid")
Suggested-by: Martin Doucha <mdoucha@suse.cz>
Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
---
 .../interfaces/timer_delete/speculative/5-1.c | 50 +++++++++++-----
 .../timer_getoverrun/speculative/6-1.c        | 49 ++++++++++-----
 .../timer_gettime/speculative/6-1.c           | 52 +++++++++++-----
 .../timer_settime/speculative/12-1.c          | 60 +++++++++++++------
 4 files changed, 145 insertions(+), 66 deletions(-)

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..d1857efead18 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
@@ -5,34 +5,52 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
 
- * Test to see if timer_delete() returns -1 and sets errno==EINVAL if
- * timerid is not a valid timer ID or not.
- * Since this is a "may" requirement, either option is a PASS.
+ * Test to see if timer_delete() sets errno==EINVAL for an invalid
+ * timerid. Since this is a "may" requirement, succeeding or crashing
+ * are equally valid outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTIMERID 99999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	timer_t tid = (timer_t)BOGUSTIMERID;
-
-	if (timer_delete(tid) == -1) {
-		if (errno == EINVAL) {
-			printf
-			    ("timer_delete() returned -1 and set errno=EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf
-			    ("timer_delete() returned -1, but didn't set errno!=EINVAL\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		timer_t tid = (timer_t) BOGUSTIMERID;
+
+		if (timer_delete(tid) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
+	}
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if (WIFSIGNALED(status) || (WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
 	}
 
-	printf("timer_delete() did not return -1\n");
-	return PTS_PASS;
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
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..6da435430879 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
@@ -5,33 +5,52 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test to see if timer_getoverrun() sets errno=EINVAL if no timers have been
- * created yet or not.  Since this is a "may" assertion, either way is
- * a pass.
+ * Test to see if timer_getoverrun() sets errno==EINVAL for an invalid
+ * timerid. Since this is a "may" assertion, succeeding or crashing
+ * are equally valid outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	timer_t tid = (timer_t)BOGUSTID;
-
-	if (timer_getoverrun(tid) == -1) {
-		if (EINVAL == errno) {
-			printf("fcn returned -1 and errno=EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf("fcn returned -1, but errno!=EINVAL\n");
-			printf("Test FAILED\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		timer_t tid = (timer_t) BOGUSTID;
+
+		if (timer_getoverrun(tid) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
+	}
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if (WIFSIGNALED(status) || (WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
 	}
 
-	printf("fcn did not return -1\n");
-	return PTS_PASS;
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
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..ec153e9866da 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
@@ -5,33 +5,53 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test to see if timer_gettime() sets errno = EINVAL if no timers have been
- * created yet and it is called with a bogus timer ID.  Since this is a "may"
- * assertion, either way is pass.
+ * Test to see if timer_gettime() sets errno==EINVAL for an invalid
+ * timerid. Since this is a "may" assertion, succeeding or crashing
+ * are equally valid outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	struct itimerspec its;
-	timer_t tid = (timer_t)BOGUSTID;
-
-	if (timer_gettime(tid, &its) == -1) {
-		if (EINVAL == errno) {
-			printf("fcn returned -1 and errno==EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf("fcn returned -1 but errno!=EINVAL\n");
-			printf("Test FAILED\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		struct itimerspec its;
+		timer_t tid = (timer_t) BOGUSTID;
+
+		if (timer_gettime(tid, &its) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
 	}
-	printf("fcn did not return -1\n");
-	return PTS_PASS;
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if (WIFSIGNALED(status) || (WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
+	}
+
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
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..f4400ce0dd64 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
@@ -5,36 +5,58 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test to see if timer_settime() sets errno = EINVAL if no timers have been
- * created yet.  Since this is a "may" assertion, either way is a pass.
+ * Test to see if timer_settime() sets errno==EINVAL for an invalid
+ * timerid. Since this is a "may" assertion, succeeding or crashing
+ * are equally valid outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	struct itimerspec its;
-	timer_t tid = (timer_t)BOGUSTID;
-	its.it_interval.tv_sec = 0;
-	its.it_interval.tv_nsec = 0;
-	its.it_value.tv_sec = 0;
-	its.it_value.tv_nsec = 0;
-
-	if (timer_settime(tid, 0, &its, NULL) == -1) {
-		if (EINVAL == errno) {
-			printf("fcn returned -1 and errno==EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf("fcn returned -1, but errno!=EINVAL\n");
-			printf("Test FAILED\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		struct itimerspec its;
+		timer_t tid = (timer_t) BOGUSTID;
+
+		its.it_interval.tv_sec = 0;
+		its.it_interval.tv_nsec = 0;
+		its.it_value.tv_sec = 0;
+		its.it_value.tv_nsec = 0;
+
+		if (timer_settime(tid, 0, &its, NULL) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
 	}
-	printf("fcn did not return -1\n");
-	return PTS_PASS;
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if (WIFSIGNALED(status) || (WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
+	}
+
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
-- 
2.55.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [LTP] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-29 19:31 ` [LTP] [PATCH v2] openposix: timer_*/speculative: fork() to isolate the " Avinesh Kumar via ltp
@ 2026-09-29 22:04   ` linuxtestproject.agent
  2026-09-30  7:35     ` Petr Vorel
  0 siblings, 1 reply; 9+ messages in thread
From: linuxtestproject.agent @ 2026-09-29 22:04 UTC (permalink / raw)
  To: Avinesh Kumar; +Cc: ltp

Hi Avinesh,

On Tue, 29 Sep 2026 21:31:15 +0200, Avinesh Kumar wrote:
> openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc

>  * Test to see if timer_delete() sets errno==EINVAL for an invalid
>  * timerid. Since this is a "may" requirement, succeeding or crashing
>  * are equally valid outcomes.

POSIX "may fail" requirements define that returning -1 with EINVAL or
succeeding are valid outcomes; crashing is undefined behavior due to
pointer dereference on older glibc, not a defined requirement outcome.
Please update the comments across all four tests to clarify that returning
-1 with EINVAL, succeeding, or crashing (on older glibc) are accepted.

> +	if (WIFSIGNALED(status) || (WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
> +		printf("Test PASSED\n");
> +		return PTS_PASS;
> +	}

WIFSIGNALED(status) without checking WTERMSIG(status) treats any terminating
signal as success, which masks abnormal process exits (such as SIGABRT or
SIGSYS) as well as test cancellation (e.g. SIGINT or test-runner SIGTERM).
Check for the expected fault explicitly with WIFSIGNALED(status) &&
(WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS), and use PTS_PASS
instead of literal 0 for WEXITSTATUS(status). This applies to all four tests.

> +		if (timer_delete(tid) == -1) {
> +			if (errno == EINVAL)
> +				_exit(PTS_PASS);
> +			_exit(PTS_FAIL);
> +		}
>
> +	printf("Test FAILED\n");
> +	return PTS_FAIL;

Printing only "Test FAILED" removes diagnostic information when the timer
call fails with an unexpected errno, violating Open POSIX result reporting
rules. The child should print the unexpected errno before calling _exit(),
or the parent should report the reason for failure before returning PTS_FAIL.

Verdict - Needs revision

---
Note:

The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.

Regards,
LTP AI Reviewer

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-29 22:04   ` [LTP] " linuxtestproject.agent
@ 2026-09-30  7:35     ` Petr Vorel
  2026-09-30  8:46       ` [LTP] [PATCH v3] " Avinesh Kumar via ltp
  0 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2026-09-30  7:35 UTC (permalink / raw)
  To: linuxtestproject.agent; +Cc: ltp

Hi Avinesh,

unfortunately all agent complains sounds reasonable, would you mind to send v3?

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [LTP] [PATCH v3] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-30  7:35     ` Petr Vorel
@ 2026-09-30  8:46       ` Avinesh Kumar via ltp
  2026-09-30  9:10         ` Petr Vorel
  0 siblings, 1 reply; 9+ messages in thread
From: Avinesh Kumar via ltp @ 2026-09-30  8:46 UTC (permalink / raw)
  To: ltp

From: Avinesh Kumar <avinesh.kumar@suse.com>

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:

  timer_delete_sp[13131]: segfault at 186a3 ip 00007f15973aed4e sp 00007ffefb52c5a0 error 4 in librt-2.31.so[7f15973aa000+8000]

fork() a child to make the call, then inspect the child's exit status.
POSIX defines no required behavior for an invalid timer ID (EINVAL is
only a recommendation), so the child being killed by SIGSEGV or SIGBUS
is treated as success.

Fixes: d377d1cff1ec ("openposix: timer_*/speculative: Don't pass a stack pointer as timerid")
Suggested-by: Martin Doucha <mdoucha@suse.cz>
Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
---
 .../interfaces/timer_delete/speculative/5-1.c | 56 +++++++++++-----
 .../timer_getoverrun/speculative/6-1.c        | 55 +++++++++++-----
 .../timer_gettime/speculative/6-1.c           | 58 +++++++++++-----
 .../timer_settime/speculative/12-1.c          | 66 +++++++++++++------
 4 files changed, 169 insertions(+), 66 deletions(-)

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..8e7d1b2e54dc 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
@@ -5,34 +5,58 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
 
- * Test to see if timer_delete() returns -1 and sets errno==EINVAL if
- * timerid is not a valid timer ID or not.
- * Since this is a "may" requirement, either option is a PASS.
+ * Test to see if timer_delete() sets errno==EINVAL for an invalid
+ * timerid. Recent POSIX versions leave this behavior undefined, so
+ * returning -1 with EINVAL, succeeding, or crashing (older glibc
+ * dereferences timerid as a pointer) are all accepted outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTIMERID 99999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	timer_t tid = (timer_t)BOGUSTIMERID;
-
-	if (timer_delete(tid) == -1) {
-		if (errno == EINVAL) {
-			printf
-			    ("timer_delete() returned -1 and set errno=EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf
-			    ("timer_delete() returned -1, but didn't set errno!=EINVAL\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		timer_t tid = (timer_t) BOGUSTIMERID;
+
+		if (timer_delete(tid) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			printf("timer_delete() returned -1, but errno=%d (%s), not EINVAL\n", errno, strerror(errno));
+			fflush(stdout);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
+	}
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if ((WIFSIGNALED(status) && (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS)) ||
+		(WIFEXITED(status) && WEXITSTATUS(status) == PTS_PASS)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
 	}
 
-	printf("timer_delete() did not return -1\n");
-	return PTS_PASS;
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
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..fbc0edc38f94 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
@@ -5,33 +5,58 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test to see if timer_getoverrun() sets errno=EINVAL if no timers have been
- * created yet or not.  Since this is a "may" assertion, either way is
- * a pass.
+ * Test to see if timer_getoverrun() sets errno==EINVAL for an invalid
+ * timerid. Recent POSIX versions leave this behavior undefined, so
+ * returning -1 with EINVAL, succeeding, or crashing (older glibc
+ * dereferences timerid as a pointer) are all accepted outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	timer_t tid = (timer_t)BOGUSTID;
-
-	if (timer_getoverrun(tid) == -1) {
-		if (EINVAL == errno) {
-			printf("fcn returned -1 and errno=EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf("fcn returned -1, but errno!=EINVAL\n");
-			printf("Test FAILED\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		timer_t tid = (timer_t) BOGUSTID;
+
+		if (timer_getoverrun(tid) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			printf("timer_getoverrun() returned -1, but errno=%d (%s), not EINVAL\n", errno, strerror(errno));
+			fflush(stdout);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
+	}
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if ((WIFSIGNALED(status) && (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS)) ||
+		(WIFEXITED(status) && WEXITSTATUS(status) == PTS_PASS)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
 	}
 
-	printf("fcn did not return -1\n");
-	return PTS_PASS;
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
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..4bc1e7b43843 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
@@ -5,33 +5,59 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test to see if timer_gettime() sets errno = EINVAL if no timers have been
- * created yet and it is called with a bogus timer ID.  Since this is a "may"
- * assertion, either way is pass.
+ * Test to see if timer_gettime() sets errno==EINVAL for an invalid
+ * timerid. Recent POSIX versions leave this behavior undefined, so
+ * returning -1 with EINVAL, succeeding, or crashing (older glibc
+ * dereferences timerid as a pointer) are all accepted outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	struct itimerspec its;
-	timer_t tid = (timer_t)BOGUSTID;
-
-	if (timer_gettime(tid, &its) == -1) {
-		if (EINVAL == errno) {
-			printf("fcn returned -1 and errno==EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf("fcn returned -1 but errno!=EINVAL\n");
-			printf("Test FAILED\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		struct itimerspec its;
+		timer_t tid = (timer_t) BOGUSTID;
+
+		if (timer_gettime(tid, &its) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			printf("timer_gettime() returned -1, but errno=%d (%s), not EINVAL\n", errno, strerror(errno));
+			fflush(stdout);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
 	}
-	printf("fcn did not return -1\n");
-	return PTS_PASS;
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if ((WIFSIGNALED(status) && (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS)) ||
+		(WIFEXITED(status) && WEXITSTATUS(status) == PTS_PASS)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
+	}
+
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
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..0ae7ee28201c 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
@@ -5,36 +5,64 @@
  * of this license, see the COPYING file at the top level of this
  * source tree.
  *
- * Test to see if timer_settime() sets errno = EINVAL if no timers have been
- * created yet.  Since this is a "may" assertion, either way is a pass.
+ * Test to see if timer_settime() sets errno==EINVAL for an invalid
+ * timerid. Recent POSIX versions leave this behavior undefined, so
+ * returning -1 with EINVAL, succeeding, or crashing (older glibc
+ * dereferences timerid as a pointer) are all accepted outcomes.
  */
 
 #include <time.h>
 #include <stdio.h>
 #include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
 #include "posixtest.h"
 
 #define BOGUSTID 9999
 
 int test_main(int argc PTS_ATTRIBUTE_UNUSED, char **argv PTS_ATTRIBUTE_UNUSED)
 {
-	struct itimerspec its;
-	timer_t tid = (timer_t)BOGUSTID;
-	its.it_interval.tv_sec = 0;
-	its.it_interval.tv_nsec = 0;
-	its.it_value.tv_sec = 0;
-	its.it_value.tv_nsec = 0;
-
-	if (timer_settime(tid, 0, &its, NULL) == -1) {
-		if (EINVAL == errno) {
-			printf("fcn returned -1 and errno==EINVAL\n");
-			return PTS_PASS;
-		} else {
-			printf("fcn returned -1, but errno!=EINVAL\n");
-			printf("Test FAILED\n");
-			return PTS_FAIL;
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("fork");
+		return PTS_UNRESOLVED;
+	}
+
+	if (pid == 0) {
+		struct itimerspec its;
+		timer_t tid = (timer_t) BOGUSTID;
+
+		its.it_interval.tv_sec = 0;
+		its.it_interval.tv_nsec = 0;
+		its.it_value.tv_sec = 0;
+		its.it_value.tv_nsec = 0;
+
+		if (timer_settime(tid, 0, &its, NULL) == -1) {
+			if (errno == EINVAL)
+				_exit(PTS_PASS);
+			printf("timer_settime() returned -1, but errno=%d (%s), not EINVAL\n", errno, strerror(errno));
+			fflush(stdout);
+			_exit(PTS_FAIL);
 		}
+		_exit(PTS_PASS);
 	}
-	printf("fcn did not return -1\n");
-	return PTS_PASS;
+
+	if (waitpid(pid, &status, 0) == -1) {
+		perror("waitpid");
+		return PTS_UNRESOLVED;
+	}
+
+	if ((WIFSIGNALED(status) && (WTERMSIG(status) == SIGSEGV || WTERMSIG(status) == SIGBUS)) ||
+		(WIFEXITED(status) && WEXITSTATUS(status) == PTS_PASS)) {
+		printf("Test PASSED\n");
+		return PTS_PASS;
+	}
+
+	printf("Test FAILED\n");
+	return PTS_FAIL;
 }
-- 
2.55.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v3] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-30  8:46       ` [LTP] [PATCH v3] " Avinesh Kumar via ltp
@ 2026-09-30  9:10         ` Petr Vorel
  2026-09-30 10:12           ` Cyril Hrubis
  0 siblings, 1 reply; 9+ messages in thread
From: Petr Vorel @ 2026-09-30  9:10 UTC (permalink / raw)
  To: Avinesh Kumar; +Cc: ltp

Hi Avinesh,

> 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:

>   timer_delete_sp[13131]: segfault at 186a3 ip 00007f15973aed4e sp 00007ffefb52c5a0 error 4 in librt-2.31.so[7f15973aa000+8000]

> fork() a child to make the call, then inspect the child's exit status.
> POSIX defines no required behavior for an invalid timer ID (EINVAL is
> only a recommendation), so the child being killed by SIGSEGV or SIGBUS
> is treated as success.

> Fixes: d377d1cff1ec ("openposix: timer_*/speculative: Don't pass a stack pointer as timerid")
> Suggested-by: Martin Doucha <mdoucha@suse.cz>
> Signed-off-by: Avinesh Kumar <avinesh.kumar@suse.com>
> ---
>  .../interfaces/timer_delete/speculative/5-1.c | 56 +++++++++++-----
>  .../timer_getoverrun/speculative/6-1.c        | 55 +++++++++++-----
>  .../timer_gettime/speculative/6-1.c           | 58 +++++++++++-----
>  .../timer_settime/speculative/12-1.c          | 66 +++++++++++++------
>  4 files changed, 169 insertions(+), 66 deletions(-)

> 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..8e7d1b2e54dc 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
> @@ -5,34 +5,58 @@
>   * of this license, see the COPYING file at the top level of this
>   * source tree.

> - * Test to see if timer_delete() returns -1 and sets errno==EINVAL if
> - * timerid is not a valid timer ID or not.
> - * Since this is a "may" requirement, either option is a PASS.
> + * Test to see if timer_delete() sets errno==EINVAL for an invalid
> + * timerid. Recent POSIX versions leave this behavior undefined, so

nit: I suggest before merge to mention the version:

"Recent POSIX versions leave" => "/Since POSIX 2016 Edition is"

(no need for v4). Why? In 5+ years we can hopefully delete those tests.
Specifying the version saves somebody searching it again.

The code itself LGTM.
Reviewed-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v3] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-30  9:10         ` Petr Vorel
@ 2026-09-30 10:12           ` Cyril Hrubis
  2026-09-30 12:02             ` Petr Vorel
  0 siblings, 1 reply; 9+ messages in thread
From: Cyril Hrubis @ 2026-09-30 10:12 UTC (permalink / raw)
  To: Petr Vorel; +Cc: ltp

Hi!
> nit: I suggest before merge to mention the version:
> 
> "Recent POSIX versions leave" => "/Since POSIX 2016 Edition is"
> 
> (no need for v4). Why? In 5+ years we can hopefully delete those tests.
> Specifying the version saves somebody searching it again.
> 
> The code itself LGTM.
> Reviewed-by: Petr Vorel <pvorel@suse.cz>

Agree, with that minor change:

Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

Also I find this safe enough to be applied before release as this change
touches only a few speculative tests.

-- 
Cyril Hrubis
chrubis@suse.cz

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [LTP] [PATCH v3] openposix: timer_*/speculative: fork() to isolate the SIGSEGV on old glibc
  2026-09-30 10:12           ` Cyril Hrubis
@ 2026-09-30 12:02             ` Petr Vorel
  0 siblings, 0 replies; 9+ messages in thread
From: Petr Vorel @ 2026-09-30 12:02 UTC (permalink / raw)
  To: Cyril Hrubis; +Cc: ltp

> Hi!
> > nit: I suggest before merge to mention the version:

> > "Recent POSIX versions leave" => "/Since POSIX 2016 Edition is"

> > (no need for v4). Why? In 5+ years we can hopefully delete those tests.
> > Specifying the version saves somebody searching it again.

> > The code itself LGTM.
> > Reviewed-by: Petr Vorel <pvorel@suse.cz>

> Agree, with that minor change:

> Reviewed-by: Cyril Hrubis <chrubis@suse.cz>

> Also I find this safe enough to be applied before release as this change
> touches only a few speculative tests.

+1, merged. Thank you all.

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-09-30 12:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 12:47 [LTP] [PATCH] openposix: timer_*/speculative: Handle SIGSEGV on old glibc Avinesh Kumar via ltp
2026-09-29 17:50 ` [LTP] " linuxtestproject.agent
2026-09-29 19:31 ` [LTP] [PATCH v2] openposix: timer_*/speculative: fork() to isolate the " Avinesh Kumar via ltp
2026-09-29 22:04   ` [LTP] " linuxtestproject.agent
2026-09-30  7:35     ` Petr Vorel
2026-09-30  8:46       ` [LTP] [PATCH v3] " Avinesh Kumar via ltp
2026-09-30  9:10         ` Petr Vorel
2026-09-30 10:12           ` Cyril Hrubis
2026-09-30 12:02             ` Petr Vorel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox