Commit 218cc8b8 authored by Linus Torvalds's avatar Linus Torvalds

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
parents fc661f2d 2105a927
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \
STATIC_CALL_TRAMP_STR(name) ": \n" \ STATIC_CALL_TRAMP_STR(name) ": \n" \
insns " \n" \ insns " \n" \
".byte 0x53, 0x43, 0x54 \n" \
".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \
".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \ ".size " STATIC_CALL_TRAMP_STR(name) ", . - " STATIC_CALL_TRAMP_STR(name) " \n" \
".popsection \n") ".popsection \n")
......
...@@ -56,10 +56,15 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, void ...@@ -56,10 +56,15 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, void
text_poke_bp(insn, code, size, emulate); 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; u8 opcode = *(u8 *)insn;
if (tramp && memcmp(insn+5, "SCT", 3)) {
pr_err("trampoline signature fail");
BUG();
}
if (tail) { if (tail) {
if (opcode == JMP32_INSN_OPCODE || if (opcode == JMP32_INSN_OPCODE ||
opcode == RET_INSN_OPCODE) opcode == RET_INSN_OPCODE)
...@@ -74,7 +79,8 @@ static void __static_call_validate(void *insn, bool tail) ...@@ -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. * 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) 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) ...@@ -97,12 +103,12 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
mutex_lock(&text_mutex); mutex_lock(&text_mutex);
if (tramp) { if (tramp) {
__static_call_validate(tramp, true); __static_call_validate(tramp, true, true);
__static_call_transform(tramp, __sc_insn(!func, true), func); __static_call_transform(tramp, __sc_insn(!func, true), func);
} }
if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site) { 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); __static_call_transform(site, __sc_insn(!func, tail), func);
} }
......
...@@ -3310,6 +3310,9 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio ...@@ -3310,6 +3310,9 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio
if (!insn->func) if (!insn->func)
return false; return false;
if (insn->func->static_call_tramp)
return true;
/* /*
* CONFIG_UBSAN_TRAP inserts a UD2 when it sees * CONFIG_UBSAN_TRAP inserts a UD2 when it sees
* __builtin_unreachable(). The BUG() macro has an unreachable() after * __builtin_unreachable(). The BUG() macro has an unreachable() after
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment