Re: [PATCH v2] lkdtm: Add CFI_BACKWARD to test ROP mitigations

From: Daniel Díaz
Date: Tue Dec 06 2022 - 19:29:13 EST


Hello!

On Sat, 16 Apr 2022 at 00:30, Kees Cook <keescook@xxxxxxxxxxxx> wrote:
> In order to test various backward-edge control flow integrity methods,
> add a test that manipulates the return address on the stack. Currently
> only arm64 Pointer Authentication and Shadow Call Stack is supported.
>
> $ echo CFI_BACKWARD | cat >/sys/kernel/debug/provoke-crash/DIRECT
>
> Under SCS, successful test of the mitigation is reported as:
>
> lkdtm: Performing direct entry CFI_BACKWARD
> lkdtm: Attempting unchecked stack return address redirection ...
> lkdtm: ok: redirected stack return address.
> lkdtm: Attempting checked stack return address redirection ...
> lkdtm: ok: control flow unchanged.
>
> Under PAC, successful test of the mitigation is reported by the PAC
> exception handler:
>
> lkdtm: Performing direct entry CFI_BACKWARD
> lkdtm: Attempting unchecked stack return address redirection ...
> lkdtm: ok: redirected stack return address.
> lkdtm: Attempting checked stack return address redirection ...
> Unable to handle kernel paging request at virtual address bfffffc0088d0514
> Mem abort info:
> ESR = 0x86000004
> EC = 0x21: IABT (current EL), IL = 32 bits
> SET = 0, FnV = 0
> EA = 0, S1PTW = 0
> FSC = 0x04: level 0 translation fault
> [bfffffc0088d0514] address between user and kernel address ranges
> ...
>
> If the CONFIGs are missing (or the mitigation isn't working), failure
> is reported as:
>
> lkdtm: Performing direct entry CFI_BACKWARD
> lkdtm: Attempting unchecked stack return address redirection ...
> lkdtm: ok: redirected stack return address.
> lkdtm: Attempting checked stack return address redirection ...
> lkdtm: FAIL: stack return address was redirected!
> lkdtm: This is probably expected, since this kernel was built *without* CONFIG_ARM64_PTR_AUTH_KERNEL=y nor CONFIG_SHADOW_CALL_STACK=y
>
> Co-developed-by: Dan Li <ashimida@xxxxxxxxxxxxxxxxx>
> Signed-off-by: Dan Li <ashimida@xxxxxxxxxxxxxxxxx>
> Cc: Arnd Bergmann <arnd@xxxxxxxx>
> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx>
> ---
> v1: https://lore.kernel.org/lkml/20220413213917.711770-1-keescook@xxxxxxxxxxxx
> v2:
> - add PAGE_OFFSET setting for PAC bits (Dan Li)
> ---
> drivers/misc/lkdtm/cfi.c | 134 ++++++++++++++++++++++++
> tools/testing/selftests/lkdtm/tests.txt | 1 +
> 2 files changed, 135 insertions(+)
>
> diff --git a/drivers/misc/lkdtm/cfi.c b/drivers/misc/lkdtm/cfi.c
> index e88f778be0d5..804965a480b7 100644
> --- a/drivers/misc/lkdtm/cfi.c
> +++ b/drivers/misc/lkdtm/cfi.c
> @@ -3,6 +3,7 @@
> * This is for all the tests relating directly to Control Flow Integrity.
> */
> #include "lkdtm.h"
> +#include <asm/page.h>
>
> static int called_count;
>
> @@ -42,8 +43,141 @@ static void lkdtm_CFI_FORWARD_PROTO(void)
> pr_expected_config(CONFIG_CFI_CLANG);
> }
>
> +/*
> + * This can stay local to LKDTM, as there should not be a production reason
> + * to disable PAC && SCS.
> + */
> +#ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
> +# ifdef CONFIG_ARM64_BTI_KERNEL
> +# define __no_pac "branch-protection=bti"
> +# else
> +# define __no_pac "branch-protection=none"
> +# endif
> +# define __no_ret_protection __noscs __attribute__((__target__(__no_pac)))
> +#else
> +# define __no_ret_protection __noscs
> +#endif

We're seeing this problem with allmodconfig on arm64 and GCC 8 (this
one observed on 6.0.12-rc3):

-----8<----------8<----------8<-----
make --silent --keep-going --jobs=8
O=/home/tuxbuild/.cache/tuxmake/builds/2/build
CROSS_COMPILE_COMPAT=arm-linux-gnueabihf- ARCH=arm64
CROSS_COMPILE=aarch64-linux-gnu- 'CC=sccache aarch64-linux-gnu-gcc'
'HOSTCC=sccache gcc'
/builds/linux/drivers/misc/lkdtm/cfi.c:67:1: error: pragma or
attribute 'target("branch-protection=none")' is not valid
{
^
make[4]: *** [/builds/linux/scripts/Makefile.build:249:
drivers/misc/lkdtm/cfi.o] Error 1
make[4]: Target '__build' not remade because of errors.
make[3]: *** [/builds/linux/scripts/Makefile.build:465:
drivers/misc/lkdtm] Error 2
make[3]: Target '__build' not remade because of errors.
make[2]: *** [/builds/linux/scripts/Makefile.build:465: drivers/misc] Error 2
make[2]: Target '__build' not remade because of errors.
make[1]: *** [/builds/linux/Makefile:1852: drivers] Error 2
----->8---------->8---------->8-----

Reproducer: `tuxmake --runtime podman --target-arch arm64 --toolchain
gcc-8 --kconfig allmodconfig
CROSS_COMPILE_COMPAT=arm-linux-gnueabihf-`

Is this a legit problem?

Greetings!

Daniel Díaz
daniel.diaz@xxxxxxxxxx