Jumping to the first insn causes emit_compare_and_branch() to access ctx->offsets[-1]. Currently ctx->offsets[] stores instruction end addresses; change it to store start addresses instead. We never need the end address of the last instruction. Cc: David S. Miller <davem@xxxxxxxxxxxxx> Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> --- arch/sparc/net/bpf_jit_comp_64.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 59d2d9953aa7..0a3c18e39199 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1168,7 +1168,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* JUMP off */ case BPF_JMP | BPF_JA: - emit_branch(BA, ctx->idx, ctx->offset[i + off], ctx); + emit_branch(BA, ctx->idx, ctx->offset[i + off + 1], ctx); emit_nop(ctx); break; /* IF (dst COND src) JUMP off */ @@ -1185,7 +1185,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) case BPF_JMP | BPF_JSET | BPF_X: { int err; - err = emit_compare_and_branch(code, dst, src, 0, false, i + off, ctx); + err = emit_compare_and_branch(code, dst, src, 0, false, i + off + 1, ctx); if (err) return err; break; @@ -1204,7 +1204,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) case BPF_JMP | BPF_JSET | BPF_K: { int err; - err = emit_compare_and_branch(code, dst, 0, imm, true, i + off, ctx); + err = emit_compare_and_branch(code, dst, 0, imm, true, i + off + 1, ctx); if (err) return err; break; @@ -1453,16 +1453,12 @@ static int build_body(struct jit_ctx *ctx) const struct bpf_insn *insn = &prog->insnsi[i]; int ret; - ret = build_insn(insn, ctx); - - if (ret > 0) { - i++; - ctx->offset[i] = ctx->idx; - continue; - } ctx->offset[i] = ctx->idx; - if (ret) + ret = build_insn(insn, ctx); + if (ret < 0) return ret; + + i += ret; } return 0; } -- 2.39.1