diff options
author | David S. Miller <davem@davemloft.net> | 2009-10-30 00:28:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-30 00:28:59 -0400 |
commit | 0519d83d83ed485b5a1f9222ff69d7d6c9bb8a01 (patch) | |
tree | 2e336be8a4bd2e59bcd4b69b00feb77c6672a9cb /net/ipv4/raw.c | |
parent | 38bfd8f5bec496e8e0db8849e01c99a33479418a (diff) | |
parent | b5dd884e682cae6b8c037f9d11f3b623b4cf2011 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net/ipv4/raw.c')
-rw-r--r-- | net/ipv4/raw.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 9ef8c0829a77..ce154b47f1da 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -351,13 +351,24 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
351 | skb->ip_summed = CHECKSUM_NONE; | 351 | skb->ip_summed = CHECKSUM_NONE; |
352 | 352 | ||
353 | skb->transport_header = skb->network_header; | 353 | skb->transport_header = skb->network_header; |
354 | err = memcpy_fromiovecend((void *)iph, from, 0, length); | 354 | err = -EFAULT; |
355 | if (err) | 355 | if (memcpy_fromiovecend((void *)iph, from, 0, length)) |
356 | goto error_fault; | 356 | goto error_free; |
357 | 357 | ||
358 | /* We don't modify invalid header */ | ||
359 | iphlen = iph->ihl * 4; | 358 | iphlen = iph->ihl * 4; |
360 | if (iphlen >= sizeof(*iph) && iphlen <= length) { | 359 | |
360 | /* | ||
361 | * We don't want to modify the ip header, but we do need to | ||
362 | * be sure that it won't cause problems later along the network | ||
363 | * stack. Specifically we want to make sure that iph->ihl is a | ||
364 | * sane value. If ihl points beyond the length of the buffer passed | ||
365 | * in, reject the frame as invalid | ||
366 | */ | ||
367 | err = -EINVAL; | ||
368 | if (iphlen > length) | ||
369 | goto error_free; | ||
370 | |||
371 | if (iphlen >= sizeof(*iph)) { | ||
361 | if (!iph->saddr) | 372 | if (!iph->saddr) |
362 | iph->saddr = rt->rt_src; | 373 | iph->saddr = rt->rt_src; |
363 | iph->check = 0; | 374 | iph->check = 0; |
@@ -380,8 +391,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
380 | out: | 391 | out: |
381 | return 0; | 392 | return 0; |
382 | 393 | ||
383 | error_fault: | 394 | error_free: |
384 | err = -EFAULT; | ||
385 | kfree_skb(skb); | 395 | kfree_skb(skb); |
386 | error: | 396 | error: |
387 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); | 397 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); |