Bläddra i källkod

qcacld-3.0: Fix a memory leak in wlan_init_sysfs()

Free the memory allocated for the global variable wlan_loader. Also
properly unlink the kobject from the parent and free the memory
resources in cleanup path. Cleanup the function wlan_boot_cb().

Change-Id: I16e558c894980cbad531231ecda6fb093cf162e5
CRs-Fixed: 1085823
Mahesh Kumar Kalikot Veetil 8 år sedan
förälder
incheckning
5a3dec6ec8
1 ändrade filer med 44 tillägg och 34 borttagningar
  1. 44 34
      core/hdd/src/wlan_hdd_main.c

+ 44 - 34
core/hdd/src/wlan_hdd_main.c

@@ -9409,32 +9409,53 @@ static void __hdd_module_exit(void)
  * Return: 'count' on success or a negative error code in case of failure
  */
 static ssize_t wlan_boot_cb(struct kobject *kobj,
-				struct kobj_attribute *attr,
-				const char *buf,
-				size_t count)
+			    struct kobj_attribute *attr,
+			    const char *buf,
+			    size_t count)
 {
 
-	int ret = 0;
-
 	if (wlan_loader->loaded_state) {
-		pr_info("Wlan driver already initialized");
-		return 0;
+		pr_err("%s: wlan driver already initialized\n", __func__);
+		return -EALREADY;
 	}
 
-
-	pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
-		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
-
 	if (__hdd_module_init()) {
-		pr_err("%s: Failed to register handler\n", __func__);
-		ret = -EINVAL;
-	} else
-		wlan_loader->loaded_state = MODULE_INITIALIZED;
+		pr_err("%s: wlan driver initialization failed\n", __func__);
+		return -EIO;
+	}
+
+	wlan_loader->loaded_state = MODULE_INITIALIZED;
 
 	return count;
 
 }
 
+/**
+ * hdd_sysfs_cleanup() - cleanup sysfs
+ *
+ * Return: None
+ *
+ */
+static void hdd_sysfs_cleanup(void)
+{
+
+	/* remove from group */
+	if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
+		sysfs_remove_group(wlan_loader->boot_wlan_obj,
+				   wlan_loader->attr_group);
+
+	/* unlink the object from parent */
+	kobject_del(wlan_loader->boot_wlan_obj);
+
+	/* free the object */
+	kobject_put(wlan_loader->boot_wlan_obj);
+
+	kfree(wlan_loader->attr_group);
+	kfree(wlan_loader);
+
+	wlan_loader = NULL;
+}
+
 /**
  * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
  * ready
@@ -9442,17 +9463,19 @@ static ssize_t wlan_boot_cb(struct kobject *kobj,
  * This is creates the syfs entry boot_wlan. Which shall be invoked
  * when the filesystem is ready.
  *
+ * QDF API cannot be used here since this function is called even before
+ * initializing WLAN driver.
+ *
  * Return: 0 for success, errno on failure
  */
 static int wlan_init_sysfs(void)
 {
-	int ret = -EINVAL;
+	int ret = -ENOMEM;
 
 	wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
 	if (!wlan_loader) {
 		pr_err("%s: memory alloc failed\n", __func__);
-		ret = -ENOMEM;
-		return ret;
+		return -ENOMEM;
 	}
 
 	wlan_loader->boot_wlan_obj = NULL;
@@ -9460,7 +9483,6 @@ static int wlan_init_sysfs(void)
 					  GFP_KERNEL);
 	if (!wlan_loader->attr_group) {
 		pr_err("%s: malloc attr_group failed\n", __func__);
-		ret = -ENOMEM;
 		goto error_return;
 	}
 
@@ -9471,7 +9493,6 @@ static int wlan_init_sysfs(void)
 							    kernel_kobj);
 	if (!wlan_loader->boot_wlan_obj) {
 		pr_err("%s: sysfs create and add failed\n", __func__);
-		ret = -ENOMEM;
 		goto error_return;
 	}
 
@@ -9485,11 +9506,7 @@ static int wlan_init_sysfs(void)
 	return 0;
 
 error_return:
-
-	if (wlan_loader->boot_wlan_obj) {
-		kobject_del(wlan_loader->boot_wlan_obj);
-		wlan_loader->boot_wlan_obj = NULL;
-	}
+	hdd_sysfs_cleanup();
 
 	return ret;
 }
@@ -9501,23 +9518,16 @@ error_return:
  */
 static int wlan_deinit_sysfs(void)
 {
-
 	if (!wlan_loader) {
 		hdd_alert("wlan loader context is Null!");
 		return -EINVAL;
 	}
 
-	if (wlan_loader->boot_wlan_obj) {
-		sysfs_remove_group(wlan_loader->boot_wlan_obj,
-				   wlan_loader->attr_group);
-		kobject_del(wlan_loader->boot_wlan_obj);
-		wlan_loader->boot_wlan_obj = NULL;
-	}
-
+	hdd_sysfs_cleanup();
 	return 0;
 }
 
-#endif
+#endif /* MODULE */
 
 #ifdef MODULE
 /**