lkml.org 
[lkml]   [2019]   [Feb]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 03/71] MIPS: eBPF: Always return sign extended 32b values
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

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

    From: Paul Burton <paul.burton@mips.com>

    commit 13443154f6cac61d148471ede6d7f1f6b5ea946a upstream.

    The function prototype used to call JITed eBPF code (ie. the type of the
    struct bpf_prog bpf_func field) returns an unsigned int. The MIPS n64
    ABI that MIPS64 kernels target defines that 32 bit integers should
    always be sign extended when passed in registers as either arguments or
    return values.

    This means that when returning any value which may not already be sign
    extended (ie. of type REG_64BIT or REG_32BIT_ZERO_EX) we need to perform
    that sign extension in order to comply with the n64 ABI. Without this we
    see strange looking test failures from test_bpf.ko, such as:

    test_bpf: #65 ALU64_MOV_X:
    dst = 4294967295 jited:1 ret -1 != -1 FAIL (1 times)

    Although the return value printed matches the expected value, this is
    only because printf is only examining the least significant 32 bits of
    the 64 bit register value we returned. The register holding the expected
    value is sign extended whilst the v0 register was set to a zero extended
    value by our JITed code, so when compared by a conditional branch
    instruction the values are not equal.

    We already handle this when the return value register is of type
    REG_32BIT_ZERO_EX, so simply extend this to also cover REG_64BIT.

    Signed-off-by: Paul Burton <paul.burton@mips.com>
    Fixes: b6bd53f9c4e8 ("MIPS: Add missing file for eBPF JIT.")
    Cc: stable@vger.kernel.org # v4.13+
    Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/mips/net/ebpf_jit.c | 9 ++++++---
    1 file changed, 6 insertions(+), 3 deletions(-)

    --- a/arch/mips/net/ebpf_jit.c
    +++ b/arch/mips/net/ebpf_jit.c
    @@ -348,12 +348,15 @@ static int build_int_epilogue(struct jit
    const struct bpf_prog *prog = ctx->skf;
    int stack_adjust = ctx->stack_size;
    int store_offset = stack_adjust - 8;
    + enum reg_val_type td;
    int r0 = MIPS_R_V0;

    - if (dest_reg == MIPS_R_RA &&
    - get_reg_val_type(ctx, prog->len, BPF_REG_0) == REG_32BIT_ZERO_EX)
    + if (dest_reg == MIPS_R_RA) {
    /* Don't let zero extended value escape. */
    - emit_instr(ctx, sll, r0, r0, 0);
    + td = get_reg_val_type(ctx, prog->len, BPF_REG_0);
    + if (td == REG_64BIT || td == REG_32BIT_ZERO_EX)
    + emit_instr(ctx, sll, r0, r0, 0);
    + }

    if (ctx->flags & EBPF_SAVE_RA) {
    emit_instr(ctx, ld, MIPS_R_RA, store_offset, MIPS_R_SP);

    \
     
     \ /
      Last update: 2019-02-25 22:17    [W:3.366 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site