Commit 37f57bd3 authored by Jim Shu's avatar Jim Shu Committed by Paul Walmsley
Browse files

arch/riscv: compile vdso with landing pad and shadow stack note



User mode tasks compiled with Zicfilp may call indirectly into the
vdso (like hwprobe indirect calls). Add support for compiling landing
pads into the vdso. Landing pad instructions in the vdso will be
no-ops for tasks which have not enabled landing pads. Furthermore, add
support for the C sources of the vdso to be compiled with shadow stack
and landing pads enabled as well.

Landing pad and shadow stack instructions are emitted only when the
VDSO_CFI cflags option is defined during compile.

Signed-off-by: default avatarJim Shu <jim.shu@sifive.com>
Reviewed-by: default avatarZong Li <zong.li@sifive.com>
Signed-off-by: default avatarDeepak Gupta <debug@rivosinc.com>
Tested-by: Andreas Korb <andreas.korb@aisec.fraunhofer.de> # QEMU, custom CVA6
Tested-by: default avatarValentin Haudiquet <valentin.haudiquet@canonical.com>
Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-23-b55691eacf4f@rivosinc.com


[pjw@kernel.org: cleaned up patch description, issues reported by checkpatch]
Signed-off-by: default avatarPaul Walmsley <pjw@kernel.org>
parent 41213bf2
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -81,9 +81,12 @@ riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
# Check if the toolchain supports Zabha
riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZABHA) := $(riscv-march-y)_zabha

KBUILD_BASE_ISA = -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
export KBUILD_BASE_ISA

# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
KBUILD_CFLAGS += $(KBUILD_BASE_ISA)

KBUILD_AFLAGS += -march=$(riscv-march-y)

+44 −0
Original line number Diff line number Diff line
@@ -80,3 +80,47 @@
	.endm

#endif	/* __ASM_ASSEMBLER_H */

#if defined(VDSO_CFI) && (__riscv_xlen == 64)
.macro vdso_lpad, label = 0
lpad \label
.endm
#else
.macro vdso_lpad, label = 0
.endm
#endif

/*
 * This macro emits a program property note section identifying
 * architecture features which require special handling, mainly for
 * use in assembly files included in the VDSO.
 */
#define NT_GNU_PROPERTY_TYPE_0  5
#define GNU_PROPERTY_RISCV_FEATURE_1_AND 0xc0000000

#define GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP		BIT(0)
#define GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS		BIT(1)

#if defined(VDSO_CFI) && (__riscv_xlen == 64)
#define GNU_PROPERTY_RISCV_FEATURE_1_DEFAULT \
	(GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP | GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS)
#endif

#ifdef GNU_PROPERTY_RISCV_FEATURE_1_DEFAULT
.macro emit_riscv_feature_1_and, feat = GNU_PROPERTY_RISCV_FEATURE_1_DEFAULT
	.pushsection .note.gnu.property, "a"
	.p2align        3
	.word           4
	.word           16
	.word           NT_GNU_PROPERTY_TYPE_0
	.asciz          "GNU"
	.word           GNU_PROPERTY_RISCV_FEATURE_1_AND
	.word           4
	.word           \feat
	.word           0
	.popsection
.endm
#else
.macro emit_riscv_feature_1_and, feat = 0
.endm
#endif
+10 −1
Original line number Diff line number Diff line
@@ -17,6 +17,11 @@ ifdef CONFIG_VDSO_GETRANDOM
vdso-syms += getrandom
endif

ifdef VDSO_CFI_BUILD
CFI_MARCH = _zicfilp_zicfiss
CFI_FULL = -fcf-protection=full
endif

# Files to link into the vdso
obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o

@@ -27,6 +32,10 @@ endif
ccflags-y := -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
ccflags-y += -fno-builtin
ccflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
ccflags-y += $(CFI_FULL)
asflags-y += $(KBUILD_BASE_ISA)$(CFI_MARCH)
asflags-y += $(CFI_FULL)

ifneq ($(c-gettimeofday-y),)
  CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
@@ -79,7 +88,7 @@ include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
# The DSO images are built using a special linker script
# Make sure only to export the intended __vdso_xxx symbol offsets.
quiet_cmd_vdsold_and_check = VDSOLD  $@
      cmd_vdsold_and_check = $(LD) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
      cmd_vdsold_and_check = $(LD) $(CFI_FULL) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
                   $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \
                   rm $@.tmp && \
                   $(cmd_vdso_check)
+4 −0
Original line number Diff line number Diff line
@@ -5,11 +5,13 @@

#include <linux/linkage.h>
#include <asm/unistd.h>
#include <asm/assembler.h>

	.text
/* int __vdso_flush_icache(void *start, void *end, unsigned long flags); */
SYM_FUNC_START(__vdso_flush_icache)
	.cfi_startproc
	vdso_lpad
#ifdef CONFIG_SMP
	li a7, __NR_riscv_flush_icache
	ecall
@@ -20,3 +22,5 @@ SYM_FUNC_START(__vdso_flush_icache)
	ret
	.cfi_endproc
SYM_FUNC_END(__vdso_flush_icache)

emit_riscv_feature_1_and
+4 −0
Original line number Diff line number Diff line
@@ -5,14 +5,18 @@

#include <linux/linkage.h>
#include <asm/unistd.h>
#include <asm/assembler.h>

	.text
/* int __vdso_getcpu(unsigned *cpu, unsigned *node, void *unused); */
SYM_FUNC_START(__vdso_getcpu)
	.cfi_startproc
	vdso_lpad
	/* For now, just do the syscall. */
	li a7, __NR_getcpu
	ecall
	ret
	.cfi_endproc
SYM_FUNC_END(__vdso_getcpu)

emit_riscv_feature_1_and
Loading