lkml.org 
[lkml]   [2016]   [Jan]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.1 110/127] arm64: bpf: fix mod-by-zero case
    Date
    4.1-stable review patch.  If anyone has any objections, please let me know.

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

    From: Zi Shen Lim <zlim.lnx@gmail.com>

    commit 14e589ff4aa3f28a5424e92b6495ecb8950080f7 upstream.

    Turns out in the case of modulo by zero in a BPF program:
    A = A % X; (X == 0)
    the expected behavior is to terminate with return value 0.

    The bug in JIT is exposed by a new test case [1].

    [1] https://lkml.org/lkml/2015/11/4/499

    Signed-off-by: Zi Shen Lim <zlim.lnx@gmail.com>
    Reported-by: Yang Shi <yang.shi@linaro.org>
    Reported-by: Xi Wang <xi.wang@gmail.com>
    CC: Alexei Starovoitov <ast@plumgrid.com>
    Fixes: e54bcde3d69d ("arm64: eBPF JIT compiler")
    Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/arm64/net/bpf_jit_comp.c | 21 +++++++++++++--------
    1 file changed, 13 insertions(+), 8 deletions(-)

    --- a/arch/arm64/net/bpf_jit_comp.c
    +++ b/arch/arm64/net/bpf_jit_comp.c
    @@ -269,6 +269,8 @@ static int build_insn(const struct bpf_i
    break;
    case BPF_ALU | BPF_DIV | BPF_X:
    case BPF_ALU64 | BPF_DIV | BPF_X:
    + case BPF_ALU | BPF_MOD | BPF_X:
    + case BPF_ALU64 | BPF_MOD | BPF_X:
    {
    const u8 r0 = bpf2a64[BPF_REG_0];

    @@ -281,16 +283,19 @@ static int build_insn(const struct bpf_i
    check_imm26(jmp_offset);
    emit(A64_B(jmp_offset), ctx);
    /* else */
    - emit(A64_UDIV(is64, dst, dst, src), ctx);
    + switch (BPF_OP(code)) {
    + case BPF_DIV:
    + emit(A64_UDIV(is64, dst, dst, src), ctx);
    + break;
    + case BPF_MOD:
    + ctx->tmp_used = 1;
    + emit(A64_UDIV(is64, tmp, dst, src), ctx);
    + emit(A64_MUL(is64, tmp, tmp, src), ctx);
    + emit(A64_SUB(is64, dst, dst, tmp), ctx);
    + break;
    + }
    break;
    }
    - case BPF_ALU | BPF_MOD | BPF_X:
    - case BPF_ALU64 | BPF_MOD | BPF_X:
    - ctx->tmp_used = 1;
    - emit(A64_UDIV(is64, tmp, dst, src), ctx);
    - emit(A64_MUL(is64, tmp, tmp, src), ctx);
    - emit(A64_SUB(is64, dst, dst, tmp), ctx);
    - break;
    case BPF_ALU | BPF_LSH | BPF_X:
    case BPF_ALU64 | BPF_LSH | BPF_X:
    emit(A64_LSLV(is64, dst, dst, src), ctx);

    \
     
     \ /
      Last update: 2016-01-27 21:01    [W:3.436 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site