]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.0.8/arm64-ftrace-fix-inadvertent-bug-in-trampoline-check.patch
Linux 4.19.35
[thirdparty/kernel/stable-queue.git] / releases / 5.0.8 / arm64-ftrace-fix-inadvertent-bug-in-trampoline-check.patch
1 From 5a3ae7b314a2259b1188b22b392f5eba01e443ee Mon Sep 17 00:00:00 2001
2 From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
3 Date: Sun, 7 Apr 2019 21:06:16 +0200
4 Subject: arm64/ftrace: fix inadvertent BUG() in trampoline check
5
6 From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
7
8 commit 5a3ae7b314a2259b1188b22b392f5eba01e443ee upstream.
9
10 The ftrace trampoline code (which deals with modules loaded out of
11 BL range of the core kernel) uses plt_entries_equal() to check whether
12 the per-module trampoline equals a zero buffer, to decide whether the
13 trampoline has already been initialized.
14
15 This triggers a BUG() in the opcode manipulation code, since we end
16 up checking the ADRP offset of a 0x0 opcode, which is not an ADRP
17 instruction.
18
19 So instead, add a helper to check whether a PLT is initialized, and
20 call that from the frace code.
21
22 Cc: <stable@vger.kernel.org> # v5.0
23 Fixes: bdb85cd1d206 ("arm64/module: switch to ADRP/ADD sequences for PLT entries")
24 Acked-by: Mark Rutland <mark.rutland@arm.com>
25 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
26 Signed-off-by: Will Deacon <will.deacon@arm.com>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29 ---
30 arch/arm64/include/asm/module.h | 5 +++++
31 arch/arm64/kernel/ftrace.c | 3 +--
32 2 files changed, 6 insertions(+), 2 deletions(-)
33
34 --- a/arch/arm64/include/asm/module.h
35 +++ b/arch/arm64/include/asm/module.h
36 @@ -73,4 +73,9 @@ static inline bool is_forbidden_offset_f
37 struct plt_entry get_plt_entry(u64 dst, void *pc);
38 bool plt_entries_equal(const struct plt_entry *a, const struct plt_entry *b);
39
40 +static inline bool plt_entry_is_initialized(const struct plt_entry *e)
41 +{
42 + return e->adrp || e->add || e->br;
43 +}
44 +
45 #endif /* __ASM_MODULE_H */
46 --- a/arch/arm64/kernel/ftrace.c
47 +++ b/arch/arm64/kernel/ftrace.c
48 @@ -107,8 +107,7 @@ int ftrace_make_call(struct dyn_ftrace *
49 trampoline = get_plt_entry(addr, mod->arch.ftrace_trampoline);
50 if (!plt_entries_equal(mod->arch.ftrace_trampoline,
51 &trampoline)) {
52 - if (!plt_entries_equal(mod->arch.ftrace_trampoline,
53 - &(struct plt_entry){})) {
54 + if (plt_entry_is_initialized(mod->arch.ftrace_trampoline)) {
55 pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n");
56 return -EINVAL;
57 }