act_nat: fix on the TX path
Subsystems (3)
PATCH 1/1 act_nat: fix on the TX path
On the TX path, skb->data points to the ethernet header, not the network header. So when validating the packet length for accessing we should take the ethernet header into account.
Signed-off-by Changli Gao <[email protected]>
--- net/sched/act_nat.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
net/sched/act_nat.c +13 -10
@@ -114,6 +114,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,int egress;int action;int ihl; +int noff;spin_lock (&p->tcf_lock);
@@ -132,7 +133,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,if (unlikely (action ==TC_ACT_SHOT )) goto drop; -if (!pskb_may_pull (skb,sizeof (*iph))) + noff =skb_network_offset (skb); +if (!pskb_may_pull (skb,sizeof (*iph) + noff)) goto drop; iph =ip_hdr (skb);
@@ -144,7 +146,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,if (!((old_addr ^ addr) & mask)) {if (skb_cloned (skb) && - !skb_clone_writable (skb,sizeof (*iph)) && + !skb_clone_writable (skb,sizeof (*iph) + noff) &&pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC )) goto drop;
@@ -172,9 +174,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, {struct tcphdr *tcph; -if (!pskb_may_pull (skb, ihl +sizeof (*tcph)) || +if (!pskb_may_pull (skb, ihl +sizeof (*tcph) + noff) || (skb_cloned (skb) && - !skb_clone_writable (skb, ihl +sizeof (*tcph)) && + !skb_clone_writable (skb, ihl +sizeof (*tcph) + noff) &&pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC ))) goto drop;
@@ -186,9 +188,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, {struct udphdr *udph; -if (!pskb_may_pull (skb, ihl +sizeof (*udph)) || +if (!pskb_may_pull (skb, ihl +sizeof (*udph) + noff) || (skb_cloned (skb) && - !skb_clone_writable (skb, ihl +sizeof (*udph)) && + !skb_clone_writable (skb, ihl +sizeof (*udph) + noff) &&pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC ))) goto drop;
@@ -205,7 +207,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, {struct icmphdr *icmph; -if (!pskb_may_pull (skb, ihl +sizeof (*icmph))) +if (!pskb_may_pull (skb, ihl +sizeof (*icmph) + noff)) goto drop; icmph = (void *)(skb_network_header (skb) + ihl);
@@ -215,7 +217,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, (icmph->type != ICMP_PARAMETERPROB))break ; -if (!pskb_may_pull (skb, ihl +sizeof (*icmph) +sizeof (*iph))) +if (!pskb_may_pull (skb, ihl +sizeof (*icmph) +sizeof (*iph) + + noff)) goto drop; icmph = (void *)(skb_network_header (skb) + ihl);
@@ -229,8 +232,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,break ;if (skb_cloned (skb) && - !skb_clone_writable (skb, - ihl +sizeof (*icmph) +sizeof (*iph)) && + !skb_clone_writable (skb, ihl +sizeof (*icmph) + +sizeof (*iph) + noff) &&pskb_expand_head (skb,0 ,0 ,GFP_ATOMIC )) goto drop;
Quoted 5 lines · Changli Gao
On the TX path,
skb->datapoints to the ethernet header, not the network header. So when validating the packet length for accessing we should take the ethernet header into account.Signed-off-by Changli Gao <[email protected]>
Acked-by Herbert Xu <[email protected]>
Thanks for cathing this!
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
From: Herbert Xu <[email protected]>
Date: Wed, 4 Aug 2010 15:06:21 +0800
Quoted 8 lines · Changli Gao
Quoted 5 lines
On the TX path,
skb->datapoints to the ethernet header, not the network header. So when validating the packet length for accessing we should take the ethernet header into account.Signed-off-by Changli Gao <[email protected]>Acked-by Herbert Xu <[email protected]>
Applied, thanks.