diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-04 09:59:47 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-04 09:59:47 -0500 |
| commit | 5cb2faa6ede7ada9cb2bffc832c4ce60f53d6834 (patch) | |
| tree | 7b72b66081d042a41dc822575503133364857ce2 /net/ipv4/raw.c | |
| parent | e0ee98513d1a2e24d2ddbdecf4216bcca29d1158 (diff) | |
| parent | 6060e8df517847bf445ebc61de7d4d9c7faae990 (diff) | |
Merge branch 'pending-misc' (early part) into devel
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 757c9171e7c2..ab996f9c0fe0 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -352,13 +352,24 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
| 352 | skb->ip_summed = CHECKSUM_NONE; | 352 | skb->ip_summed = CHECKSUM_NONE; |
| 353 | 353 | ||
| 354 | skb->transport_header = skb->network_header; | 354 | skb->transport_header = skb->network_header; |
| 355 | err = memcpy_fromiovecend((void *)iph, from, 0, length); | 355 | err = -EFAULT; |
| 356 | if (err) | 356 | if (memcpy_fromiovecend((void *)iph, from, 0, length)) |
| 357 | goto error_fault; | 357 | goto error_free; |
| 358 | 358 | ||
| 359 | /* We don't modify invalid header */ | ||
| 360 | iphlen = iph->ihl * 4; | 359 | iphlen = iph->ihl * 4; |
| 361 | if (iphlen >= sizeof(*iph) && iphlen <= length) { | 360 | |
| 361 | /* | ||
| 362 | * We don't want to modify the ip header, but we do need to | ||
| 363 | * be sure that it won't cause problems later along the network | ||
| 364 | * stack. Specifically we want to make sure that iph->ihl is a | ||
| 365 | * sane value. If ihl points beyond the length of the buffer passed | ||
| 366 | * in, reject the frame as invalid | ||
| 367 | */ | ||
| 368 | err = -EINVAL; | ||
| 369 | if (iphlen > length) | ||
| 370 | goto error_free; | ||
| 371 | |||
| 372 | if (iphlen >= sizeof(*iph)) { | ||
| 362 | if (!iph->saddr) | 373 | if (!iph->saddr) |
| 363 | iph->saddr = rt->rt_src; | 374 | iph->saddr = rt->rt_src; |
| 364 | iph->check = 0; | 375 | iph->check = 0; |
| @@ -381,8 +392,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length, | |||
| 381 | out: | 392 | out: |
| 382 | return 0; | 393 | return 0; |
| 383 | 394 | ||
| 384 | error_fault: | 395 | error_free: |
| 385 | err = -EFAULT; | ||
| 386 | kfree_skb(skb); | 396 | kfree_skb(skb); |
| 387 | error: | 397 | error: |
| 388 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); | 398 | IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS); |
