On Fri, May 23, 2025 at 01:22:01AM -0700, Charlie Jenkins wrote: > On Thu, May 22, 2025 at 10:31:30PM -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 > > > > In case toolchain doesn't support cfi extension, cfi kselftest wont > > get built. > > > > 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> > > Suggested-by: Charlie Jenkins <charlie@xxxxxxxxxxxx> > > --- > > tools/testing/selftests/riscv/Makefile | 2 +- > > tools/testing/selftests/riscv/cfi/.gitignore | 3 + > > tools/testing/selftests/riscv/cfi/Makefile | 16 + > > 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, 687 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..55165a93845f > > --- /dev/null > > +++ b/tools/testing/selftests/riscv/cfi/Makefile > > @@ -0,0 +1,16 @@ > > +CFLAGS += -I$(top_srcdir)/tools/include > > + > > +CFLAGS += -march=rv64gc_zicfilp_zicfiss -fcf-protection=full > > + > > +ifeq ($(shell $(CC) $(CFLAGS) -nostdlib -xc /dev/null -o /dev/null > /dev/null 2>&1; echo $$?),0) > > +TEST_GEN_PROGS := cfitests > > + > > +include ../../lib.mk > > I'm sorry, I just realized I messed up this patch :/. This line is > supposed to be above the ifeq line to get the proper definition of > $(CC). Okay that doesn't work either, this does though.