mwifiex: failure path handling in mwifiex_add_virtual_intf()

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:07 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=bec568ff51078276109e21b5521829e2dd60a7fa
Commit:     bec568ff51078276109e21b5521829e2dd60a7fa
Parent:     68b76e99d1f7b696d49b5e99286401150072987a
Author:     Amitkumar Karwar <akarwar at marvell.com>
AuthorDate: Thu Nov 14 19:10:38 2013 -0800
Committer:  John W. Linville <linville at tuxdriver.com>
CommitDate: Fri Nov 15 14:29:31 2013 -0500

    mwifiex: failure path handling in mwifiex_add_virtual_intf()
    
    1) If register_netdevice() is failed, we are freeing netdev
    pointer, but priv->netdev is not cleared. This gives kernel
    paging request error when driver is unloaded or interface is
    deleted. Fix the problem by clearing the pointer.
    2) Fix memory leak issue by freeing 'wdev' in failure paths.
    Also, clear priv->wdev pointer.
    
    As mwifiex_add_virtual_intf() successfully handles the
    failure conditions, redundant code under err_add_intf label
    is removed in this patch.
    
    Reported-by: Ujjal Roy <royujjal at gmail.com>
    Signed-off-by: Amitkumar Karwar <akarwar at marvell.com>
    Signed-off-by: Bing Zhao <bzhao at marvell.com>
    Signed-off-by: John W. Linville <linville at tuxdriver.com>
---
 drivers/net/wireless/mwifiex/cfg80211.c | 20 ++++++++++++++++----
 drivers/net/wireless/mwifiex/main.c     | 13 ++-----------
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index fbad00a..ccc9c08 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2210,8 +2210,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 		priv->bss_started = 0;
 		priv->bss_num = 0;
 
-		if (mwifiex_cfg80211_init_p2p_client(priv))
-			return ERR_PTR(-EFAULT);
+		if (mwifiex_cfg80211_init_p2p_client(priv)) {
+			wdev = ERR_PTR(-EFAULT);
+			goto done;
+		}
 
 		break;
 	default:
@@ -2224,7 +2226,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 	if (!dev) {
 		wiphy_err(wiphy, "no memory available for netdevice\n");
 		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-		return ERR_PTR(-ENOMEM);
+		wdev = ERR_PTR(-ENOMEM);
+		goto done;
 	}
 
 	mwifiex_init_priv_params(priv, dev);
@@ -2264,7 +2267,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 		wiphy_err(wiphy, "cannot register virtual network device\n");
 		free_netdev(dev);
 		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-		return ERR_PTR(-EFAULT);
+		priv->netdev = NULL;
+		wdev = ERR_PTR(-EFAULT);
+		goto done;
 	}
 
 	sema_init(&priv->async_sem, 1);
@@ -2274,6 +2279,13 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 #ifdef CONFIG_DEBUG_FS
 	mwifiex_dev_debugfs_init(priv);
 #endif
+
+done:
+	if (IS_ERR(wdev)) {
+		kfree(priv->wdev);
+		priv->wdev = NULL;
+	}
+
 	return wdev;
 }
 EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 7c7da3e..9236b42 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -411,7 +411,7 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
  */
 static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 {
-	int ret, i;
+	int ret;
 	char fmt[64];
 	struct mwifiex_private *priv;
 	struct mwifiex_adapter *adapter = context;
@@ -479,6 +479,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 					NL80211_IFTYPE_STATION, NULL, NULL);
 	if (IS_ERR(wdev)) {
 		dev_err(adapter->dev, "cannot create default STA interface\n");
+		rtnl_unlock();
 		goto err_add_intf;
 	}
 	rtnl_unlock();
@@ -488,16 +489,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 	goto done;
 
 err_add_intf:
-	for (i = 0; i < adapter->priv_num; i++) {
-		priv = adapter->priv[i];
-
-		if (!priv)
-			continue;
-
-		if (priv->wdev && priv->netdev)
-			mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
-	}
-	rtnl_unlock();
 err_register_cfg80211:
 	wiphy_unregister(adapter->wiphy);
 	wiphy_free(adapter->wiphy);



More information about the linux-mtd-cvs mailing list