Skip to content

Commit 6c3fce7

Browse files
Peter Zijlstraingomolnar
authored andcommitted
static_call: Add some validation
Verify the text we're about to change is as we expect it to be. Requested-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200818135805.161974981@infradead.org
1 parent 5b06fd3 commit 6c3fce7

1 file changed

Lines changed: 26 additions & 2 deletions

File tree

arch/x86/kernel/static_call.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,26 @@ static void __static_call_transform(void *insn, enum insn_type type, void *func)
4141
text_poke_bp(insn, code, size, NULL);
4242
}
4343

44+
static void __static_call_validate(void *insn, bool tail)
45+
{
46+
u8 opcode = *(u8 *)insn;
47+
48+
if (tail) {
49+
if (opcode == JMP32_INSN_OPCODE ||
50+
opcode == RET_INSN_OPCODE)
51+
return;
52+
} else {
53+
if (opcode == CALL_INSN_OPCODE ||
54+
!memcmp(insn, ideal_nops[NOP_ATOMIC5], 5))
55+
return;
56+
}
57+
58+
/*
59+
* If we ever trigger this, our text is corrupt, we'll probably not live long.
60+
*/
61+
WARN_ONCE(1, "unexpected static_call insn opcode 0x%x at %pS\n", opcode, insn);
62+
}
63+
4464
static inline enum insn_type __sc_insn(bool null, bool tail)
4565
{
4666
/*
@@ -60,11 +80,15 @@ void arch_static_call_transform(void *site, void *tramp, void *func, bool tail)
6080
{
6181
mutex_lock(&text_mutex);
6282

63-
if (tramp)
83+
if (tramp) {
84+
__static_call_validate(tramp, true);
6485
__static_call_transform(tramp, __sc_insn(!func, true), func);
86+
}
6587

66-
if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site)
88+
if (IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) && site) {
89+
__static_call_validate(site, tail);
6790
__static_call_transform(site, __sc_insn(!func, tail), func);
91+
}
6892

6993
mutex_unlock(&text_mutex);
7094
}

0 commit comments

Comments
 (0)