On Fri, May 02, 2025 at 04:30:58PM -0700, Deepak Gupta wrote: > Adds kselftest for RISC-V control flow integrity implementation for user > mode. There is not a lot going on in kernel for enabling landing pad for > user mode. cfi selftest are intended to be compiled with zicfilp and > zicfiss enabled compiler. Thus kselftest simply checks if landing pad / > shadow stack for the process are enabled or not and executes ptrace > selftests on cfi. selftest then register a signal handler for SIGSEGV. > Any control flow violation are reported as SIGSEGV with si_code = > SEGV_CPERR. Test will fail on receiving any SEGV_CPERR. Shadow stack part > has more changes in kernel and thus there are separate tests for that > > - Exercise `map_shadow_stack` syscall > - `fork` test to make sure COW works for shadow stack pages > - gup tests > Kernel uses FOLL_FORCE when access happens to memory via > /proc/<pid>/mem. Not breaking that for shadow stack. > - signal test. Make sure signal delivery results in token creation on > shadow stack and consumes (and verifies) token on sigreturn > - shadow stack protection test. attempts to write using regular store > instruction on shadow stack memory must result in access faults > - ptrace test: adds landing pad violation, clears ELP and continues > > Test outut > ========== > > """ > TAP version 13 > 1..5 > This is to ensure shadow stack is indeed enabled and working > This is to ensure shadow stack is indeed enabled and working > ok 1 shstk fork test > ok 2 map shadow stack syscall > ok 3 shadow stack gup tests > ok 4 shadow stack signal tests > ok 5 memory protections of shadow stack memory > """ > > Signed-off-by: Deepak Gupta <debug@xxxxxxxxxxxx> > > squash > > Signed-off-by: Deepak Gupta <debug@xxxxxxxxxxxx> > --- > tools/testing/selftests/riscv/Makefile | 2 +- > tools/testing/selftests/riscv/cfi/.gitignore | 3 + > tools/testing/selftests/riscv/cfi/Makefile | 10 + > tools/testing/selftests/riscv/cfi/cfi_rv_test.h | 82 +++++ > tools/testing/selftests/riscv/cfi/riscv_cfi_test.c | 173 +++++++++ > tools/testing/selftests/riscv/cfi/shadowstack.c | 385 +++++++++++++++++++++ > tools/testing/selftests/riscv/cfi/shadowstack.h | 27 ++ > 7 files changed, 681 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/riscv/Makefile b/tools/testing/selftests/riscv/Makefile > index 099b8c1f46f8..5671b4405a12 100644 > --- a/tools/testing/selftests/riscv/Makefile > +++ b/tools/testing/selftests/riscv/Makefile > @@ -5,7 +5,7 @@ > ARCH ?= $(shell uname -m 2>/dev/null || echo not) > > ifneq (,$(filter $(ARCH),riscv)) > -RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector > +RISCV_SUBTARGETS ?= abi hwprobe mm sigreturn vector cfi > else > RISCV_SUBTARGETS := > endif > diff --git a/tools/testing/selftests/riscv/cfi/.gitignore b/tools/testing/selftests/riscv/cfi/.gitignore > new file mode 100644 > index 000000000000..82545863bac6 > --- /dev/null > +++ b/tools/testing/selftests/riscv/cfi/.gitignore > @@ -0,0 +1,3 @@ > +cfitests > +riscv_cfi_test > +shadowstack > diff --git a/tools/testing/selftests/riscv/cfi/Makefile b/tools/testing/selftests/riscv/cfi/Makefile > new file mode 100644 > index 000000000000..1fa27cc10fb5 > --- /dev/null > +++ b/tools/testing/selftests/riscv/cfi/Makefile > @@ -0,0 +1,10 @@ > +CFLAGS += -I$(top_srcdir)/tools/include > + > +CFLAGS += -march=rv64gc_zicfilp_zicfiss -fcf-protection=full I am worried about the developer workflows that this will impact. Trying to build kselftest with TARGETS=riscv will fail if the toolchain does not support -fcf-protection=full. How about we skip these tests if the compiler can't compile it instead? Something like: