I'm seeing aborts of the test-sigdelay1 and test-sigdelay2 tests on
OpenBSD and on 32-bit Cygwin.

The cause is the use of signal numbers >= NSIG, together with an
incorrect use of the sigismember() function. sigismember() does not
return a boolean value; it returns a negative value for invalid
signal numbers.

To fix this, here are two patches:
  - Change sigismember() invocations to treat invalid signal numbers
    like signals that are not in the set.
  - Avoid iterating over invalid signal numbers in the first place.


2026-04-16  Bruno Haible  <[email protected]>

        sigdelay: Don't use out-of-range signal numbers.
        * lib/sigdelay.c (states): Change number of elements to NSIG.

        sigdelay, posix-spawn-internal: Ignore out-of-range signal numbers.
        * lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
        * lib/spawni.c (__spawni): Likewise.

>From 9bb54c2fe5d2ffe5fc44085f32e7d2cde31c18f8 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 16 Apr 2026 14:14:38 +0200
Subject: [PATCH 1/2] sigdelay, posix-spawn-internal: Ignore out-of-range
 signal numbers.

* lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
* lib/spawni.c (__spawni): Likewise.
---
 ChangeLog      | 6 ++++++
 lib/sigdelay.c | 2 +-
 lib/spawni.c   | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 67e90f524b..55f69d5198 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2026-04-16  Bruno Haible  <[email protected]>
+
+	sigdelay, posix-spawn-internal: Ignore out-of-range signal numbers.
+	* lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
+	* lib/spawni.c (__spawni): Likewise.
+
 2026-04-16  Bruno Haible  <[email protected]>
 
 	sigprocmask: Fix sigismember function.
diff --git a/lib/sigdelay.c b/lib/sigdelay.c
index d69fa6126b..ea0292ff90 100644
--- a/lib/sigdelay.c
+++ b/lib/sigdelay.c
@@ -76,7 +76,7 @@ sigdelay (int how, const sigset_t *restrict set, sigset_t *restrict old_set)
         sigaddset (old_set, sig);
 
   for (int sig = 1; sig < countof (states); sig++)
-    if (sigismember (set, sig))
+    if (sigismember (set, sig) > 0)
       {
         switch (how)
           {
diff --git a/lib/spawni.c b/lib/spawni.c
index 9e34e95c11..2ed0c69652 100644
--- a/lib/spawni.c
+++ b/lib/spawni.c
@@ -956,7 +956,7 @@ __spawni (pid_t *pid, const char *file,
       sa.sa_handler = SIG_DFL;
 
       for (int sig = 1; sig < NSIG; ++sig)
-        if (sigismember (&attrp->_sd, sig) != 0
+        if (sigismember (&attrp->_sd, sig) > 0
             && sigaction (sig, &sa, NULL) != 0)
           _exit (SPAWN_ERROR);
 
-- 
2.52.0

>From 0d791d4881ab315c4a30454cb574ac16cb2d4749 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email protected]>
Date: Thu, 16 Apr 2026 14:15:52 +0200
Subject: [PATCH 2/2] sigdelay: Don't use out-of-range signal numbers.

* lib/sigdelay.c (states): Change number of elements to NSIG.
---
 ChangeLog      | 3 +++
 lib/sigdelay.c | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 55f69d5198..899ef72c2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2026-04-16  Bruno Haible  <[email protected]>
 
+	sigdelay: Don't use out-of-range signal numbers.
+	* lib/sigdelay.c (states): Change number of elements to NSIG.
+
 	sigdelay, posix-spawn-internal: Ignore out-of-range signal numbers.
 	* lib/sigdelay.c (sigdelay): Do nothing when sigismember() returns -1.
 	* lib/spawni.c (__spawni): Likewise.
diff --git a/lib/sigdelay.c b/lib/sigdelay.c
index ea0292ff90..b85e816247 100644
--- a/lib/sigdelay.c
+++ b/lib/sigdelay.c
@@ -41,8 +41,8 @@ struct state
 };
 
 /* The state for all signals.
-   Size 32 would not be sufficient: On HP-UX, SIGXCPU = 33, SIGXFSZ = 34.  */
-static struct state states[64];
+   NSIG is the maximum signal number + 1.  */
+static struct state states[NSIG];
 
 static _GL_ASYNC_SAFE void
 delaying_handler (int sig)
-- 
2.52.0

Reply via email to