Patch "bpf: try harder on clones when writing into skb" has been added to the 4.4-stable tree
Subsystems (5)
This is a note to let you know that I've just added the patch titled
bpf: try harder on clones when writing into skb
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
bpf-try-harder-on-clones-when-writing-into-skb.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Jul 6 16:50:47 PDT 2016
From: Daniel Borkmann <[email protected]>
Date: Fri, 19 Feb 2016 23:05:25 +0100
Subject: bpf: try harder on clones when writing into skb
From: Daniel Borkmann <[email protected]>
[ Upstream commit 3697649ff29e0f647565eed04b27a7779c646a22 ]
When we're dealing with clones and the area is not writeable, try harder and get a copy via pskb_expand_head(). Replace also other occurences in tc actions with the new skb_try_make_writable().
--- include/linux/skbuff.h | 7 +++++++ net/core/filter.c | 18 ++++++++++-------- net/sched/act_csum.c | 8 ++------ net/sched/act_nat.c | 18 +++++------------- 4 files changed, 24 insertions(+), 27 deletions(-)
include/linux/skbuff.h +7 -0
@@ -2564,6 +2564,13 @@ static inline int skb_clone_writable(conskb_headroom (skb) + len <= skb->hdr_len; } +static inline int skb_try_make_writable (struct sk_buff *skb, +unsigned int write_len) +{ +return skb_cloned (skb) && !skb_clone_writable (skb, write_len) && +pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC ); +} +static inline int __skb_cow (struct sk_buff *skb,unsigned int headroom,int cloned) {
net/core/filter.c +10 -8
@@ -1275,9 +1275,7 @@ static u64 bpf_skb_store_bytes(u64 r1, u*/ if (unlikely ((u32 ) offset >0xffff || len >sizeof (buf)))return -EFAULT ; - -if (unlikely (skb_cloned (skb) && - !skb_clone_writable (skb, offset + len))) +if (unlikely (skb_try_make_writable (skb, offset + len)))return -EFAULT ; ptr =skb_header_pointer (skb, offset, len, buf);
@@ -1321,8 +1319,7 @@ static u64 bpf_l3_csum_replace(u64 r1, uif (unlikely ((u32 ) offset >0xffff ))return -EFAULT ; -if (unlikely (skb_cloned (skb) && - !skb_clone_writable (skb, offset +sizeof (sum)))) +if (unlikely (skb_try_make_writable (skb, offset +sizeof (sum))))return -EFAULT ; ptr =skb_header_pointer (skb, offset,sizeof (sum), &sum);
@@ -1367,9 +1364,7 @@ static u64 bpf_l4_csum_replace(u64 r1, uif (unlikely ((u32 ) offset >0xffff ))return -EFAULT ; - -if (unlikely (skb_cloned (skb) && - !skb_clone_writable (skb, offset +sizeof (sum)))) +if (unlikely (skb_try_make_writable (skb, offset +sizeof (sum))))return -EFAULT ; ptr =skb_header_pointer (skb, offset,sizeof (sum), &sum);
@@ -1554,6 +1549,13 @@ bool bpf_helper_changes_skb_data(void *freturn true;if (func == bpf_skb_vlan_pop)return true; +if (func == bpf_skb_store_bytes) +return true; +if (func == bpf_l3_csum_replace) +return true; +if (func == bpf_l4_csum_replace) +return true; +return false; }
net/sched/act_csum.c +2 -6
@@ -105,9 +105,7 @@ static void *tcf_csum_skb_nextlayer(struint hl = ihl + jhl;if (!pskb_may_pull (skb, ipl + ntkoff) || (ipl < hl) || - (skb_cloned (skb) && - !skb_clone_writable (skb, hl + ntkoff) && -pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC ))) +skb_try_make_writable (skb, hl + ntkoff))return NULL ;else return (void *)(skb_network_header (skb) + ihl);
@@ -365,9 +363,7 @@ static int tcf_csum_ipv4(struct sk_buff }if (update_flags &TCA_CSUM_UPDATE_FLAG_IPV4HDR ) { -if (skb_cloned (skb) && - !skb_clone_writable (skb,sizeof (*iph) + ntkoff) && -pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC )) +if (skb_try_make_writable (skb,sizeof (*iph) + ntkoff)) goto fail;ip_send_check (ip_hdr (skb));
net/sched/act_nat.c +5 -13
@@ -126,9 +126,7 @@ static int tcf_nat(struct sk_buff *skb, addr = iph->daddr;if (!((old_addr ^ addr) & mask)) { -if (skb_cloned (skb) && - !skb_clone_writable (skb,sizeof (*iph) + noff) && -pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC )) +if (skb_try_make_writable (skb,sizeof (*iph) + noff)) goto drop; new_addr &= mask;
@@ -156,9 +154,7 @@ static int tcf_nat(struct sk_buff *skb,struct tcphdr *tcph;if (!pskb_may_pull (skb, ihl +sizeof (*tcph) + noff) || - (skb_cloned (skb) && - !skb_clone_writable (skb, ihl +sizeof (*tcph) + noff) && -pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC ))) +skb_try_make_writable (skb, ihl +sizeof (*tcph) + noff)) goto drop; tcph = (void *)(skb_network_header (skb) + ihl);
@@ -171,9 +167,7 @@ static int tcf_nat(struct sk_buff *skb,struct udphdr *udph;if (!pskb_may_pull (skb, ihl +sizeof (*udph) + noff) || - (skb_cloned (skb) && - !skb_clone_writable (skb, ihl +sizeof (*udph) + noff) && -pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC ))) +skb_try_make_writable (skb, ihl +sizeof (*udph) + noff)) goto drop; udph = (void *)(skb_network_header (skb) + ihl);
@@ -213,10 +207,8 @@ static int tcf_nat(struct sk_buff *skb,if ((old_addr ^ addr) & mask)break ; -if (skb_cloned (skb) && - !skb_clone_writable (skb, ihl +sizeof (*icmph) + -sizeof (*iph) + noff) && -pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC )) +if (skb_try_make_writable (skb, ihl +sizeof (*icmph) + +sizeof (*iph) + noff)) goto drop; icmph = (void *)(skb_network_header (skb) + ihl);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/bpf-perf-delay-release-of-bpf-prog-after-grace-period.patch queue-4.4/bpf-try-harder-on-clones-when-writing-into-skb.patch