netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] bpf: fix 64-bit divide
@ 2015-04-27 21:40 Alexei Starovoitov
  2015-04-28  3:15 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Alexei Starovoitov @ 2015-04-27 21:40 UTC (permalink / raw)
  To: David S. Miller; +Cc: Daniel Borkmann, Michael Holzheu, netdev

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.

 kernel/bpf/core.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

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;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH net] bpf: fix 64-bit divide
  2015-04-27 21:40 [PATCH net] bpf: fix 64-bit divide Alexei Starovoitov
@ 2015-04-28  3:15 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2015-04-28  3:15 UTC (permalink / raw)
  To: ast; +Cc: daniel, holzheu, netdev

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.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-04-28  3:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-27 21:40 [PATCH net] bpf: fix 64-bit divide Alexei Starovoitov
2015-04-28  3:15 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).