Re: [PATCH v16 01/18] seccomp: Convert __secure_computing() to return boolean
From: Michal Suchánek <hidden>
Date: 2026-07-03 07:51:07
Also in:
linux-alpha, linux-m68k, linux-mips, linux-mm, linux-s390, linux-sh, lkml, loongarch
On Mon, Jun 29, 2026 at 09:05:59PM +0800, Jinjie Ruan wrote:
quoted hunk ↗ jump to hunk
The return value of __secure_computing() currently uses 0 to indicate that a system call should be allowed, and -1 to indicate that it should be blocked/killed. This 0/-1 pattern is non-intuitive for a security check function and makes the control flow at the call sites less readable. Furthermore, any potential future changes to these return values would require a high-risk, error-prone audit of all its users across different architectures. Sanitize this logic by converting the return type of __secure_computing() to a proper boolean, where 'true' explicitly means 'allow' and 'false' means 'fail/deny'. Update all the two dozen or so call sites across the tree to align with this new boolean semantic. No functional changes are intended, as the callers still return -1 to the lower-level assembly entry code upon seccomp denial. Suggested-by: Thomas Gleixner <tglx@kernel.org> Signed-off-by: Jinjie Ruan <redacted> --- arch/alpha/kernel/ptrace.c | 2 +- arch/arm/kernel/ptrace.c | 2 +- arch/arm64/kernel/ptrace.c | 2 +- arch/csky/kernel/ptrace.c | 2 +- arch/m68k/kernel/ptrace.c | 2 +- arch/mips/kernel/ptrace.c | 2 +- arch/parisc/kernel/ptrace.c | 2 +- arch/sh/kernel/ptrace_32.c | 2 +- arch/um/kernel/skas/syscall.c | 2 +- arch/x86/entry/vsyscall/vsyscall_64.c | 2 +- arch/xtensa/kernel/ptrace.c | 3 +-- include/linux/entry-common.h | 7 +++--- include/linux/seccomp.h | 10 ++++---- kernel/seccomp.c | 34 +++++++++++++-------------- 14 files changed, 36 insertions(+), 38 deletions(-)diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 0687760ea466..27d9847b1082 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c@@ -387,7 +387,7 @@ asmlinkage unsigned long syscall_trace_enter(void) * If this fails, seccomp may already have set up the return value * (e.g. SECCOMP_RET_ERRNO / TRACE). */ - if (secure_computing() == -1) { + if (!secure_computing()) { if (regs->r19 == 0 && regs->r0 == (unsigned long)-1) syscall_set_return_value(current, regs, -ENOSYS, 0); syscall_set_nr(current, regs, -1);diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 7951b2c06fec..5210745725ca 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c@@ -855,7 +855,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) /* Do seccomp after ptrace; syscall may have changed. */ #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER - if (secure_computing() == -1) + if (!secure_computing()) return -1; #else /* XXX: remove this once OABI gets fixed */diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 4d08598e2891..2ca6fab39a37 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c@@ -2420,7 +2420,7 @@ int syscall_trace_enter(struct pt_regs *regs) } /* Do the secure computing after ptrace; failures should be fast. */ - if (secure_computing() == -1) + if (!secure_computing()) return NO_SYSCALL; if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c index 6bb685a2646b..11c5eff41e9d 100644 --- a/arch/csky/kernel/ptrace.c +++ b/arch/csky/kernel/ptrace.c@@ -323,7 +323,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) if (ptrace_report_syscall_entry(regs)) return -1; - if (secure_computing() == -1) + if (!secure_computing()) return -1; if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index cfa2df24eced..d2411404b9df 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c@@ -281,7 +281,7 @@ asmlinkage int syscall_trace_enter(void) if (test_thread_flag(TIF_SYSCALL_TRACE)) ret = ptrace_report_syscall_entry(task_pt_regs(current)); - if (secure_computing() == -1) + if (!secure_computing()) return -1; return ret;diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 3f4c94c88124..0d809cda7542 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c@@ -1328,7 +1328,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs) return -1; } - if (secure_computing()) + if (!secure_computing()) return -1;
Hello, I am not fond of this logic inversion. The boolean is meaningless in itself. Previously -1 was used to indicate that the syscall was filtered but you chose to invert the logic choosing true to mean syscall was not filtered. You could choose true to mean that syscall was fitered avoiding this inversion. Sashiko points out some places in existing code where it supposedly explodes which might or might not be true but any in-flight patches that use secure_computing would also be affected. Also please document what the value actually means. I do not see that added as part of these series. As either interpretation of the boolean value is equally valid it needs to be documented which one was chosen. While there is a code comment in one of the functions that secure_computing() calls I could not find any documentation for the return value of secure_computing. This could add a kernel-doc comment while touching the code anyway https://www.kernel.org/doc/html/v7.2-rc1/doc-guide/kernel-doc.html Thanks Michal
quoted hunk ↗ jump to hunk
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 8a17ab7e6e0b..565b51a48c8a 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c@@ -351,7 +351,7 @@ long do_syscall_trace_enter(struct pt_regs *regs) } /* Do the secure computing check after ptrace. */ - if (secure_computing() == -1) + if (!secure_computing()) return -1; #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTSdiff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 06f765d71a29..8687f17cbe5a 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c@@ -460,7 +460,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) return -1; } - if (secure_computing() == -1) + if (!secure_computing()) return -1; if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index ba7494f9bfe4..916cd7acceaf 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c@@ -27,7 +27,7 @@ void handle_syscall(struct uml_pt_regs *r) goto out; /* Do the seccomp check after ptrace; failures should be fast. */ - if (secure_computing() == -1) + if (!secure_computing()) goto out; syscall = UPT_SYSCALL_NR(r);diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c index ea36de9fa864..6aed3987b9f9 100644 --- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c@@ -198,7 +198,7 @@ static bool __emulate_vsyscall(struct pt_regs *regs, unsigned long address) regs->orig_ax = syscall_nr; regs->ax = -ENOSYS; tmp = secure_computing(); - if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) { + if ((tmp && regs->orig_ax != syscall_nr) || regs->ip != address) { warn_bad_vsyscall(KERN_DEBUG, regs, "seccomp tried to change syscall nr or ip"); force_exit_sig(SIGSYS);diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index b80d54b2ea34..ef78fcd318ff 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c@@ -553,8 +553,7 @@ int do_syscall_trace_enter(struct pt_regs *regs) return 0; } - if (regs->syscall == NO_SYSCALL || - secure_computing() == -1) { + if (regs->syscall == NO_SYSCALL || !secure_computing()) { do_syscall_trace_leave(regs); return 0; }diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h index 416a3352261f..3f66320e46d3 100644 --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h@@ -100,9 +100,8 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l /* Do seccomp after ptrace, to catch any tracer changes. */ if (work & SYSCALL_WORK_SECCOMP) { - ret = __secure_computing(); - if (ret == -1L) - return ret; + if (!__secure_computing()) + return -1L; } /* Either of the above might have changed the syscall number */@@ -113,7 +112,7 @@ static __always_inline long syscall_trace_enter(struct pt_regs *regs, unsigned l syscall_enter_audit(regs, syscall); - return ret ? : syscall; + return syscall; } /**diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 9b959972bf4a..7af3173f40e9 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h@@ -22,14 +22,14 @@ #include <linux/atomic.h> #include <asm/seccomp.h> -extern int __secure_computing(void); +extern bool __secure_computing(void); #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER -static inline int secure_computing(void) +static inline bool secure_computing(void) { if (unlikely(test_syscall_work(SECCOMP))) return __secure_computing(); - return 0; + return true; } #else extern void secure_computing_strict(int this_syscall);@@ -50,11 +50,11 @@ static inline int seccomp_mode(struct seccomp *s) struct seccomp_data; #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER -static inline int secure_computing(void) { return 0; } +static inline bool secure_computing(void) { return true; } #else static inline void secure_computing_strict(int this_syscall) { return; } #endif -static inline int __secure_computing(void) { return 0; } +static inline bool __secure_computing(void) { return true; } static inline long prctl_get_seccomp(void) {diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 066909393c38..1fec6efedab6 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c@@ -1100,12 +1100,12 @@ void secure_computing_strict(int this_syscall) else BUG(); } -int __secure_computing(void) +bool __secure_computing(void) { int this_syscall = syscall_get_nr(current, current_pt_regs()); secure_computing_strict(this_syscall); - return 0; + return true; } #else@@ -1256,7 +1256,7 @@ static int seccomp_do_user_notification(int this_syscall, return -1; } -static int __seccomp_filter(int this_syscall, const bool recheck_after_trace) +static bool __seccomp_filter(int this_syscall, const bool recheck_after_trace) { u32 filter_ret, action; struct seccomp_data sd;@@ -1294,7 +1294,7 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace) case SECCOMP_RET_TRACE: /* We've been put in this state by the ptracer already. */ if (recheck_after_trace) - return 0; + return true; /* ENOSYS these calls if there is no tracer attached. */ if (!ptrace_event_enabled(current, PTRACE_EVENT_SECCOMP)) {@@ -1330,19 +1330,19 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace) * a skip would have already been reported. */ if (__seccomp_filter(this_syscall, true)) - return -1; + return false; - return 0; + return true; case SECCOMP_RET_USER_NOTIF: if (seccomp_do_user_notification(this_syscall, match, &sd)) goto skip; - return 0; + return true; case SECCOMP_RET_LOG: seccomp_log(this_syscall, 0, action, true); - return 0; + return true; case SECCOMP_RET_ALLOW: /*@@ -1350,7 +1350,7 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace) * this action since SECCOMP_RET_ALLOW is the starting * state in seccomp_run_filters(). */ - return 0; + return true; case SECCOMP_RET_KILL_THREAD: case SECCOMP_RET_KILL_PROCESS:@@ -1367,46 +1367,46 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace) } else { do_exit(SIGSYS); } - return -1; /* skip the syscall go directly to signal handling */ + return false; /* skip the syscall go directly to signal handling */ } unreachable(); skip: seccomp_log(this_syscall, 0, action, match ? match->log : false); - return -1; + return false; } #else -static int __seccomp_filter(int this_syscall, const bool recheck_after_trace) +static bool __seccomp_filter(int this_syscall, const bool recheck_after_trace) { BUG(); - return -1; + return false; } #endif -int __secure_computing(void) +bool __secure_computing(void) { int mode = current->seccomp.mode; int this_syscall; if (IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) && unlikely(current->ptrace & PT_SUSPEND_SECCOMP)) - return 0; + return true; this_syscall = syscall_get_nr(current, current_pt_regs()); switch (mode) { case SECCOMP_MODE_STRICT: __secure_computing_strict(this_syscall); /* may call do_exit */ - return 0; + return true; case SECCOMP_MODE_FILTER: return __seccomp_filter(this_syscall, false); /* Surviving SECCOMP_RET_KILL_* must be proactively impossible. */ case SECCOMP_MODE_DEAD: WARN_ON_ONCE(1); do_exit(SIGKILL); - return -1; + return false; default: BUG(); }-- 2.34.1