netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] x86: bpf_jit: fix FROM_BE16 and FROM_LE16/32 instructions
@ 2015-05-12  6:25 Alexei Starovoitov
  2015-05-13  3:14 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Alexei Starovoitov @ 2015-05-12  6:25 UTC (permalink / raw)
  To: David S. Miller; +Cc: Daniel Borkmann, netdev

FROM_BE16:
'ror %reg, 8' doesn't clear upper bits of the register,
so use additional 'movzwl' insn to zero extend 16 bits into 64

FROM_LE16:
should zero extend lower 16 bits into 64 bit

FROM_LE32:
should zero extend lower 32 bits into 64 bit

Fixes: 89aa075832b0 ("net: sock: allow eBPF programs to be attached to sockets")
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
---
Though these instructions were implemented incorrectly during
the first eBPF JIT drop:
commit 622582786c9e ("net: filter: x86: internal BPF JIT")
and FROM_BE16 was used by converter from classic to extended,
the coverter used zero-extending 16-bit load from memory
right before FROM_BE16 insn, so classic extension skb->protocol
was not affected.
Therefore it makes sense to backport this fix only till commit
89aa075832b0 (which is above Fixes tag) when eBPF programs became
accessible via sockets.

The bug was found via new exhaustive eBPF testsuite.

 arch/x86/net/bpf_jit_comp.c |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 987514396c1e..99f76103c6b7 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -559,6 +559,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
 				if (is_ereg(dst_reg))
 					EMIT1(0x41);
 				EMIT3(0xC1, add_1reg(0xC8, dst_reg), 8);
+
+				/* emit 'movzwl eax, ax' */
+				if (is_ereg(dst_reg))
+					EMIT3(0x45, 0x0F, 0xB7);
+				else
+					EMIT2(0x0F, 0xB7);
+				EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
 				break;
 			case 32:
 				/* emit 'bswap eax' to swap lower 4 bytes */
@@ -577,6 +584,27 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
 			break;
 
 		case BPF_ALU | BPF_END | BPF_FROM_LE:
+			switch (imm32) {
+			case 16:
+				/* emit 'movzwl eax, ax' to zero extend 16-bit
+				 * into 64 bit
+				 */
+				if (is_ereg(dst_reg))
+					EMIT3(0x45, 0x0F, 0xB7);
+				else
+					EMIT2(0x0F, 0xB7);
+				EMIT1(add_2reg(0xC0, dst_reg, dst_reg));
+				break;
+			case 32:
+				/* emit 'mov eax, eax' to clear upper 32-bits */
+				if (is_ereg(dst_reg))
+					EMIT1(0x45);
+				EMIT2(0x89, add_2reg(0xC0, dst_reg, dst_reg));
+				break;
+			case 64:
+				/* nop */
+				break;
+			}
 			break;
 
 			/* ST: *(u8*)(dst_reg + off) = imm */
-- 
1.7.9.5

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

* Re: [PATCH net] x86: bpf_jit: fix FROM_BE16 and FROM_LE16/32 instructions
  2015-05-12  6:25 [PATCH net] x86: bpf_jit: fix FROM_BE16 and FROM_LE16/32 instructions Alexei Starovoitov
@ 2015-05-13  3:14 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2015-05-13  3:14 UTC (permalink / raw)
  To: ast; +Cc: daniel, netdev

From: Alexei Starovoitov <ast@plumgrid.com>
Date: Mon, 11 May 2015 23:25:16 -0700

> FROM_BE16:
> 'ror %reg, 8' doesn't clear upper bits of the register,
> so use additional 'movzwl' insn to zero extend 16 bits into 64
> 
> FROM_LE16:
> should zero extend lower 16 bits into 64 bit
> 
> FROM_LE32:
> should zero extend lower 32 bits into 64 bit
> 
> Fixes: 89aa075832b0 ("net: sock: allow eBPF programs to be attached to sockets")
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>

Applied and queued up for -stable, thank you.

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

end of thread, other threads:[~2015-05-13  3:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-12  6:25 [PATCH net] x86: bpf_jit: fix FROM_BE16 and FROM_LE16/32 instructions Alexei Starovoitov
2015-05-13  3:14 ` 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).