ath10k: fix memleak in mac setup
authorMichal Kazior <michal.kazior@tieto.com>
Mon, 22 Jul 2013 12:13:30 +0000 (14:13 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 30 Jul 2013 15:01:21 +0000 (18:01 +0300)
In some cases channel arrays were never freed.

The patch also unifies error handling in the mac
setup function.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/mac.c

index 07e5f7d40466bd80398220815613cc9cbe3a71a8..6144b3bf3da5ccd52d9e3f0523d1b08c240646eb 100644 (file)
@@ -3225,8 +3225,10 @@ int ath10k_mac_register(struct ath10k *ar)
                channels = kmemdup(ath10k_2ghz_channels,
                                   sizeof(ath10k_2ghz_channels),
                                   GFP_KERNEL);
-               if (!channels)
-                       return -ENOMEM;
+               if (!channels) {
+                       ret = -ENOMEM;
+                       goto err_free;
+               }
 
                band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
                band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
@@ -3245,11 +3247,8 @@ int ath10k_mac_register(struct ath10k *ar)
                                   sizeof(ath10k_5ghz_channels),
                                   GFP_KERNEL);
                if (!channels) {
-                       if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
-                               band = &ar->mac.sbands[IEEE80211_BAND_2GHZ];
-                               kfree(band->channels);
-                       }
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto err_free;
                }
 
                band = &ar->mac.sbands[IEEE80211_BAND_5GHZ];
@@ -3313,25 +3312,30 @@ int ath10k_mac_register(struct ath10k *ar)
                            ath10k_reg_notifier);
        if (ret) {
                ath10k_err("Regulatory initialization failed\n");
-               return ret;
+               goto err_free;
        }
 
        ret = ieee80211_register_hw(ar->hw);
        if (ret) {
                ath10k_err("ieee80211 registration failed: %d\n", ret);
-               return ret;
+               goto err_free;
        }
 
        if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
                ret = regulatory_hint(ar->hw->wiphy,
                                      ar->ath_common.regulatory.alpha2);
                if (ret)
-                       goto exit;
+                       goto err_unregister;
        }
 
        return 0;
-exit:
+
+err_unregister:
        ieee80211_unregister_hw(ar->hw);
+err_free:
+       kfree(ar->mac.sbands[IEEE80211_BAND_2GHZ].channels);
+       kfree(ar->mac.sbands[IEEE80211_BAND_5GHZ].channels);
+
        return ret;
 }