aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/net/bpf_jit.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2018-05-22 10:28:38 +0100
committerMark Brown <broonie@kernel.org>2018-05-22 10:28:38 +0100
commite1c51aa8705fd78e5259e0515aad3b5003e18550 (patch)
tree3728628142a24460d6b488e5331f421f902e5d3a /arch/mips/net/bpf_jit.c
parent6e49b7fa3083c30688b7fff1b37ed891cd1c30af (diff)
parent08556e03ad36b2c6219aba90de88ccf58038e208 (diff)
Merge branch 'linux-linaro-lsk-v4.9' into linux-linaro-lsk-v4.9-rtlinux-linaro-lsk-v4.9-rt-test
Diffstat (limited to 'arch/mips/net/bpf_jit.c')
-rw-r--r--arch/mips/net/bpf_jit.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
index 49a2e2226fee..248603739198 100644
--- a/arch/mips/net/bpf_jit.c
+++ b/arch/mips/net/bpf_jit.c
@@ -526,7 +526,8 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
u32 sflags, tmp_flags;
/* Adjust the stack pointer */
- emit_stack_offset(-align_sp(offset), ctx);
+ if (offset)
+ emit_stack_offset(-align_sp(offset), ctx);
tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT;
/* sflags is essentially a bitmap */
@@ -578,7 +579,8 @@ static void restore_bpf_jit_regs(struct jit_ctx *ctx,
emit_load_stack_reg(r_ra, r_sp, real_off, ctx);
/* Restore the sp and discard the scrach memory */
- emit_stack_offset(align_sp(offset), ctx);
+ if (offset)
+ emit_stack_offset(align_sp(offset), ctx);
}
static unsigned int get_stack_depth(struct jit_ctx *ctx)
@@ -625,8 +627,14 @@ static void build_prologue(struct jit_ctx *ctx)
if (ctx->flags & SEEN_X)
emit_jit_reg_move(r_X, r_zero, ctx);
- /* Do not leak kernel data to userspace */
- if (bpf_needs_clear_a(&ctx->skf->insns[0]))
+ /*
+ * Do not leak kernel data to userspace, we only need to clear
+ * r_A if it is ever used. In fact if it is never used, we
+ * will not save/restore it, so clearing it in this case would
+ * corrupt the state of the caller.
+ */
+ if (bpf_needs_clear_a(&ctx->skf->insns[0]) &&
+ (ctx->flags & SEEN_A))
emit_jit_reg_move(r_A, r_zero, ctx);
}