diff options
Diffstat (limited to 'net/ipv4/ip_input.c')
-rw-r--r-- | net/ipv4/ip_input.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 81e18023dc19..322b082ede1e 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -361,6 +361,7 @@ drop: | |||
361 | int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | 361 | int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) |
362 | { | 362 | { |
363 | struct iphdr *iph; | 363 | struct iphdr *iph; |
364 | u32 len; | ||
364 | 365 | ||
365 | /* When the interface is in promisc. mode, drop all the crap | 366 | /* When the interface is in promisc. mode, drop all the crap |
366 | * that it receives, do not try to analyse it. | 367 | * that it receives, do not try to analyse it. |
@@ -392,7 +393,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
392 | */ | 393 | */ |
393 | 394 | ||
394 | if (iph->ihl < 5 || iph->version != 4) | 395 | if (iph->ihl < 5 || iph->version != 4) |
395 | goto inhdr_error; | 396 | goto inhdr_error; |
396 | 397 | ||
397 | if (!pskb_may_pull(skb, iph->ihl*4)) | 398 | if (!pskb_may_pull(skb, iph->ihl*4)) |
398 | goto inhdr_error; | 399 | goto inhdr_error; |
@@ -400,21 +401,19 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
400 | iph = skb->nh.iph; | 401 | iph = skb->nh.iph; |
401 | 402 | ||
402 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) | 403 | if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) |
403 | goto inhdr_error; | 404 | goto inhdr_error; |
404 | 405 | ||
405 | { | 406 | len = ntohs(iph->tot_len); |
406 | __u32 len = ntohs(iph->tot_len); | 407 | if (skb->len < len || len < (iph->ihl*4)) |
407 | if (skb->len < len || len < (iph->ihl<<2)) | 408 | goto inhdr_error; |
408 | goto inhdr_error; | ||
409 | 409 | ||
410 | /* Our transport medium may have padded the buffer out. Now we know it | 410 | /* Our transport medium may have padded the buffer out. Now we know it |
411 | * is IP we can trim to the true length of the frame. | 411 | * is IP we can trim to the true length of the frame. |
412 | * Note this now means skb->len holds ntohs(iph->tot_len). | 412 | * Note this now means skb->len holds ntohs(iph->tot_len). |
413 | */ | 413 | */ |
414 | if (pskb_trim_rcsum(skb, len)) { | 414 | if (pskb_trim_rcsum(skb, len)) { |
415 | IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); | 415 | IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); |
416 | goto drop; | 416 | goto drop; |
417 | } | ||
418 | } | 417 | } |
419 | 418 | ||
420 | return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, | 419 | return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, |