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