All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Andy Lutomirski <luto@kernel.org>, Kees Cook <kees@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Thomas Gleixner <tglx@kernel.org>, Will Drewry <wad@chromium.org>
Cc: Kusaram Devineni <kusaram@devineni.in>,
	Max Ver <dudududumaxver@gmail.com>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 2/2] seccomp: defer syscall_rollback() to get_signal()
Date: Tue, 14 Apr 2026 18:48:20 +0200	[thread overview]
Message-ID: <ad5v1J7bosR88z7b@redhat.com> (raw)
In-Reply-To: <ad5voOrbqayQBgNk@redhat.com>

Currently, seccomp_nack_syscall() calls syscall_rollback() immediately.
Because this restores the original registers, the syscall exit path sees
the original syscall number as the return value.

This confuses audit_syscall_exit(), trace_syscall_exit(), and ptrace.

Change seccomp_nack_syscall() to call syscall_set_return_value(-EINTR),
and add the new check_force_sig_seccomp() helper called by get_signal()
which does syscall_rollback() if the signal was sent by seccomp.

Note that the si_code == SYS_SECCOMP check in check_force_sig_seccomp()
is not 100% reliable, see the comment in check_force_sig_seccomp(), but
I hope we don't really care.

Reported-by: Max Ver <dudududumaxver@gmail.com>
Closes: https://lore.kernel.org/all/CABjJbFJO+p3jA1r0gjUZrCepQb1Fab3kqxYhc_PSfoqo21ypeQ@mail.gmail.com/
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/seccomp.c |  4 ++--
 kernel/signal.c  | 20 ++++++++++++++++++++
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index cb8dd78791cd..a8d103054212 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -1258,8 +1258,8 @@ static int seccomp_do_user_notification(int this_syscall,
 
 static void seccomp_nack_syscall(int this_syscall, int data, bool force_coredump)
 {
-	/* Show the handler or coredump the original registers. */
-	syscall_rollback(current, current_pt_regs());
+	/* check_force_sig_seccomp() will restore the original registers */
+	syscall_set_return_value(current, current_pt_regs(), -EINTR, 0);
 	/* Let the filter pass back 16 bits of data. */
 	force_sig_seccomp(this_syscall, data, force_coredump);
 }
diff --git a/kernel/signal.c b/kernel/signal.c
index d65d0fe24bfb..b93e37517d6d 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2796,6 +2796,24 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig)
 	}
 }
 
+static inline void check_force_sig_seccomp(kernel_siginfo_t *info)
+{
+	/*
+	 * See seccomp_nack_syscall(). Show the original registers to
+	 * the handler or coredump.
+	 *
+	 * Note: a task can send a .si_code == SYS_SECCOMP signal to
+	 * itself, but syscall_rollback() is harmless in this case.
+	 * SYS_SECCOMP can also be missed if a prior SIGSYS was pending
+	 * and blocked before force_sig_seccomp(), but in that case the
+	 * seccomp siginfo is already lost anyway.
+	 */
+	if (IS_ENABLED(CONFIG_SECCOMP_FILTER)) {
+		if (info->si_code == SYS_SECCOMP)
+			syscall_rollback(current, current_pt_regs());
+	}
+}
+
 bool get_signal(struct ksignal *ksig)
 {
 	struct sighand_struct *sighand = current->sighand;
@@ -2916,6 +2934,8 @@ bool get_signal(struct ksignal *ksig)
 		if (!signr)
 			break; /* will return 0 */
 
+		check_force_sig_seccomp(&ksig->info);
+
 		if (unlikely(current->ptrace) && (signr != SIGKILL) &&
 		    !(sighand->action[signr -1].sa.sa_flags & SA_IMMUTABLE)) {
 			signr = ptrace_signal(signr, &ksig->info, type);
-- 
2.52.0


  parent reply	other threads:[~2026-04-14 16:48 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-14 16:47 [RFC PATCH 0/2] seccomp: defer syscall_rollback() to get_signal() Oleg Nesterov
2026-04-14 16:48 ` [RFC PATCH 1/2] seccomp: introduce seccomp_nack_syscall() helper Oleg Nesterov
2026-04-14 16:48 ` Oleg Nesterov [this message]
2026-04-14 17:27   ` [RFC PATCH 2/2] seccomp: defer syscall_rollback() to get_signal() Kees Cook
2026-04-14 17:41     ` Oleg Nesterov
2026-04-15 15:50       ` Kees Cook
2026-04-15 16:08         ` Oleg Nesterov
2026-04-15 10:44 ` [RFC PATCH 0/2] " Oleg Nesterov
2026-04-15 16:07   ` Kees Cook
2026-04-15 19:21   ` Kees Cook
2026-04-16 14:07     ` Oleg Nesterov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ad5v1J7bosR88z7b@redhat.com \
    --to=oleg@redhat.com \
    --cc=dudududumaxver@gmail.com \
    --cc=kees@kernel.org \
    --cc=kusaram@devineni.in \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@kernel.org \
    --cc=wad@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.