Skip to content

Commit 218cc8b

Browse files
committed
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
2 parents fc661f2 + 2105a92 commit 218cc8b

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

arch/x86/include/asm/static_call.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
".globl " STATIC_CALL_TRAMP_STR(name) " \n" \
2828
STATIC_CALL_TRAMP_STR(name) ": \n" \
2929
insns " \n" \
30+
".byte 0x53, 0x43, 0x54 \n" \
3031
".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \
3132
".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \
3233
".popsection \n")

arch/x86/kernel/static_call.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,15 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, void
5656
text_poke_bp(insn, code, size, emulate);
5757
}
5858

59-
static void __static_call_validate(void *insn, bool tail)
59+
static void __static_call_validate(void *insn, bool tail, bool tramp)
6060
{
6161
u8 opcode = *(u8 *)insn;
6262

63+
if (tramp && memcmp(insn+5, "SCT", 3)) {
64+
pr_err("trampoline signature fail");
65+
BUG();
66+
}
67+
6368
if (tail) {
6469
if (opcode == JMP32_INSN_OPCODE ||
6570
opcode == RET_INSN_OPCODE)
@@ -74,7 +79,8 @@ static void __static_call_validate(void *insn, bool tail)
7479
/*
7580
* If we ever trigger this, our text is corrupt, we'll probably not live long.
7681
*/
77-
WARN_ONCE(1, "unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn);
82+
pr_err("unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn);
83+
BUG();
7884
}
7985

8086
static inline enum insn_type __sc_insn(bool null, bool tail)
@@ -97,12 +103,12 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
97103
mutex_lock(&text_mutex);
98104

99105
if (tramp) {
100-
__static_call_validate(tramp, true);
106+
__static_call_validate(tramp, true, true);
101107
__static_call_transform(tramp, __sc_insn(!func, true), func);
102108
}
103109

104110
if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site) {
105-
__static_call_validate(site, tail);
111+
__static_call_validate(site, tail, false);
106112
__static_call_transform(site, __sc_insn(!func, tail), func);
107113
}
108114

tools/objtool/check.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,6 +3310,9 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
33103310
if (!insn->func)
33113311
return false;
33123312

3313+
if (insn->func->static_call_tramp)
3314+
return true;
3315+
33133316
/*
33143317
* CONFIG_UBSAN_TRAP inserts a UD2 when it sees
33153318
* __builtin_unreachable(). The BUG() macro has an unreachable() after

0 commit comments

Comments
 (0)