MIPS: eBPF: Fix icache flush end address [Linux 5.0]

MIPS: eBPF: Fix icache flush end address [Linux 5.0]

This Linux kernel change "MIPS: eBPF: Fix icache flush end address" is included in the Linux 5.0 release. This change is authored by Paul Burton <paul.burton [at] mips.com> on Fri Mar 1 22:58:09 2019 +0000. The commit for this change in Linux stable tree is d1a2930 (patch).

MIPS: eBPF: Fix icache flush end address

The MIPS eBPF JIT calls flush_icache_range() in order to ensure the
icache observes the code that we just wrote. Unfortunately it gets the
end address calculation wrong due to some bad pointer arithmetic.

The struct jit_ctx target field is of type pointer to u32, and as such
adding one to it will increment the address being pointed to by 4 bytes.
Therefore in order to find the address of the end of the code we simply
need to add the number of 4 byte instructions emitted, but we mistakenly
add the number of instructions multiplied by 4. This results in the call
to flush_icache_range() operating on a memory region 4x larger than
intended, which is always wasteful and can cause crashes if we overrun
into an unmapped page.

Fix this by correcting the pointer arithmetic to remove the bogus
multiplication, and use braces to remove the need for a set of brackets
whilst also making it obvious that the target field is a pointer.

Signed-off-by: Paul Burton <[email protected]>
Fixes: b6bd53f9c4e8 ("MIPS: Add missing file for eBPF JIT.")
Cc: Alexei Starovoitov <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Cc: Martin KaFai Lau <[email protected]>
Cc: Song Liu <[email protected]>
Cc: Yonghong Song <[email protected]>
Cc: [email protected]
Cc: [email protected]g
Cc: [email protected]
Cc: [email protected] # v4.13+
Signed-off-by: Daniel Borkmann <[email protected]>

There are 2 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 arch/mips/net/ebpf_jit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c
index 76e9bf8..0effd3c 100644
--- a/arch/mips/net/ebpf_jit.c
+++ b/arch/mips/net/ebpf_jit.c
@@ -1819,7 +1819,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)

    /* Update the icache */
    flush_icache_range((unsigned long)ctx.target,
-              (unsigned long)(ctx.target + ctx.idx * sizeof(u32)));
+              (unsigned long)&ctx.target[ctx.idx]);

    if (bpf_jit_enable > 1)
        /* Dump JIT code */

Leave a Reply

Your email address will not be published. Required fields are marked *