Skip to content

Commit

Permalink
act_nat: fix on the TX path
Browse files Browse the repository at this point in the history
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]>
Acked-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
xiaosuo authored and davem330 committed Aug 5, 2010
1 parent c33788b commit 36d1269
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions net/sched/act_nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;

Expand Down

0 comments on commit 36d1269

Please sign in to comment.