sparc64: Fix BPF JIT wrt. branches and ldimm64 instructions.
authorDavid S. Miller <davem@davemloft.net>
Tue, 2 May 2017 03:26:02 +0000 (20:26 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 2 May 2017 03:48:36 +0000 (20:48 -0700)
Like other JITs, sparc64 maintains an array of instruction offsets but
stores the entries off by one.  This is done because jumps to the
exit block are indexed to one past the last BPF instruction.

So if we size the array by the program length, we need to record
the previous instruction in order to stay within the array bounds.

This is explained in ARM JIT commit 8eee539ddea0 ("arm64: bpf: fix
out-of-bounds read in bpf2a64_offset()").

But this scheme requires a little bit of careful handling when
the instruction before the branch destination is a 64-bit load
immediate.  It takes up 2 BPF instruction slots.

Therefore, we have to fill in the array entry for the second
half of the 64-bit load immediate instruction rather than for
the one for the beginning of that instruction.

Fixes: 7a12b5031c6b ("sparc64: Add eBPF JIT.")
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/net/bpf_jit_comp_64.c

index ec7d10da94f08eccce59bfde30158910de0900b2..21de77419f484b16939d4ce4bf6abbf734ccf325 100644 (file)
@@ -1446,12 +1446,13 @@ static int build_body(struct jit_ctx *ctx)
                int ret;
 
                ret = build_insn(insn, ctx);
-               ctx->offset[i] = ctx->idx;
 
                if (ret > 0) {
                        i++;
+                       ctx->offset[i] = ctx->idx;
                        continue;
                }
+               ctx->offset[i] = ctx->idx;
                if (ret)
                        return ret;
        }