Commit bec568ff authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville

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: default avatarUjjal Roy <royujjal@gmail.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 68b76e99
...@@ -2210,8 +2210,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, ...@@ -2210,8 +2210,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->bss_started = 0; priv->bss_started = 0;
priv->bss_num = 0; priv->bss_num = 0;
if (mwifiex_cfg80211_init_p2p_client(priv)) if (mwifiex_cfg80211_init_p2p_client(priv)) {
return ERR_PTR(-EFAULT); wdev = ERR_PTR(-EFAULT);
goto done;
}
break; break;
default: default:
...@@ -2224,7 +2226,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, ...@@ -2224,7 +2226,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
if (!dev) { if (!dev) {
wiphy_err(wiphy, "no memory available for netdevice\n"); wiphy_err(wiphy, "no memory available for netdevice\n");
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
return ERR_PTR(-ENOMEM); wdev = ERR_PTR(-ENOMEM);
goto done;
} }
mwifiex_init_priv_params(priv, dev); mwifiex_init_priv_params(priv, dev);
...@@ -2264,7 +2267,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, ...@@ -2264,7 +2267,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
wiphy_err(wiphy, "cannot register virtual network device\n"); wiphy_err(wiphy, "cannot register virtual network device\n");
free_netdev(dev); free_netdev(dev);
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 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); sema_init(&priv->async_sem, 1);
...@@ -2274,6 +2279,13 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, ...@@ -2274,6 +2279,13 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
mwifiex_dev_debugfs_init(priv); mwifiex_dev_debugfs_init(priv);
#endif #endif
done:
if (IS_ERR(wdev)) {
kfree(priv->wdev);
priv->wdev = NULL;
}
return wdev; return wdev;
} }
EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
......
...@@ -411,7 +411,7 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter) ...@@ -411,7 +411,7 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
*/ */
static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
{ {
int ret, i; int ret;
char fmt[64]; char fmt[64];
struct mwifiex_private *priv; struct mwifiex_private *priv;
struct mwifiex_adapter *adapter = context; struct mwifiex_adapter *adapter = context;
...@@ -479,6 +479,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) ...@@ -479,6 +479,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
NL80211_IFTYPE_STATION, NULL, NULL); NL80211_IFTYPE_STATION, NULL, NULL);
if (IS_ERR(wdev)) { if (IS_ERR(wdev)) {
dev_err(adapter->dev, "cannot create default STA interface\n"); dev_err(adapter->dev, "cannot create default STA interface\n");
rtnl_unlock();
goto err_add_intf; goto err_add_intf;
} }
rtnl_unlock(); rtnl_unlock();
...@@ -488,16 +489,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) ...@@ -488,16 +489,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
goto done; goto done;
err_add_intf: 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: err_register_cfg80211:
wiphy_unregister(adapter->wiphy); wiphy_unregister(adapter->wiphy);
wiphy_free(adapter->wiphy); wiphy_free(adapter->wiphy);
......
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