Unverified Commit 245561ba authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Palmer Dabbelt
Browse files

lkdtm: Fix CFI_BACKWARD on RISC-V



On RISC-V, the return address is before the current frame pointer,
unlike on most other architectures. Use the correct offset on RISC-V
to fix the CFI_BACKWARD test.

Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
Acked-by: default avatarKees Cook <keescook@chromium.org>
Tested-by: default avatarNathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/r/20230927224757.1154247-14-samitolvanen@google.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent c40fef85
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -68,12 +68,20 @@ static void lkdtm_CFI_FORWARD_PROTO(void)
#define no_pac_addr(addr)      \
	((__force __typeof__(addr))((uintptr_t)(addr) | PAGE_OFFSET))

#ifdef CONFIG_RISCV
/* https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#frame-pointer-convention */
#define FRAME_RA_OFFSET		(-1)
#else
#define FRAME_RA_OFFSET		1
#endif

/* The ultimate ROP gadget. */
static noinline __no_ret_protection
void set_return_addr_unchecked(unsigned long *expected, unsigned long *addr)
{
	/* Use of volatile is to make sure final write isn't seen as a dead store. */
	unsigned long * volatile *ret_addr = (unsigned long **)__builtin_frame_address(0) + 1;
	unsigned long * volatile *ret_addr =
		(unsigned long **)__builtin_frame_address(0) + FRAME_RA_OFFSET;

	/* Make sure we've found the right place on the stack before writing it. */
	if (no_pac_addr(*ret_addr) == expected)
@@ -88,7 +96,8 @@ static noinline
void set_return_addr(unsigned long *expected, unsigned long *addr)
{
	/* Use of volatile is to make sure final write isn't seen as a dead store. */
	unsigned long * volatile *ret_addr = (unsigned long **)__builtin_frame_address(0) + 1;
	unsigned long * volatile *ret_addr =
		(unsigned long **)__builtin_frame_address(0) + FRAME_RA_OFFSET;

	/* Make sure we've found the right place on the stack before writing it. */
	if (no_pac_addr(*ret_addr) == expected)