aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 58f6288e9ba5..bf8a58a1c32d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -597,7 +597,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
597 int ptr, offset = 0, err = 0; 597 int ptr, offset = 0, err = 0;
598 u8 *prevhdr, nexthdr = 0; 598 u8 *prevhdr, nexthdr = 0;
599 599
600 hlen = ip6_find_1stfragopt(skb, &prevhdr); 600 err = ip6_find_1stfragopt(skb, &prevhdr);
601 if (err < 0)
602 goto fail;
603 hlen = err;
601 nexthdr = *prevhdr; 604 nexthdr = *prevhdr;
602 605
603 mtu = ip6_skb_dst_mtu(skb); 606 mtu = ip6_skb_dst_mtu(skb);
@@ -1463,6 +1466,11 @@ alloc_new_skb:
1463 */ 1466 */
1464 alloclen += sizeof(struct frag_hdr); 1467 alloclen += sizeof(struct frag_hdr);
1465 1468
1469 copy = datalen - transhdrlen - fraggap;
1470 if (copy < 0) {
1471 err = -EINVAL;
1472 goto error;
1473 }
1466 if (transhdrlen) { 1474 if (transhdrlen) {
1467 skb = sock_alloc_send_skb(sk, 1475 skb = sock_alloc_send_skb(sk,
1468 alloclen + hh_len, 1476 alloclen + hh_len,
@@ -1512,13 +1520,9 @@ alloc_new_skb:
1512 data += fraggap; 1520 data += fraggap;
1513 pskb_trim_unique(skb_prev, maxfraglen); 1521 pskb_trim_unique(skb_prev, maxfraglen);
1514 } 1522 }
1515 copy = datalen - transhdrlen - fraggap; 1523 if (copy > 0 &&
1516 1524 getfrag(from, data + transhdrlen, offset,
1517 if (copy < 0) { 1525 copy, fraggap, skb) < 0) {
1518 err = -EINVAL;
1519 kfree_skb(skb);
1520 goto error;
1521 } else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
1522 err = -EFAULT; 1526 err = -EFAULT;
1523 kfree_skb(skb); 1527 kfree_skb(skb);
1524 goto error; 1528 goto error;