lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 129/241] MIPS: BPF: Quit clobbering callee saved registers in JIT code.
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: David Daney <david.daney@cavium.com>


    [ Upstream commit 1ef0910cfd681f0bd0b81f8809935b2006e9cfb9 ]

    If bpf_needs_clear_a() returns true, only actually clear it if it is
    ever used. If it is not used, we don't save and restore it, so the
    clearing has the nasty side effect of clobbering caller state.

    Also, don't emit stack pointer adjustment instructions if the
    adjustment amount is zero.

    Signed-off-by: David Daney <david.daney@cavium.com>
    Cc: James Hogan <james.hogan@imgtec.com>
    Cc: Alexei Starovoitov <ast@kernel.org>
    Cc: Steven J. Hill <steven.hill@cavium.com>
    Cc: linux-mips@linux-mips.org
    Cc: netdev@vger.kernel.org
    Cc: linux-kernel@vger.kernel.org
    Patchwork: https://patchwork.linux-mips.org/patch/15745/
    Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/mips/net/bpf_jit.c | 16 ++++++++++++----
    1 file changed, 12 insertions(+), 4 deletions(-)

    --- 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
    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
    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_ct
    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);
    }


    \
     
     \ /
      Last update: 2018-03-19 20:30    [W:4.128 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site