summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-05-01 20:26:02 -0700
committerDavid S. Miller <davem@davemloft.net>2017-05-01 20:48:36 -0700
commite3bf4c61da801c7967d0efff0c3f6b22d2c0e544 (patch)
tree19a50e3d01ce35ce251795e3fbd52feac3a3bb23 /arch
parent48e75b430670ebdbb00ba008e1d3690f61ab9824 (diff)
downloadlinux-e3bf4c61da801c7967d0efff0c3f6b22d2c0e544.tar.bz2
sparc64: Fix BPF JIT wrt. branches and ldimm64 instructions.
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/net/bpf_jit_comp_64.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c
index ec7d10da94f0..21de77419f48 100644
--- a/arch/sparc/net/bpf_jit_comp_64.c
+++ b/arch/sparc/net/bpf_jit_comp_64.c
@@ -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;
}