diff options
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); | 
