Re: [PATCH v15 27/27] kselftest/riscv: kselftest for user mode cfi
From: Charlie Jenkins
Date: Tue May 20 2025 - 02:02:46 EST
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: