linux/arch/riscv/kernel
Ziyi Guo 4d0697f192 riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp
Under CONFIG_SHADOW_CALL_STACK, handle_exception() reloads the kernel
shadow call stack pointer (gp) only when the trap came from userspace.
It made that decision with scs_load_current_if_task_changed, which
compares the trap-time tp (read back from sscratch into s5) against the
current tp:

	beq	\prev, tp, _skip_scs
	scs_load_current
_skip_scs:

tp is a user-writable register.  A user task that sets tp to the
linear-map address of its own task_struct (&current) before trapping
makes the comparison succeed (can achieve by brute force with KASLR
enable under our test), so the kernel skips scs_load_current and
keeps running with the gp that userspace left in place.  Under
CONFIG_SHADOW_CALL_STACK gp is the shadow call stack pointer and
load_global_pointer is a no-op, so the compiler-emitted
"sd ra, -8(gp)" / "ld ra, -8(gp)" in every non-leaf function then write
to, and return through, an attacker-controlled address -- an
unprivileged kernel arbitrary-write and control-flow-hijack primitive.
The poisoned gp is saved to task_struct.scs_sp on return, so the reload
is skipped on every subsequent entry as well.

Decide "came from userspace" from the hardware sstatus.SPP bit (already
in s1 at this point) instead of from tp, mirroring the check that
ret_from_exception already uses a few instructions later.  SPP is
written by hardware on trap entry and cannot be forged from U-mode.
Legitimate behaviour is unchanged: user entries (SPP=0) reload the task
shadow call stack, nested kernel entries (SPP=1) skip it.

Fixes: d1584d791a ("riscv: Implement Shadow Call Stack")
Signed-off-by: Ziyi Guo <guoziyi114@gmail.com>
Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
Link: https://patch.msgid.link/20261001135711.934152-1-guoziyi114@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
2026-10-07 19:38:05 -06:00
..
compat_vdso Makefile: remove redundant tool coverage variables 2024-05-14 23:35:48 +09:00
pi riscv: pi: replace strlcat with strscpy in get_early_cmdline 2026-06-06 20:17:52 -06:00
probes riscv: probes: simulate c.jal instruction 2026-08-07 19:24:29 -06:00
tests riscv: kprobes: add test case for c.jal instruction simulation 2026-08-07 19:24:29 -06:00
vdso random: vDSO: avoid call to memset() when zeroing reserved parameter 2026-10-02 12:12:13 +02:00
vdso_cfi riscv: vdso_cfi: Add .gitignore for build artifacts 2026-04-04 18:42:44 -06:00
vendor_extensions riscv: hwprobe: Add MIPS vendor extension probing 2025-09-19 10:33:56 -06:00
.gitignore
acpi_numa.c RISC-V: ACPI: Add acpi_get_cpu_uid() for unified ACPI CPU UID retrieval 2026-04-06 16:55:15 +02:00
acpi.c riscv: acpi: Enable ARCH_HAS_ACPI_TABLE_UPGRADE 2026-08-07 19:24:29 -06:00
alternative.c riscv: alternative: Also patch the compat vDSO 2026-08-07 19:24:34 -06:00
asm-offsets.c riscv: Fix 32-bit call_on_irq_stack() frame pointer ABI 2026-06-25 13:44:27 -06:00
bugs.c riscv: use sysfs_emit in cpu_show_ghostwrite 2026-06-06 20:17:52 -06:00
cacheinfo.c riscv: cacheinfo: Fix node reference leak in populate_cache_leaves 2026-06-06 23:48:15 -06:00
cfi.c cfi: Move BPF CFI types and helpers to generic code 2025-07-31 18:23:53 -07:00
compat_signal.c riscv: Fix register corruption from uninitialized cregs on error 2026-05-01 21:11:31 -06:00
compat_syscall_table.c riscv: convert to generic syscall table 2024-07-10 14:23:38 +02:00
copy-unaligned.h RISC-V: Report vector unaligned access speed hwprobe 2024-10-18 12:38:34 -07:00
copy-unaligned.S riscv: Define __riscv_copy_{,vec_}{words,bytes}_unaligned() using SYM_TYPED_FUNC_START 2026-04-29 20:38:17 -06:00
cpu_ops_sbi.c riscv: cpu_ops_sbi: No need to be bothered to check ret.error 2026-06-06 23:48:14 -06:00
cpu_ops_spinwait.c riscv: prevent pt_regs corruption for secondary idle threads 2024-05-30 09:42:51 -07:00
cpu_ops.c riscv: Use the same CPU operations for all CPUs 2024-01-04 15:03:07 -08:00
cpu-hotplug.c riscv: cpu_ops: Change return value type of cpu_is_stopped() to bool 2026-06-06 23:48:14 -06:00
cpu.c RISC-V: Don't print details of CPUs disabled in DT 2025-10-17 22:02:21 -06:00
cpufeature.c RISC-V: Clear HSTATUS.HU on CPU initialization 2026-10-05 19:02:38 -06:00
crash_dump.c
crash_save_regs.S
efi-header.S include: pe.h: Fix PE definitions 2025-05-21 16:46:37 +02:00
efi.c riscv: efi: Power off via EFI runtime services when available 2026-08-07 19:24:29 -06:00
entry.S riscv: entry: gate shadow call stack reload on sstatus.SPP, not tp 2026-10-07 19:38:05 -06:00
fpu.S RISC-V: Replace RISCV_MISALIGNED with RISCV_SCALAR_MISALIGNED 2024-10-18 12:38:32 -07:00
ftrace.c riscv: ftrace: Fix ftrace_modify_call failure on kprobed functions 2026-08-06 21:02:56 -06:00
head.h riscv: Remove support for XIP kernel 2026-04-04 18:42:44 -06:00
head.S riscv: Remove support for XIP kernel 2026-04-04 18:42:44 -06:00
hibernate-asm.S riscv: Use SYM_*() assembly macros instead of deprecated ones 2023-11-06 09:42:47 -08:00
hibernate.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
image-vars.h riscv: add platform-specific double word shifts for riscv32 2026-05-28 21:24:51 -07:00
irq.c riscv: panic if IRQ handler stacks cannot be allocated 2026-06-07 00:56:22 -06:00
jump_label.c riscv: Move nop definition to insn-def.h 2025-03-20 09:14:42 +00:00
kernel_mode_fpu.c riscv: add support for kernel-mode FPU 2024-05-19 14:36:19 -07:00
kernel_mode_vector.c RISC-V: KVM: fix vcpu vector context handling for kernel-mode vector 2026-08-13 13:20:02 +05:30
kexec_elf.c riscv: kexec: use min to simplify riscv_kexec_elf_load 2026-06-07 01:06:19 -06:00
kexec_image.c riscv: kexec_image: Fix dead link to boot-image-header.rst 2026-01-05 17:54:11 -07:00
kexec_relocate.S
kgdb.c riscv: kgdb: fix several debug register assignment bugs 2026-04-04 18:36:52 -06:00
machine_kexec_file.c riscv: kexec_file: Add support for crashkernel CMA reservation 2026-06-30 18:49:06 +03:00
machine_kexec.c riscv: Prevent NULL pointer dereference in machine_kexec_prepare() 2026-07-06 18:24:06 -06:00
Makefile riscv: Add support for srmcfg CSR from Ssqosid extension 2026-08-07 19:24:32 -06:00
Makefile.syscalls syscalls: fix syscall macros for newfstat/newfstatat 2024-08-02 15:20:47 +02:00
mcount-dyn.S riscv: fix various typos in comments and code 2026-04-04 18:42:39 -06:00
mcount.S riscv: fgraph: Fix stack layout to match __arch_ftrace_regs argument of ftrace_return_to_handler 2025-03-19 12:03:25 +00:00
module-sections.c riscv: module: Use generic cmp_int() instead of custom cmp_3way() 2026-06-06 20:17:53 -06:00
module.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
paravirt.c riscv/paravirt: Use common code for paravirt_steal_clock() 2026-01-12 16:47:33 +01:00
patch.c riscv: patch: fix handling of bpf-jit execmem addresses 2026-10-05 19:02:38 -06:00
perf_callchain.c The biggest change here is eliminating the awful idea that KVM had, of 2024-11-23 16:00:50 -08:00
perf_regs.c
process.c Revert "riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set" 2026-08-31 19:11:23 -06:00
ptrace.c riscv: ptrace: Zero-initialize regset buffers before copyin 2026-10-07 10:44:54 -06:00
qos.c riscv: Add support for srmcfg CSR from Ssqosid extension 2026-08-07 19:24:32 -06:00
reset.c riscv: Mark default_power_off() as __noreturn 2026-08-07 19:24:30 -06:00
return_address.c riscv: add CALLER_ADDRx support 2024-02-22 12:17:47 -08:00
riscv_ksyms.c riscv: Omit optimized string routines when using KASAN 2024-09-19 01:10:00 -07:00
sbi_ecall.c riscv: Fix RISCV_ALTERNATIVE_EARLY 2024-09-03 07:57:55 -07:00
sbi-ipi.c RISC-V: Enable the IPI before workqueue_online_cpu() 2024-08-01 07:15:43 -07:00
sbi.c riscv: sbi: Prefer SRST shutdown over legacy 2025-11-16 10:37:27 -07:00
setup.c RISC-V: Clear HSTATUS.HU on CPU initialization 2026-10-05 19:02:38 -06:00
signal.c riscv/signal: save and restore the shadow stack on a signal 2026-01-29 02:38:40 -07:00
smp.c genirq/proc: Increase default interrupt number precision to four 2026-05-26 16:21:14 +02:00
smpboot.c RISC-V: Clear HSTATUS.HU on CPU initialization 2026-10-05 19:02:38 -06:00
soc.c riscv: fix various typos in comments and code 2026-04-04 18:42:39 -06:00
stacktrace.c riscv: stacktrace: Remove bogus -0x4 offset in non-FP walk_stackframe 2026-06-06 23:48:15 -06:00
suspend_entry.S riscv: Remove support for XIP kernel 2026-04-04 18:42:44 -06:00
suspend.c RISC-V: Clear HSTATUS.HU on CPU initialization 2026-10-05 19:02:38 -06:00
sys_hwprobe.c riscv: hwprobe: initialize pair->value in hwprobe_one_pair() 2026-08-31 19:11:23 -06:00
sys_riscv.c riscv/mm: ensure PROT_WRITE leads to VM_READ | VM_WRITE 2026-01-25 21:09:53 -07:00
syscall_table.c riscv: convert to generic syscall table 2024-07-10 14:23:38 +02:00
time.c RISC-V: paravirt: Add skeleton for pv-time support 2023-12-30 11:25:03 +05:30
traps_misaligned.c riscv: traps_misaligned: Avoid redundant unaligned access speed probe 2026-06-08 10:47:22 -06:00
traps.c RISC-V updates for v7.3 2026-08-20 14:53:54 -07:00
unaligned_access_speed.c riscv: unaligned: stop using kthread for check_vector_unaligned_access() 2026-08-07 19:24:30 -06:00
usercfi.c riscv: use string helper in setup_global_riscv_enable() 2026-08-31 19:11:23 -06:00
vdso.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
vec-copy-unaligned.S riscv: Define __riscv_copy_{,vec_}{words,bytes}_unaligned() using SYM_TYPED_FUNC_START 2026-04-29 20:38:17 -06:00
vector.c riscv: vector: init vector context with proper vlenb 2026-02-09 15:27:33 -07:00
vendor_extensions.c riscv: Add xmipsexectl as a vendor extension 2025-09-18 20:36:00 -06:00
vmcore_info.c riscv: Remove support for XIP kernel 2026-04-04 18:42:44 -06:00
vmlinux.lds.S riscv: Remove support for XIP kernel 2026-04-04 18:42:44 -06:00