]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/ipv4/ip_output.c
inet: protect against too small mtu values.
[mirror_ubuntu-bionic-kernel.git] / net / ipv4 / ip_output.c
index e8e675be60ec0044007c660bae1bb4d12c9a484e..73cd64c7692f9d109bef25f618928d1db8a795a6 100644 (file)
@@ -518,11 +518,14 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
        to->pkt_type = from->pkt_type;
        to->priority = from->priority;
        to->protocol = from->protocol;
+       to->skb_iif = from->skb_iif;
        skb_dst_drop(to);
        skb_dst_copy(to, from);
        to->dev = from->dev;
        to->mark = from->mark;
 
+       skb_copy_hash(to, from);
+
        /* Copy the flags to each fragment. */
        IPCB(to)->flags = IPCB(from)->flags;
 
@@ -1040,7 +1043,8 @@ alloc_new_skb:
                if (copy > length)
                        copy = length;
 
-               if (!(rt->dst.dev->features&NETIF_F_SG)) {
+               if (!(rt->dst.dev->features&NETIF_F_SG) &&
+                   skb_tailroom(skb) >= copy) {
                        unsigned int off;
 
                        off = skb->len;
@@ -1119,13 +1123,17 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
        rt = *rtp;
        if (unlikely(!rt))
                return -EFAULT;
-       /*
-        * We steal reference to this route, caller should not release it
-        */
-       *rtp = NULL;
+
        cork->fragsize = ip_sk_use_pmtu(sk) ?
-                        dst_mtu(&rt->dst) : rt->dst.dev->mtu;
+                        dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
+
+       if (!inetdev_valid_mtu(cork->fragsize))
+               return -ENETUNREACH;
+
        cork->dst = &rt->dst;
+       /* We stole this route, caller should not release it. */
+       *rtp = NULL;
+
        cork->length = 0;
        cork->ttl = ipc->ttl;
        cork->tos = ipc->tos;