|
@@ -532,7 +532,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 */
|
|
@@ -584,7 +585,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)
|
|
@@ -631,8 +633,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);
|
|
|
}
|
|
|
|