Skip to content

Commit

Permalink
Merge tag 'locking-urgent-2021-11-14' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
torvalds committed Nov 14, 2021
2 parents fc661f2 + 2105a92 commit 218cc8b
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/static_call.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
".globl " STATIC_CALL_TRAMP_STR(name) " \n" \
STATIC_CALL_TRAMP_STR(name) ": \n" \
insns " \n" \
".byte 0x53, 0x43, 0x54 \n" \
".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \
".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \
".popsection \n")
Expand Down
14 changes: 10 additions & 4 deletions arch/x86/kernel/static_call.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,15 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, void
text_poke_bp(insn, code, size, emulate);
}

static void __static_call_validate(void *insn, bool tail)
static void __static_call_validate(void *insn, bool tail, bool tramp)
{
u8 opcode = *(u8 *)insn;

if (tramp && memcmp(insn+5, "SCT", 3)) {
pr_err("trampoline signature fail");
BUG();
}

if (tail) {
if (opcode == JMP32_INSN_OPCODE ||
opcode == RET_INSN_OPCODE)
Expand All @@ -74,7 +79,8 @@ static void __static_call_validate(void *insn, bool tail)
/*
* If we ever trigger this, our text is corrupt, we'll probably not live long.
*/
WARN_ONCE(1, "unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn);
pr_err("unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn);
BUG();
}

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

if (tramp) {
__static_call_validate(tramp, true);
__static_call_validate(tramp, true, true);
__static_call_transform(tramp, __sc_insn(!func, true), func);
}

if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site) {
__static_call_validate(site, tail);
__static_call_validate(site, tail, false);
__static_call_transform(site, __sc_insn(!func, tail), func);
}

Expand Down
3 changes: 3 additions & 0 deletions tools/objtool/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -3310,6 +3310,9 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
if (!insn->func)
return false;

if (insn->func->static_call_tramp)
return true;

/*
* CONFIG_UBSAN_TRAP inserts a UD2 when it sees
* __builtin_unreachable(). The BUG() macro has an unreachable() after
Expand Down

0 comments on commit 218cc8b

Please sign in to comment.