On Tue, Mar 17, 2026 at 9:20 AM Jinjie Ruan <[email protected]> wrote:

> Move the rseq_syscall() check earlier in the syscall exit path to ensure
> it operates on the original instruction pointer (regs->pc) before any
> potential modification by a tracer.
>
> [Background]
> When CONFIG_DEBUG_RSEQ is enabled, rseq_syscall() verifies that a system
> call was not executed within an rseq critical section by examining
> regs->pc. If a violation is detected, it triggers a SIGSEGV.
>
> [Problem]
> Currently, arm64 invokes rseq_syscall() after report_syscall_exit().
> However, during report_syscall_exit(), a ptrace tracer can modify the
> task's instruction pointer via PTRACE_SETREGS. This leads to an
> inconsistency where rseq may analyze a post-trace PC instead of the
> actual PC at the time of syscall exit.
>
> [Why this matters]
> The rseq check is intended to validate the execution context of the
> syscall itself. Analyzing a tracer-modified PC can lead to incorrect
> detection or missed violations. Moving the check earlier ensures rseq
> sees the authentic state of the task.
>
> [Alignment]
> This change aligns arm64 with:
> - Generic entry, which calls rseq_syscall() first.
> - arm32 implementation, which also performs the check before audit.
>
> [Impact]
> There is no functional change to signal delivery; SIGSEGV will still be
> processed in arm64_exit_to_user_mode() at the end of the exit path.
>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Will Deacon <[email protected]>
> Cc: Catalin Marinas <[email protected]>
> Reviewed-by: Kevin Brodsky <[email protected]>
> Signed-off-by: Jinjie Ruan <[email protected]>

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij

Reply via email to