Message ID | 1430170837-9394-1-git-send-email-ast@plumgrid.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Alexei Starovoitov <ast@plumgrid.com> Date: Mon, 27 Apr 2015 14:40:37 -0700 > ALU64_DIV instruction should be dividing 64-bit by 64-bit, > whereas do_div() does 64-bit by 32-bit divide. > x64 and arm64 JITs correctly implement 64 by 64 unsigned divide. > llvm BPF backend emits code assuming that ALU64_DIV does 64 by 64. > > Fixes: 89aa075832b0 ("net: sock: allow eBPF programs to be attached to sockets") > Reported-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> > Acked-by: Daniel Borkmann <daniel@iogearbox.net> > Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> > --- > The bug is old and sneaked in during the very first eBPF code drop: > Fixes: bd4cf0ed331a ("net: filter: rework/optimize internal BPF interpreter's instruction set") > but it's not affecting classic and shouldn't be backported further > than commit 89aa075832b0 (which is the above Fixes tag). > It was found by exhaustive tests being written by Michael Holzheu. Ok, applied and queued up for v3.19 -stable and later. Thanks. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 4139a0f8b558..54f0e7fcd0e2 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -357,8 +357,8 @@ select_insn: ALU64_MOD_X: if (unlikely(SRC == 0)) return 0; - tmp = DST; - DST = do_div(tmp, SRC); + div64_u64_rem(DST, SRC, &tmp); + DST = tmp; CONT; ALU_MOD_X: if (unlikely(SRC == 0)) @@ -367,8 +367,8 @@ select_insn: DST = do_div(tmp, (u32) SRC); CONT; ALU64_MOD_K: - tmp = DST; - DST = do_div(tmp, IMM); + div64_u64_rem(DST, IMM, &tmp); + DST = tmp; CONT; ALU_MOD_K: tmp = (u32) DST; @@ -377,7 +377,7 @@ select_insn: ALU64_DIV_X: if (unlikely(SRC == 0)) return 0; - do_div(DST, SRC); + DST = div64_u64(DST, SRC); CONT; ALU_DIV_X: if (unlikely(SRC == 0)) @@ -387,7 +387,7 @@ select_insn: DST = (u32) tmp; CONT; ALU64_DIV_K: - do_div(DST, IMM); + DST = div64_u64(DST, IMM); CONT; ALU_DIV_K: tmp = (u32) DST;