Commit 6ab2b999 authored by David S. Miller's avatar David S. Miller

Merge tag 'batadv-net-for-davem-20170301' of git://git.open-mesh.org/linux-merge

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: default avatarDavid S. Miller <davem@davemloft.net>
parents f1304f7b 51c6b429
...@@ -239,8 +239,10 @@ static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node, ...@@ -239,8 +239,10 @@ static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node,
spin_unlock_bh(&chain->lock); spin_unlock_bh(&chain->lock);
err: err:
if (!ret) if (!ret) {
kfree(frag_entry_new); kfree(frag_entry_new);
kfree_skb(skb);
}
return ret; return ret;
} }
...@@ -313,7 +315,7 @@ batadv_frag_merge_packets(struct hlist_head *chain) ...@@ -313,7 +315,7 @@ batadv_frag_merge_packets(struct hlist_head *chain)
* *
* There are three possible outcomes: 1) Packet is merged: Return true and * 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 * 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 * Return: true when packet is merged or buffered, false when skb is not not
* used. * used.
...@@ -338,9 +340,9 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb, ...@@ -338,9 +340,9 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,
goto out_err; goto out_err;
out: out:
*skb = skb_out;
ret = true; ret = true;
out_err: out_err:
*skb = skb_out;
return ret; return ret;
} }
...@@ -499,6 +501,12 @@ int batadv_frag_send_packet(struct sk_buff *skb, ...@@ -499,6 +501,12 @@ int batadv_frag_send_packet(struct sk_buff *skb,
/* Eat and send fragments from the tail of skb */ /* Eat and send fragments from the tail of skb */
while (skb->len > max_fragment_size) { 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); skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
if (!skb_fragment) { if (!skb_fragment) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -515,12 +523,6 @@ int batadv_frag_send_packet(struct sk_buff *skb, ...@@ -515,12 +523,6 @@ int batadv_frag_send_packet(struct sk_buff *skb,
} }
frag_header.no++; 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. */ /* Make room for the fragment header. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment