summaryrefslogtreecommitdiff
path: root/arch/riscv/include
diff options
context:
space:
mode:
authorDeepak Gupta <debug@rivosinc.com>2026-01-25 21:09:55 -0700
committerPaul Walmsley <pjw@kernel.org>2026-01-29 02:38:40 -0700
commit66c9c713de597f9b40a319ebda4d3466ce2cdff0 (patch)
treec68ea2d67b694af0414648da28969e0bfa6c98e1 /arch/riscv/include
parent9d42fc28fc178e5031eddc6f80df561fc586caf4 (diff)
riscv/signal: save and restore the shadow stack on a signal
Save the shadow stack pointer in the sigcontext structure when delivering a signal. Restore the shadow stack pointer from sigcontext on sigreturn. As part of the save operation, the kernel uses the 'ssamoswap' instruction to save a snapshot of the current shadow stack on the shadow stack itself (this can be called a "save token"). During restore on sigreturn, the kernel retrieves the save token from the top of the shadow stack and validates it. This ensures that user mode can't arbitrarily pivot to any shadow stack address without having a token and thus provides a strong security assurance during the window between signal delivery and sigreturn. Use an ABI-compatible way of saving/restoring the shadow stack pointer into the signal stack. This follows the vector extension, where extra registers are placed in a form of extension header + extension body in the stack. The extension header indicates the size of the extra architectural states plus the size of header itself, and a magic identifier for the extension. Then, the extension body contains the new architectural states in the form defined by uapi. Signed-off-by: Andy Chiu <andy.chiu@sifive.com> Signed-off-by: Deepak Gupta <debug@rivosinc.com> Tested-by: Andreas Korb <andreas.korb@aisec.fraunhofer.de> Tested-by: Valentin Haudiquet <valentin.haudiquet@canonical.com> Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-17-b55691eacf4f@rivosinc.com [pjw@kernel.org: cleaned patch description, code comments; resolved checkpatch warning] Signed-off-by: Paul Walmsley <pjw@kernel.org>
Diffstat (limited to 'arch/riscv/include')
-rw-r--r--arch/riscv/include/asm/usercfi.h10
-rw-r--r--arch/riscv/include/uapi/asm/ptrace.h4
-rw-r--r--arch/riscv/include/uapi/asm/sigcontext.h1
3 files changed, 15 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
index 4501d741a609..ec4b8a53eb74 100644
--- a/arch/riscv/include/asm/usercfi.h
+++ b/arch/riscv/include/asm/usercfi.h
@@ -8,6 +8,7 @@
#ifndef __ASSEMBLER__
#include <linux/types.h>
#include <linux/prctl.h>
+#include <linux/errno.h>
struct task_struct;
struct kernel_clone_args;
@@ -34,6 +35,9 @@ bool is_shstk_locked(struct task_struct *task);
bool is_shstk_allocated(struct task_struct *task);
void set_shstk_lock(struct task_struct *task);
void set_shstk_status(struct task_struct *task, bool enable);
+unsigned long get_active_shstk(struct task_struct *task);
+int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr);
+int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_ptr);
bool is_indir_lp_enabled(struct task_struct *task);
bool is_indir_lp_locked(struct task_struct *task);
void set_indir_lp_status(struct task_struct *task, bool enable);
@@ -71,6 +75,12 @@ void set_indir_lp_lock(struct task_struct *task);
#define set_indir_lp_lock(task) do {} while (0)
+#define restore_user_shstk(tsk, shstk_ptr) -EINVAL
+
+#define save_user_shstk(tsk, saved_shstk_ptr) -EINVAL
+
+#define get_active_shstk(task) 0UL
+
#endif /* CONFIG_RISCV_USER_CFI */
#endif /* __ASSEMBLER__ */
diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index beff8df80ac9..261bfe70f60a 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -127,6 +127,10 @@ struct __riscv_v_regset_state {
*/
#define RISCV_MAX_VLENB (8192)
+struct __sc_riscv_cfi_state {
+ unsigned long ss_ptr; /* shadow stack pointer */
+};
+
#endif /* __ASSEMBLER__ */
#endif /* _UAPI_ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/include/uapi/asm/sigcontext.h b/arch/riscv/include/uapi/asm/sigcontext.h
index 748dffc9ae19..d22d0815d605 100644
--- a/arch/riscv/include/uapi/asm/sigcontext.h
+++ b/arch/riscv/include/uapi/asm/sigcontext.h
@@ -10,6 +10,7 @@
/* The Magic number for signal context frame header. */
#define RISCV_V_MAGIC 0x53465457
+#define RISCV_ZICFISS_MAGIC 0x9487
#define END_MAGIC 0x0
/* The size of END signal context header. */