qseecom: fix memory leak in qseecom_start_app()
Fixes the incorrect return path in qseecom_start_app() function with
proper clean-up. With out this patch, there are lot of memory leaks.
Change-Id: Ied95480fa28b11efa3e53219102bfbe782921351
Signed-off-by: AnilKumar Chimata <anilc@codeaurora.org>
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 232b4ae..1a570fd 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -4444,11 +4444,8 @@
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data) {
- if (ret == 0) {
- kfree(*handle);
- *handle = NULL;
- }
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto exit_handle_free;
}
data->abort = 0;
data->type = QSEECOM_CLIENT_APP;
@@ -4463,10 +4460,8 @@
ION_HEAP(ION_QSECOM_HEAP_ID), 0);
if (IS_ERR_OR_NULL(data->client.ihandle)) {
pr_err("Ion client could not retrieve the handle\n");
- kfree(data);
- kfree(*handle);
- *handle = NULL;
- return -EINVAL;
+ ret = -ENOMEM;
+ goto exit_data_free;
}
mutex_lock(&app_access_lock);
@@ -4474,7 +4469,7 @@
strlcpy(app_ireq.app_name, app_name, MAX_APP_NAME_SIZE);
ret = __qseecom_check_app_exists(app_ireq, &app_id);
if (ret)
- goto err;
+ goto exit_ion_free;
strlcpy(data->client.app_name, app_name, MAX_APP_NAME_SIZE);
if (app_id) {
@@ -4500,23 +4495,22 @@
qseecom.pdev->init_name);
ret = __qseecom_load_fw(data, app_name, &app_id);
if (ret < 0)
- goto err;
+ goto exit_ion_free;
}
data->client.app_id = app_id;
if (!found_app) {
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
pr_err("kmalloc for app entry failed\n");
- ret = -ENOMEM;
- goto err;
+ ret = -ENOMEM;
+ goto exit_ion_free;
}
entry->app_id = app_id;
entry->ref_cnt = 1;
strlcpy(entry->app_name, app_name, MAX_APP_NAME_SIZE);
if (__qseecom_get_fw_size(app_name, &fw_size, &app_arch)) {
ret = -EIO;
- kfree(entry);
- goto err;
+ goto exit_entry_free;
}
entry->app_arch = app_arch;
entry->app_blocked = false;
@@ -4532,7 +4526,7 @@
if (ret) {
pr_err("Cannot get phys_addr for the Ion Client, ret = %d\n",
ret);
- goto err;
+ goto exit_entry_free;
}
/* Populate the structure for sending scm call to load image */
@@ -4541,7 +4535,7 @@
if (IS_ERR_OR_NULL(data->client.sb_virt)) {
pr_err("ION memory mapping for client shared buf failed\n");
ret = -ENOMEM;
- goto err;
+ goto exit_entry_free;
}
data->client.user_virt_sb_base = (uintptr_t)data->client.sb_virt;
data->client.sb_phys = (phys_addr_t)pa;
@@ -4552,7 +4546,7 @@
kclient_entry = kzalloc(sizeof(*kclient_entry), GFP_KERNEL);
if (!kclient_entry) {
ret = -ENOMEM;
- goto err;
+ goto exit_ion_unmap_kernel;
}
kclient_entry->handle = *handle;
@@ -4564,11 +4558,24 @@
mutex_unlock(&app_access_lock);
return 0;
-err:
- kfree(data);
- kfree(*handle);
- *handle = NULL;
+exit_ion_unmap_kernel:
+ if (!IS_ERR_OR_NULL(data->client.ihandle))
+ ion_unmap_kernel(qseecom.ion_clnt, data->client.ihandle);
+exit_entry_free:
+ kfree(entry);
+exit_ion_free:
mutex_unlock(&app_access_lock);
+ if (!IS_ERR_OR_NULL(data->client.ihandle)) {
+ ion_free(qseecom.ion_clnt, data->client.ihandle);
+ data->client.ihandle = NULL;
+ }
+exit_data_free:
+ kfree(data);
+exit_handle_free:
+ if (*handle) {
+ kfree(*handle);
+ *handle = NULL;
+ }
return ret;
}
EXPORT_SYMBOL(qseecom_start_app);