diff options
author | Dennis Jeon <dennis.jeon@broadcom.corp-partner.google.com> | 2022-11-15 19:27:45 +0900 |
---|---|---|
committer | Roger Wang <wangroger@google.com> | 2022-11-18 10:35:23 +0000 |
commit | 39e26f3d52d7baedb9e514532bfdc12d23be4b41 (patch) | |
tree | 42342b9bca0f97e7597d70b3215522d1a784f493 | |
parent | 8cb56c4fd716df5848352043986a0cf53d615c92 (diff) | |
download | bcm4389-39e26f3d52d7baedb9e514532bfdc12d23be4b41.tar.gz |
dhd: Fixed not to free wdev twice in case of ENOMEM when system booting up
DHD tried to allocate kernel memory in wl_init_priv_mem() but it failed with error(ENOMEM)
and KP happened due to double-free when DHD executed a failure routine in the wl_cfg80211_attach() due to error(ENOMEM)
Fixed double free code
Bug: 258942793
Test: insmod/rmmod test done with the change which returns ENOMEM forcely
Change-Id: Ida3a61fa5b5a401f8ec08b0ea30603057f6ffd39
Signed-off-by: Dennis Jeon <dennis.jeon@broadcom.corp-partner.google.com>
-rw-r--r-- | dhd_linux.c | 4 | ||||
-rw-r--r-- | wl_cfg80211.c | 7 |
2 files changed, 9 insertions, 2 deletions
diff --git a/dhd_linux.c b/dhd_linux.c index db11bcb..76d8b22 100644 --- a/dhd_linux.c +++ b/dhd_linux.c @@ -14089,7 +14089,9 @@ void dhd_detach(dhd_pub_t *dhdp) MFREE(dhd->pub.osh, ifp, sizeof(*ifp)); ifp = NULL; #ifdef WL_CFG80211 - cfg->wdev->netdev = NULL; + if (cfg && cfg->wdev) { + cfg->wdev->netdev = NULL; + } #endif } } diff --git a/wl_cfg80211.c b/wl_cfg80211.c index fd763ea..e048ac1 100644 --- a/wl_cfg80211.c +++ b/wl_cfg80211.c @@ -11950,11 +11950,14 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev static void wl_free_wdev(struct bcm_cfg80211 *cfg) { struct wireless_dev *wdev = cfg->wdev; + struct net_device *ndev; struct wiphy *wiphy = NULL; if (!wdev) { WL_ERR(("wdev is invalid\n")); return; } + + ndev = wdev->netdev; if (wdev->wiphy) { wiphy = wdev->wiphy; @@ -11976,8 +11979,10 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg) } wl_delete_all_netinfo(cfg); + if (ndev) { + ndev->ieee80211_ptr = NULL; + } if (wiphy) { - MFREE(cfg->osh, wdev, sizeof(*wdev)); wiphy_free(wiphy); } |