]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge tag 'batadv-net-for-davem-20170301' of git://git.open-mesh.org/linux-merge
authorDavid S. Miller <davem@davemloft.net>
Thu, 2 Mar 2017 21:16:08 +0000 (13:16 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Mar 2017 21:16:08 +0000 (13:16 -0800)
Simon Wunderlich says:

====================
Here are two batman-adv bugfixes:

 - fix a potential double free when fragment merges fail,
   by Sven Eckelmann

 - fix failing tranmission of the 16th (last) fragment if that exists,
   by Linus Lüssing
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
net/batman-adv/fragmentation.c

index ead18ca836de7ba134502f3ca2ea3201e6257f97..11a23fd6e1a07fa0c541fa3ea0a13775f9933893 100644 (file)
@@ -239,8 +239,10 @@ err_unlock:
        spin_unlock_bh(&chain->lock);
 
 err:
-       if (!ret)
+       if (!ret) {
                kfree(frag_entry_new);
+               kfree_skb(skb);
+       }
 
        return ret;
 }
@@ -313,7 +315,7 @@ free:
  *
  * There are three possible outcomes: 1) Packet is merged: Return true and
  * set *skb to merged packet; 2) Packet is buffered: Return true and set *skb
- * to NULL; 3) Error: Return false and leave skb as is.
+ * to NULL; 3) Error: Return false and free skb.
  *
  * Return: true when packet is merged or buffered, false when skb is not not
  * used.
@@ -338,9 +340,9 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,
                goto out_err;
 
 out:
-       *skb = skb_out;
        ret = true;
 out_err:
+       *skb = skb_out;
        return ret;
 }
 
@@ -499,6 +501,12 @@ int batadv_frag_send_packet(struct sk_buff *skb,
 
        /* Eat and send fragments from the tail of skb */
        while (skb->len > max_fragment_size) {
+               /* The initial check in this function should cover this case */
+               if (unlikely(frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1)) {
+                       ret = -EINVAL;
+                       goto put_primary_if;
+               }
+
                skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
                if (!skb_fragment) {
                        ret = -ENOMEM;
@@ -515,12 +523,6 @@ int batadv_frag_send_packet(struct sk_buff *skb,
                }
 
                frag_header.no++;
-
-               /* The initial check in this function should cover this case */
-               if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
-                       ret = -EINVAL;
-                       goto put_primary_if;
-               }
        }
 
        /* Make room for the fragment header. */