[PATCH 11/11] signal: Remove SA_IMMUTABLE

From: Eric W. Biederman

Date: Fri Jun 26 2026 - 13:03:32 EST



Now that fatal signals experience short circuit delivery in
__send_signal_locked. There is no longer a race between sigaction
changing the signal handler and the signal handler being forced to
SIG_DFL, for fatal forced signals.

So remove SA_IMMUTABLE whose job it was to stop that race.
---
include/linux/signal_types.h | 3 ---
include/uapi/asm-generic/signal-defs.h | 1 -
kernel/signal.c | 9 +--------
3 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/include/linux/signal_types.h b/include/linux/signal_types.h
index caf4f7a59ab9..1a3bb540f1c7 100644
--- a/include/linux/signal_types.h
+++ b/include/linux/signal_types.h
@@ -70,9 +70,6 @@ struct ksignal {
int sig;
};

-/* Used to kill the race between sigaction and forced signals */
-#define SA_IMMUTABLE 0x00800000
-
#ifndef __ARCH_UAPI_SA_FLAGS
#ifdef SA_RESTORER
#define __ARCH_UAPI_SA_FLAGS SA_RESTORER
diff --git a/include/uapi/asm-generic/signal-defs.h b/include/uapi/asm-generic/signal-defs.h
index 7572f2f46ee8..fe929e7b77ca 100644
--- a/include/uapi/asm-generic/signal-defs.h
+++ b/include/uapi/asm-generic/signal-defs.h
@@ -45,7 +45,6 @@
#define SA_UNSUPPORTED 0x00000400
#define SA_EXPOSE_TAGBITS 0x00000800
/* 0x00010000 used on mips */
-/* 0x00800000 used for internal SA_IMMUTABLE */
/* 0x01000000 used on x86 */
/* 0x02000000 used on x86 */
/*
diff --git a/kernel/signal.c b/kernel/signal.c
index 0b602dfb0b78..d1decfef86c0 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1328,8 +1328,6 @@ force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t,
blocked = sigismember(&t->blocked, sig);
if (blocked || ignored || (handler != HANDLER_CURRENT)) {
action->sa.sa_handler = SIG_DFL;
- if (handler == HANDLER_EXIT)
- action->sa.sa_flags |= SA_IMMUTABLE;
if (blocked)
sigdelset(&t->blocked, sig);
}
@@ -2946,8 +2944,7 @@ bool get_signal(struct ksignal *ksig)
if (!signr)
break; /* will return 0 */

- if (unlikely(current->ptrace) && (signr != SIGKILL) &&
- !(sighand->action[signr -1].sa.sa_flags & SA_IMMUTABLE)) {
+ if (unlikely(current->ptrace) && (signr != SIGKILL)) {
signr = ptrace_signal(signr, &ksig->info, type);
if (!signr)
continue;
@@ -4351,10 +4348,6 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
k = &p->sighand->action[sig-1];

spin_lock_irq(&p->sighand->siglock);
- if (k->sa.sa_flags & SA_IMMUTABLE) {
- spin_unlock_irq(&p->sighand->siglock);
- return -EINVAL;
- }
if (oact)
*oact = *k;

--
2.41.0