Skip to content

Commit

Permalink
mwifiex: failure path handling in mwifiex_add_virtual_intf()
Browse files Browse the repository at this point in the history
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@gmail.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Amitkumar Karwar authored and John W. Linville committed Nov 15, 2013
1 parent 68b76e9 commit bec568f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 deletions.
20 changes: 16 additions & 4 deletions drivers/net/wireless/mwifiex/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
13 changes: 2 additions & 11 deletions drivers/net/wireless/mwifiex/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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);
Expand Down

0 comments on commit bec568f

Please sign in to comment.