Re: [PATCH] seccomp: Fix syscall skip logic on ptrace

Kees Cook <[email protected]>
Newsgroups gmane.linux.ports.ppc.embedded
Message-ID <202609011132.F4A3EB7103__30402.4608851009$1788287687$gmane$org@keescook>
On Tue, Jul 21, 2026 at 12:44:37PM +0200, Michal Suchanek wrote:
> seccomp takes a shortcut here. When the syscall number is re-read after
> ptrace and the sign bit is set in the syscall number the syscall is
> skipped right away.
> 
> This works fairly well on x86 where the return value of the syscall is
> preset before seccomp is processed.
> 
> However, on some architectures the syscall return value overlaps with
> the syscall number or syscall arguments, and as a result the return
> value cannot be preset in advance.
> 
> For these architectures seccomp needs to exit without flagging the
> syscall as skipped. Then processing of invalid syscall number in the
> architecture code should set the return value to -ENOSYS and skip the
> syscall.
> 
> This introduces a change: If the syscall number has the sign bit
> set, such as -1, previously the filter re-check would not be done, not
> applying the filter after trace. Now the re-check is done both for
> syscall nubers with and without sign bit set. This would only make a
> difference if the syscall number or the filter was changed by the
> tracer. Otherwise the filter would be resolved the first time around.
> 
> Signed-off-by: Michal Suchanek <[email protected]>
> ---
>  kernel/seccomp.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> index 066909393c38..9e40a38aaedf 100644
> --- a/kernel/seccomp.c
> +++ b/kernel/seccomp.c
> @@ -1318,11 +1318,8 @@ static int __seccomp_filter(int this_syscall, const bool recheck_after_trace)
>  		 */
>  		if (fatal_signal_pending(current))
>  			goto skip;
> -		/* Check if the tracer forced the syscall to be skipped. */
> -		this_syscall = syscall_get_nr(current, current_pt_regs());
> -		if (this_syscall < 0)
> -			goto skip;
>  
> +		this_syscall = syscall_get_nr(current, current_pt_regs());
>  		/*
>  		 * Recheck the syscall, since it may have changed. This
>  		 * intentionally uses a NULL struct seccomp_data to force

Does the seccomp selftest still pass with this change? I _think_ it's
fine; this just induces more work on a tracer-induced skip path, which,
in theory, shouldn't be fast-path: kicking out to the tracer is going to
be the slowest part.

-- 
Kees Cook
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.