diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d4a31becbd25dda895d7391e1e65c2de237bf2a3..f66ecd9cebab7619ebe82e0efd78ff386e2b35a6 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1506,6 +1506,13 @@ static int __ip6_append_data(struct sock *sk, data += fragheaderlen; skb->transport_header = (skb->network_header + fragheaderlen); + copy = datalen - transhdrlen - fraggap; + + if (copy < 0) { + err = -EINVAL; + kfree_skb(skb); + goto error; + } if (fraggap) { skb->csum = skb_copy_and_csum_bits( skb_prev, maxfraglen, @@ -1515,13 +1522,9 @@ static int __ip6_append_data(struct sock *sk, data += fraggap; pskb_trim_unique(skb_prev, maxfraglen); } - copy = datalen - transhdrlen - fraggap; - - if (copy < 0) { - err = -EINVAL; - kfree_skb(skb); - goto error; - } else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) { + if (copy > 0 && getfrag(from, data + transhdrlen, + offset, copy, fraggap, + skb) < 0) { err = -EFAULT; kfree_skb(skb); goto error;