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.

Merge tag 'locking-urgent-2021-11-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 static call update from Thomas Gleixner:
"A single fix for static calls to make the trampoline patching more
robust by placing explicit signature bytes after the call trampoline
to prevent patching random other jumps like the CFI jump table
entries"

* tag 'locking-urgent-2021-11-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
static_call,x86: Robustify trampoline patching

+14 -4
+1
arch/x86/include/asm/static_call.h
··· 27 27 ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ 28 28 STATIC_CALL_TRAMP_STR(name) ": \n" \ 29 29 insns " \n" \ 30 + ".byte 0x53, 0x43, 0x54 \n" \ 30 31 ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ 31 32 ".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \ 32 33 ".popsection \n")
+10 -4
arch/x86/kernel/static_call.c
··· 56 56 text_poke_bp(insn, code, size, emulate); 57 57 } 58 58 59 - static void __static_call_validate(void *insn, bool tail) 59 + static void __static_call_validate(void *insn, bool tail, bool tramp) 60 60 { 61 61 u8 opcode = *(u8 *)insn; 62 + 63 + if (tramp && memcmp(insn+5, "SCT", 3)) { 64 + pr_err("trampoline signature fail"); 65 + BUG(); 66 + } 62 67 63 68 if (tail) { 64 69 if (opcode == JMP32_INSN_OPCODE || ··· 79 74 /* 80 75 * If we ever trigger this, our text is corrupt, we'll probably not live long. 81 76 */ 82 - WARN_ONCE(1, "unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn); 77 + pr_err("unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn); 78 + BUG(); 83 79 } 84 80 85 81 static inline enum insn_type __sc_insn(bool null, bool tail) ··· 103 97 mutex_lock(&text_mutex); 104 98 105 99 if (tramp) { 106 - __static_call_validate(tramp, true); 100 + __static_call_validate(tramp, true, true); 107 101 __static_call_transform(tramp, __sc_insn(!func, true), func); 108 102 } 109 103 110 104 if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site) { 111 - __static_call_validate(site, tail); 105 + __static_call_validate(site, tail, false); 112 106 __static_call_transform(site, __sc_insn(!func, tail), func); 113 107 } 114 108
+3
tools/objtool/check.c
··· 3310 3310 if (!insn->func) 3311 3311 return false; 3312 3312 3313 + if (insn->func->static_call_tramp) 3314 + return true; 3315 + 3313 3316 /* 3314 3317 * CONFIG_UBSAN_TRAP inserts a UD2 when it sees 3315 3318 * __builtin_unreachable(). The BUG() macro has an unreachable() after