Follow @Openwall on Twitter for new release announcements and other news
[<prev] [<thread-prev] [day] [month] [year] [list]
Message-Id: <549bd118-2d30-462d-bda0-9ddadb96a40e@app.fastmail.com>
Date: Wed, 04 Nov 2026 10:12:03 +0100
From: "Imre Kaloz" <kaloz@...nel.org>
To: "Rich Felker" <dalias@...c.org>
Cc: musl@...ts.openwall.com
Subject: Re: [PATCH 04/10] add SYSCALL_RT_SIGACTION_RESTORER hook for sparc

Hi Rich,

On Wed, Nov 4, 2026, at 04:44, Rich Felker wrote:

> I think this patch misses other places SYS_rt_sigaction is used, and
> puts arch-specific ifdefs we shouldn't be doing inline each place the
> syscall is used.

Right, abort() still makes the generic call, which on sparc passes
_NSIG/8 as the restorer and no valid sigsetsize, so resetting SIGABRT
to SIG_DFL fails.

> Probably we should either (or both) replace direct use of the syscall
> with a __sys_sigaction (like __sys_open, etc.) defined in
> src/internal/syscall.h if the arch doesn't first define it, or #undef
> SYS_rt_sigaction on sparc and have a case for where that's not
> defined, to be safe against missing instances of its use or adding new
> ones with silent breakage.

I'd do both. The generic part is below as an RFC; with it, sparc64
would define

#define __sys_sigaction(sig,sa,old) \
	__syscall(__NR_rt_sigaction,sig,sa,old,__restore,_NSIG/8)
#undef SYS_rt_sigaction

> Note that since __restore and __restore_rt are the same,
> __sys_sigaction does not need a conditional on flags. It can just
> always pass __restore in the extra slot.

They are on sparc64. 32-bit sparc builds a different frame for
handlers without SA_SIGINFO and returns from it with sigreturn rather
than rt_sigreturn, so there the restorer has to follow SA_SIGINFO:

#define __sys_sigaction(sig,sa,old) \
	__syscall(__NR_rt_sigaction,sig,sa,old, \
		(long)(sa) && ((sa)->flags & SA_SIGINFO) ? __restore_rt : __restore, \
		_NSIG/8)
#undef SYS_rt_sigaction

(sa is tested as an integer because gcc warns on the address of
abort's compound literal.) Does this look right before I fold it
into v2?


Thanks,
Imre

-- >8 --
Subject: abstract rt_sigaction syscall with __sys_sigaction

archs whose rt_sigaction takes different arguments (sparc passes the
signal restorer ahead of sigsetsize) can define __sys_sigaction in
syscall_arch.h; the default is the generic rt_sigaction call.

sigaction and abort both use it, so a direct use of SYS_rt_sigaction
elsewhere cannot bypass an arch's definition. an arch that defines it
can also undefine SYS_rt_sigaction to catch new uses at build time.

there is no codegen change for existing archs.
---
 src/exit/abort.c       | 3 +--
 src/internal/syscall.h | 4 ++++
 src/signal/sigaction.c | 2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/exit/abort.c b/src/exit/abort.c
index f21f458e..10b5d199 100644
--- a/src/exit/abort.c
+++ b/src/exit/abort.c
@@ -17,8 +17,7 @@ _Noreturn void abort(void)
 	 * the default action of abnormal termination. */
 	__block_all_sigs(0);
 	LOCK(__abort_lock);
-	__syscall(SYS_rt_sigaction, SIGABRT,
-		&(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8);
+	__sys_sigaction(SIGABRT, &(struct k_sigaction){.handler = SIG_DFL}, 0);
 	__syscall(SYS_tkill, __pthread_self()->tid, SIGABRT);
 	__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
 		&(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8);
diff --git a/src/internal/syscall.h b/src/internal/syscall.h
index 2d8a5c13..fc1254c0 100644
--- a/src/internal/syscall.h
+++ b/src/internal/syscall.h
@@ -414,6 +414,10 @@ hidden long __emulate_wait4(int, int *, int, void *, int);
 #define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d))
 #define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d))
 
+#ifndef __sys_sigaction
+#define __sys_sigaction(sig,sa,old) __syscall(SYS_rt_sigaction,sig,sa,old,_NSIG/8)
+#endif
+
 hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
 
 hidden void *__vdsosym(const char *, const char *);
diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
index e45308fa..622aed52 100644
--- a/src/signal/sigaction.c
+++ b/src/signal/sigaction.c
@@ -51,7 +51,7 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
 #endif
 		memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
 	}
-	int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
+	int r = __sys_sigaction(sig, sa?&ksa:0, old?&ksa_old:0);
 	if (old && !r) {
 		old->sa_handler = ksa_old.handler;
 		old->sa_flags = ksa_old.flags;

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.