diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index a06b6041f3e0..384a1014da07 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -232,8 +232,10 @@ err_unlock: spin_unlock_bh(&chain->lock); err: - if (!ret) + if (!ret) { kfree(frag_entry_new); + kfree_skb(skb); + } return ret; } @@ -305,7 +307,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. @@ -330,9 +332,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; } diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 8b98609ebc1e..f9ffb1825f6d 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1080,6 +1080,12 @@ int batadv_recv_frag_packet(struct sk_buff *skb, batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_RX); batadv_add_counter(bat_priv, BATADV_CNT_FRAG_RX_BYTES, skb->len); + /* batadv_frag_skb_buffer will always consume the skb and + * the caller should therefore never try to free the + * skb after this point + */ + ret = NET_RX_SUCCESS; + /* Add fragment to buffer and merge if possible. */ if (!batadv_frag_skb_buffer(&skb, orig_node_src)) goto out;