mac80211: skb leak in mesh_plink_frame_tx()

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Sat Sep 29 10:59:40 EDT 2012


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=f609a43dca2964a8a604ef554be92fa11c3b4c41
Commit:     f609a43dca2964a8a604ef554be92fa11c3b4c41
Parent:     e7570dfb635b0c89570852002c9f85dd1cf82ba1
Author:     Thomas Pedersen <thomas at cozybit.com>
AuthorDate: Fri Aug 3 12:21:35 2012 -0700
Committer:  Johannes Berg <johannes.berg at intel.com>
CommitDate: Fri Aug 3 21:34:29 2012 +0200

    mac80211: skb leak in mesh_plink_frame_tx()
    
    Although adding an IE is almost guaranteed to succeed since we already
    accounted for its length while allocating the skb, we should still free
    the skb in case of failure.
    
    Signed-off-by: Thomas Pedersen <thomas at cozybit.com>
    Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
 net/mac80211/mesh_plink.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index bad5126..5fd1250 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -224,6 +224,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 	u8 *pos, ie_len = 4;
 	int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
 		      sizeof(mgmt->u.action.u.self_prot);
+	int err = -ENOMEM;
 
 	skb = dev_alloc_skb(local->tx_headroom +
 			    hdr_len +
@@ -267,11 +268,11 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 		    mesh_add_rsn_ie(skb, sdata) ||
 		    mesh_add_meshid_ie(skb, sdata) ||
 		    mesh_add_meshconf_ie(skb, sdata))
-			return -1;
+			goto free;
 	} else {	/* WLAN_SP_MESH_PEERING_CLOSE */
 		info->flags |= IEEE80211_TX_CTL_NO_ACK;
 		if (mesh_add_meshid_ie(skb, sdata))
-			return -1;
+			goto free;
 	}
 
 	/* Add Mesh Peering Management element */
@@ -290,11 +291,12 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 		ie_len += 2;	/* reason code */
 		break;
 	default:
-		return -EINVAL;
+		err = -EINVAL;
+		goto free;
 	}
 
 	if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
-		return -ENOMEM;
+		goto free;
 
 	pos = skb_put(skb, 2 + ie_len);
 	*pos++ = WLAN_EID_PEER_MGMT;
@@ -315,14 +317,17 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
 		if (mesh_add_ht_cap_ie(skb, sdata) ||
 		    mesh_add_ht_oper_ie(skb, sdata))
-			return -1;
+			goto free;
 	}
 
 	if (mesh_add_vendor_ies(skb, sdata))
-		return -1;
+		goto free;
 
 	ieee80211_tx_skb(sdata, skb);
 	return 0;
+free:
+	kfree_skb(skb);
+	return err;
 }
 
 /**



More information about the linux-mtd-cvs mailing list