瀏覽代碼

qcacld-3.0: Fix mem leak in hdd_objmgr_create_and_store_vdev

In the error path of hdd_objmgr_create_and_store_vdev,
osif_priv->osif_tdls is not freed.
Call wlan_cfg80211_tdls_priv_deinit to free the buffer
in error path.

Change-Id: I4f1fdca1a6a4f2e8c061dc227632850d5baab320
CRs-Fixed: 2275008
Min Liu 6 年之前
父節點
當前提交
e4b38a08e2
共有 1 個文件被更改,包括 21 次插入9 次删除
  1. 21 9
      core/hdd/src/wlan_hdd_object_manager.c

+ 21 - 9
core/hdd/src/wlan_hdd_object_manager.c

@@ -48,13 +48,29 @@ static void hdd_deinit_pdev_os_priv(struct wlan_objmgr_pdev *pdev)
 	wlan_cfg80211_scan_priv_deinit(pdev);
 }
 
-static void hdd_init_vdev_os_priv(struct hdd_adapter *adapter,
-	struct vdev_osif_priv *os_priv)
+static struct vdev_osif_priv *
+hdd_init_vdev_os_priv(struct hdd_adapter *adapter)
 {
+	struct vdev_osif_priv *os_priv;
+
+	os_priv = qdf_mem_malloc(sizeof(*os_priv));
+	if (!os_priv)
+		return NULL;
+
 	/* Initialize the vdev OS private structure*/
 	os_priv->wdev = adapter->dev->ieee80211_ptr;
 	os_priv->legacy_osif_priv = adapter;
 	wlan_cfg80211_tdls_priv_init(os_priv);
+
+	return os_priv;
+}
+
+static void hdd_deinit_vdev_os_priv(struct vdev_osif_priv *os_priv)
+{
+	if (os_priv) {
+		wlan_cfg80211_tdls_priv_deinit(os_priv);
+		qdf_mem_free(os_priv);
+	}
 }
 
 static void hdd_init_psoc_qdf_ctx(struct wlan_objmgr_psoc *psoc)
@@ -234,12 +250,11 @@ int hdd_objmgr_create_and_store_vdev(struct wlan_objmgr_pdev *pdev,
 		return -EINVAL;
 	}
 
-	osif_priv = qdf_mem_malloc(sizeof(*osif_priv));
+	osif_priv = hdd_init_vdev_os_priv(adapter);
 	if (!osif_priv) {
 		hdd_err("Failed to allocate osif_priv; out of memory");
 		return -ENOMEM;
 	}
-	hdd_init_vdev_os_priv(adapter, osif_priv);
 
 	vdev_params.opmode = adapter->device_mode;
 	vdev_params.osifp = osif_priv;
@@ -275,7 +290,7 @@ vdev_destroy:
 	wlan_objmgr_vdev_obj_delete(vdev);
 
 osif_priv_free:
-	qdf_mem_free(osif_priv);
+	hdd_deinit_vdev_os_priv(osif_priv);
 
 	return errno;
 }
@@ -297,10 +312,7 @@ int hdd_objmgr_release_and_destroy_vdev(struct hdd_adapter *adapter)
 	wlan_vdev_reset_ospriv(vdev);
 
 	QDF_BUG(osif_priv);
-	if (osif_priv) {
-		wlan_cfg80211_tdls_priv_deinit(osif_priv);
-		qdf_mem_free(osif_priv);
-	}
+	hdd_deinit_vdev_os_priv(osif_priv);
 
 	status = wlan_objmgr_vdev_obj_delete(vdev);
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);