diff options
| author | J. Bruce Fields <bfields@citi.umich.edu> | 2009-11-23 12:34:58 -0500 |
|---|---|---|
| committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-11-23 12:34:58 -0500 |
| commit | 9b8b317d58084b9a44f6f33b355c4278d9f841fb (patch) | |
| tree | e0df89800bf4301c4017db3cdf04a2056ec1a852 /net/ipv4/raw.c | |
| parent | 78c210efdefe07131f91ed512a3308b15bb14e2f (diff) | |
| parent | 648f4e3e50c4793d9dbf9a09afa193631f76fa26 (diff) | |
Merge commit 'v2.6.32-rc8' into HEAD
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 757c9171e7c..ab996f9c0fe 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); |
