mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
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
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user