Re: [PATCH] riscv: ptrace: reject CFI regset access when extensions are absent

Guo Ren <[email protected]>
Newsgroups org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel
Message-ID <CAJF2gTQ-_kSrtV_rpoMK2pKPM3q-CmgDwyX111XvM9oJ=oyDxg@mail.gmail.com>
On Thu, Aug 20, 2026 at 2:32 PM Chen Pei <[email protected]> wrote:
>
> riscv_cfi_get() and riscv_cfi_set() do not check whether the Zicfilp
> or Zicfiss extensions are present. On systems without them,
> PTRACE_GETREGSET on REGSET_CFI still succeeds and returns a zeroed
> user_cfi_state, misleading debuggers into believing the register set
> is available, and PTRACE_SETREGSET silently accepts writes that have
> no effect (e.g. clearing SR_ELP).
>
> Reject the access with -EINVAL when neither branch landing pads nor
> shadow stack is available to userspace, using the same availability
> helpers as the prctl path.
>
> Fixes: 2af7c9cf021c ("riscv/ptrace: expose riscv CFI status and state via ptrace and in core files")
Cc: [email protected]

> Signed-off-by: Chen Pei <[email protected]>
> ---
> This follows the behaviour of the arm64 GCS regset. Unlike vector
> registers, no ENODATA case applies here: the CFI status regset has a
> valid all-zero representation even when CFI has not been enabled for
> the traced task.
>
> is_user_lpad_enabled()/is_user_shstk_enabled() are used instead of a
> plain ISA check so that the regset visibility matches what userspace
> can actually use via prctl: both helpers also honor the
> riscv_nousercfi kernel command line switch.
>
>  arch/riscv/kernel/ptrace.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
> index f336a183667e..566856e42f65 100644
> --- a/arch/riscv/kernel/ptrace.c
> +++ b/arch/riscv/kernel/ptrace.c
> @@ -299,6 +299,9 @@ static int riscv_cfi_get(struct task_struct *target,
>         struct user_cfi_state user_cfi;
>         struct pt_regs *regs;
>
> +       if (!is_user_lpad_enabled() && !is_user_shstk_enabled())
Do you want:

/* If shadow stack is not supported or not enabled, nothing to ... */
if (!is_user_shstk_enabled() || !is_shstk_enabled(tsk))

> +               return -EINVAL;
> +
>         memset(&user_cfi, 0, sizeof(user_cfi));
>         regs = task_pt_regs(target);
>
> @@ -337,6 +340,9 @@ static int riscv_cfi_set(struct task_struct *target,
>         struct user_cfi_state user_cfi;
>         struct pt_regs *regs;
>
> +       if (!is_user_lpad_enabled() && !is_user_shstk_enabled())
> +               return -EINVAL;
> +
>         regs = task_pt_regs(target);
>
>         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &user_cfi, 0, -1);
> --
> 2.50.1
>


-- 
Best Regards
 Guo Ren

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
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.