* [PATCH V2 net 0/3] BPF JIT fixes for ARM
@ 2015-07-21 12:14 Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 1/3] ARM: net: fix condition for load_order > 0 when translating load instructions Nicolas Schichan
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Nicolas Schichan @ 2015-07-21 12:14 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
These patches are fixing bugs in the ARM JIT and should probably find
their way to a stable kernel. All 60 test_bpf tests in Linux 4.1 release
are now passing OK (was 54 out of 60 before).
Regards,
Changes from original submission:
* split fixes and features in separate patch series.
Nicolas Schichan (3):
ARM: net: fix condition for load_order > 0 when translating load
instructions.
ARM: net: handle negative offsets in BPF JIT.
ARM: net: fix vlan access instructions in ARM JIT.
arch/arm/net/bpf_jit_32.c | 57 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 13 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V2 net 1/3] ARM: net: fix condition for load_order > 0 when translating load instructions.
2015-07-21 12:14 [PATCH V2 net 0/3] BPF JIT fixes for ARM Nicolas Schichan
@ 2015-07-21 12:14 ` Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 2/3] ARM: net: handle negative offsets in BPF JIT Nicolas Schichan
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Nicolas Schichan @ 2015-07-21 12:14 UTC (permalink / raw)
To: linux-arm-kernel
To check whether the load should take the fast path or not, the code
would check that (r_skb_hlen - load_order) is greater than the offset
of the access using an "Unsigned higher or same" condition. For
halfword accesses and an skb length of 1 at offset 0, that test is
valid, as we end up comparing 0xffffffff(-1) and 0, so the fast path
is taken and the filter allows the load to wrongly succeed. A similar
issue exists for word loads at offset 0 and an skb length of less than
4.
Fix that by using the condition "Signed greater than or equal"
condition for the fast path code for load orders greater than 0.
Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
---
arch/arm/net/bpf_jit_32.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index 4550d24..21f5ace 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -547,7 +547,7 @@ load_common:
emit(ARM_SUB_I(r_scratch, r_skb_hl,
1 << load_order), ctx);
emit(ARM_CMP_R(r_scratch, r_off), ctx);
- condt = ARM_COND_HS;
+ condt = ARM_COND_GE;
} else {
emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
condt = ARM_COND_HI;
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 net 2/3] ARM: net: handle negative offsets in BPF JIT.
2015-07-21 12:14 [PATCH V2 net 0/3] BPF JIT fixes for ARM Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 1/3] ARM: net: fix condition for load_order > 0 when translating load instructions Nicolas Schichan
@ 2015-07-21 12:14 ` Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 3/3] ARM: net: fix vlan access instructions in ARM JIT Nicolas Schichan
2015-07-22 5:20 ` [PATCH V2 net 0/3] BPF JIT fixes for ARM David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Nicolas Schichan @ 2015-07-21 12:14 UTC (permalink / raw)
To: linux-arm-kernel
Previously, the JIT would reject negative offsets known during code
generation and mishandle negative offsets provided at runtime.
Fix that by calling bpf_internal_load_pointer_neg_helper()
appropriately in the jit_get_skb_{b,h,w} slow path helpers and by forcing
the execution flow to the slow path helpers when the offset is
negative.
Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
---
arch/arm/net/bpf_jit_32.c | 47 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 38 insertions(+), 9 deletions(-)
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index 21f5ace..d9b2524 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -74,32 +74,52 @@ struct jit_ctx {
int bpf_jit_enable __read_mostly;
-static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret,
+ unsigned int size)
+{
+ void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size);
+
+ if (!ptr)
+ return -EFAULT;
+ memcpy(ret, ptr, size);
+ return 0;
+}
+
+static u64 jit_get_skb_b(struct sk_buff *skb, int offset)
{
u8 ret;
int err;
- err = skb_copy_bits(skb, offset, &ret, 1);
+ if (offset < 0)
+ err = call_neg_helper(skb, offset, &ret, 1);
+ else
+ err = skb_copy_bits(skb, offset, &ret, 1);
return (u64)err << 32 | ret;
}
-static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+static u64 jit_get_skb_h(struct sk_buff *skb, int offset)
{
u16 ret;
int err;
- err = skb_copy_bits(skb, offset, &ret, 2);
+ if (offset < 0)
+ err = call_neg_helper(skb, offset, &ret, 2);
+ else
+ err = skb_copy_bits(skb, offset, &ret, 2);
return (u64)err << 32 | ntohs(ret);
}
-static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+static u64 jit_get_skb_w(struct sk_buff *skb, int offset)
{
u32 ret;
int err;
- err = skb_copy_bits(skb, offset, &ret, 4);
+ if (offset < 0)
+ err = call_neg_helper(skb, offset, &ret, 4);
+ else
+ err = skb_copy_bits(skb, offset, &ret, 4);
return (u64)err << 32 | ntohl(ret);
}
@@ -536,9 +556,6 @@ static int build_body(struct jit_ctx *ctx)
case BPF_LD | BPF_B | BPF_ABS:
load_order = 0;
load:
- /* the interpreter will deal with the negative K */
- if ((int)k < 0)
- return -ENOTSUPP;
emit_mov_i(r_off, k, ctx);
load_common:
ctx->seen |= SEEN_DATA | SEEN_CALL;
@@ -553,6 +570,18 @@ load_common:
condt = ARM_COND_HI;
}
+ /*
+ * test for negative offset, only if we are
+ * currently scheduled to take the fast
+ * path. this will update the flags so that
+ * the slowpath instruction are ignored if the
+ * offset is negative.
+ *
+ * for loard_order == 0 the HI condition will
+ * make loads at offset 0 take the slow path too.
+ */
+ _emit(condt, ARM_CMP_I(r_off, 0), ctx);
+
_emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
ctx);
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 net 3/3] ARM: net: fix vlan access instructions in ARM JIT.
2015-07-21 12:14 [PATCH V2 net 0/3] BPF JIT fixes for ARM Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 1/3] ARM: net: fix condition for load_order > 0 when translating load instructions Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 2/3] ARM: net: handle negative offsets in BPF JIT Nicolas Schichan
@ 2015-07-21 12:14 ` Nicolas Schichan
2015-07-22 5:20 ` [PATCH V2 net 0/3] BPF JIT fixes for ARM David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Nicolas Schichan @ 2015-07-21 12:14 UTC (permalink / raw)
To: linux-arm-kernel
This makes BPF_ANC | SKF_AD_VLAN_TAG and BPF_ANC | SKF_AD_VLAN_TAG_PRESENT
have the same behaviour as the in kernel VM and makes the test_bpf LD_VLAN_TAG
and LD_VLAN_TAG_PRESENT tests pass.
Signed-off-by: Nicolas Schichan <nschichan@freebox.fr>
---
arch/arm/net/bpf_jit_32.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index d9b2524..c011e22 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -889,9 +889,11 @@ b_epilogue:
off = offsetof(struct sk_buff, vlan_tci);
emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
if (code == (BPF_ANC | SKF_AD_VLAN_TAG))
- OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx);
- else
- OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx);
+ OP_IMM3(ARM_AND, r_A, r_A, ~VLAN_TAG_PRESENT, ctx);
+ else {
+ OP_IMM3(ARM_LSR, r_A, r_A, 12, ctx);
+ OP_IMM3(ARM_AND, r_A, r_A, 0x1, ctx);
+ }
break;
case BPF_ANC | SKF_AD_QUEUE:
ctx->seen |= SEEN_SKB;
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 net 0/3] BPF JIT fixes for ARM
2015-07-21 12:14 [PATCH V2 net 0/3] BPF JIT fixes for ARM Nicolas Schichan
` (2 preceding siblings ...)
2015-07-21 12:14 ` [PATCH V2 net 3/3] ARM: net: fix vlan access instructions in ARM JIT Nicolas Schichan
@ 2015-07-22 5:20 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2015-07-22 5:20 UTC (permalink / raw)
To: linux-arm-kernel
From: Nicolas Schichan <nschichan@freebox.fr>
Date: Tue, 21 Jul 2015 14:14:11 +0200
> These patches are fixing bugs in the ARM JIT and should probably find
> their way to a stable kernel. All 60 test_bpf tests in Linux 4.1 release
> are now passing OK (was 54 out of 60 before).
Series applied, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-07-22 5:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-21 12:14 [PATCH V2 net 0/3] BPF JIT fixes for ARM Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 1/3] ARM: net: fix condition for load_order > 0 when translating load instructions Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 2/3] ARM: net: handle negative offsets in BPF JIT Nicolas Schichan
2015-07-21 12:14 ` [PATCH V2 net 3/3] ARM: net: fix vlan access instructions in ARM JIT Nicolas Schichan
2015-07-22 5:20 ` [PATCH V2 net 0/3] BPF JIT fixes for ARM 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).