mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 06:10:56 +00:00
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: Sami Tolvanen <samitolvanen@google.com> Acked-by: Kees Cook <keescook@chromium.org> Tested-by: Nathan Chancellor <nathan@kernel.org> Link: https://lore.kernel.org/r/20230927224757.1154247-14-samitolvanen@google.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
c40fef858d
commit
245561ba6d
1 changed files with 11 additions and 2 deletions
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue