Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <lkp@intel.com>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Kees Cook <kees@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.1742852847.git.jpoimboe@kernel.org
Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/

authored by

Josh Poimboeuf and committed by
Ingo Molnar
05026ea0 29c578c8

+11 -3
+11 -3
drivers/misc/lkdtm/perms.c
··· 29 29 static unsigned long ro_after_init __ro_after_init = 0x55AA5500; 30 30 31 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 + 38 + /* 32 39 * This just returns to the caller. It is designed to be copied into 33 40 * non-executable memory regions. 34 41 */ ··· 72 65 { 73 66 void (*func)(void); 74 67 func_desc_t fdesc; 75 - void *do_nothing_text = dereference_function_descriptor(do_nothing); 76 68 77 - pr_info("attempting ok execution at %px\n", do_nothing_text); 69 + pr_info("attempting ok execution at %px\n", do_nothing_ptr); 78 70 do_nothing(); 79 71 80 72 if (write == CODE_WRITE) { 81 - memcpy(dst, do_nothing_text, EXEC_SIZE); 73 + memcpy(dst, do_nothing_ptr, EXEC_SIZE); 82 74 flush_icache_range((unsigned long)dst, 83 75 (unsigned long)dst + EXEC_SIZE); 84 76 } ··· 273 267 274 268 void __init lkdtm_perms_init(void) 275 269 { 270 + do_nothing_ptr = dereference_function_descriptor(do_nothing); 271 + 276 272 /* Make sure we can write to __ro_after_init values during __init */ 277 273 ro_after_init |= 0xAA; 278 274 }