Skip to content

Commit 05026ea

Browse files
jpoimboeIngo Molnar
authored andcommitted
objtool, lkdtm: Obfuscate the do_nothing() pointer
If execute_location()'s memcpy of do_nothing() gets inlined and unrolled by the compiler, it copies one word at a time: mov 0x0(%rip),%rax R_X86_64_PC32 .text+0x1374 mov %rax,0x38(%rbx) mov 0x0(%rip),%rax R_X86_64_PC32 .text+0x136c mov %rax,0x30(%rbx) ... Those .text references point to the middle of the function, causing objtool to complain about their lack of ENDBR. Prevent that by resolving the function pointer at runtime rather than build time. This fixes the following warning: drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378 Reported-by: kernel test robot <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Reviewed-by: Kees Cook <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Linus Torvalds <[email protected]> Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
1 parent 29c578c commit 05026ea

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

drivers/misc/lkdtm/perms.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55;
2828
/* This is marked __ro_after_init, so it should ultimately be .rodata. */
2929
static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
3030

31+
/*
32+
* This is a pointer to do_nothing() which is initialized at runtime rather
33+
* than build time to avoid objtool IBT validation warnings caused by an
34+
* inlined unrolled memcpy() in execute_location().
35+
*/
36+
static void __ro_after_init *do_nothing_ptr;
37+
3138
/*
3239
* This just returns to the caller. It is designed to be copied into
3340
* non-executable memory regions.
@@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write)
6572
{
6673
void (*func)(void);
6774
func_desc_t fdesc;
68-
void *do_nothing_text = dereference_function_descriptor(do_nothing);
6975

70-
pr_info("attempting ok execution at %px\n", do_nothing_text);
76+
pr_info("attempting ok execution at %px\n", do_nothing_ptr);
7177
do_nothing();
7278

7379
if (write == CODE_WRITE) {
74-
memcpy(dst, do_nothing_text, EXEC_SIZE);
80+
memcpy(dst, do_nothing_ptr, EXEC_SIZE);
7581
flush_icache_range((unsigned long)dst,
7682
(unsigned long)dst + EXEC_SIZE);
7783
}
@@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
267273

268274
void __init lkdtm_perms_init(void)
269275
{
276+
do_nothing_ptr = dereference_function_descriptor(do_nothing);
277+
270278
/* Make sure we can write to __ro_after_init values during __init */
271279
ro_after_init |= 0xAA;
272280
}

0 commit comments

Comments
 (0)