Skip to content

Commit 3eefdf9

Browse files
mrutland-armctmarinas
authored andcommitted
arm64: ftrace: fix branch range checks
The branch range checks in ftrace_make_call() and ftrace_make_nop() are incorrect, erroneously permitting a forwards branch of 128M and erroneously rejecting a backwards branch of 128M. This is because both functions calculate the offset backwards, calculating the offset *from* the target *to* the branch, rather than the other way around as the later comparisons expect. If an out-of-range branch were erroeously permitted, this would later be rejected by aarch64_insn_gen_branch_imm() as branch_imm_common() checks the bounds correctly, resulting in warnings and the placement of a BRK instruction. Note that this can only happen for a forwards branch of exactly 128M, and so the caller would need to be exactly 128M bytes below the relevant ftrace trampoline. If an in-range branch were erroeously rejected, then: * For modules when CONFIG_ARM64_MODULE_PLTS=y, this would result in the use of a PLT entry, which is benign. Note that this is the common case, as this is selected by CONFIG_RANDOMIZE_BASE (and therefore RANDOMIZE_MODULE_REGION_FULL), which distributions typically seelct. This is also selected by CONFIG_ARM64_ERRATUM_843419. * For modules when CONFIG_ARM64_MODULE_PLTS=n, this would result in internal ftrace failures. * For core kernel text, this would result in internal ftrace failues. Note that for this to happen, the kernel text would need to be at least 128M bytes in size, and typical configurations are smaller tha this. Fix this by calculating the offset *from* the branch *to* the target in both functions. Fixes: f8af0b3 ("arm64: ftrace: don't validate branch via PLT in ftrace_make_nop()") Fixes: e71a4e1 ("arm64: ftrace: add support for far branches to dynamic ftrace") Signed-off-by: Mark Rutland <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Will Deacon <[email protected]> Tested-by: "Ivan T. Ivanov" <[email protected]> Reviewed-by: Chengming Zhou <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 27d8fa2 commit 3eefdf9

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

arch/arm64/kernel/ftrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
8484
{
8585
unsigned long pc = rec->ip;
8686
u32 old, new;
87-
long offset = (long)pc - (long)addr;
87+
long offset = (long)addr - (long)pc;
8888

8989
if (offset < -SZ_128M || offset >= SZ_128M) {
9090
struct module *mod;
@@ -183,7 +183,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
183183
unsigned long pc = rec->ip;
184184
bool validate = true;
185185
u32 old = 0, new;
186-
long offset = (long)pc - (long)addr;
186+
long offset = (long)addr - (long)pc;
187187

188188
if (offset < -SZ_128M || offset >= SZ_128M) {
189189
u32 replaced;

0 commit comments

Comments
 (0)