summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaidiReddy Yenuga <saidir@codeaurora.org>2017-03-08 16:17:55 +0530
committerqcabuildsw <qcabuildsw@localhost>2017-03-10 01:38:05 -0800
commit6a40481429c3489ae0a6ef208e1e02b63a25bb77 (patch)
treecc1214ee196576fedd7ff79b38c71c9f56b91141
parent0712ce3a813241f0edb51d7ed150bfdb8e463cca (diff)
qcacld-3.0: Acquire lock to protect hdd_ctx in hdd_driver_memdump_read()
qcacld-2.0 to qcacld-3.0 propagation. Two threads accessing the procfs entry might end up in race condition and lead to use-after-free for hdd_ctx->driver_dump_mem. Hence, acquire a lock to protect hdd_ctx. Change-Id: If871f4ceadf650978e16b4a336f688a0dae1c494 CRs-Fixed: 2005832
-rw-r--r--core/hdd/src/wlan_hdd_memdump.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/core/hdd/src/wlan_hdd_memdump.c b/core/hdd/src/wlan_hdd_memdump.c
index d980732228e9..0d2a6b65e592 100644
--- a/core/hdd/src/wlan_hdd_memdump.c
+++ b/core/hdd/src/wlan_hdd_memdump.c
@@ -698,11 +698,14 @@ static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf,
if (status != 0)
return -EINVAL;
+ mutex_lock(&hdd_ctx->memdump_lock);
if (*pos < 0) {
+ mutex_unlock(&hdd_ctx->memdump_lock);
hdd_err("Invalid start offset for memdump read");
return -EINVAL;
} else if (!count || (hdd_ctx->driver_dump_size &&
(*pos >= hdd_ctx->driver_dump_size))) {
+ mutex_unlock(&hdd_ctx->memdump_lock);
hdd_debug("No more data to copy");
return 0;
} else if ((*pos == 0) || (hdd_ctx->driver_dump_mem == NULL)) {
@@ -713,6 +716,7 @@ static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf,
hdd_ctx->driver_dump_mem =
qdf_mem_malloc(DRIVER_MEM_DUMP_SIZE);
if (!hdd_ctx->driver_dump_mem) {
+ mutex_unlock(&hdd_ctx->memdump_lock);
hdd_err("qdf_mem_malloc failed");
return -ENOMEM;
}
@@ -741,6 +745,7 @@ static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf,
if (copy_to_user(buf, hdd_ctx->driver_dump_mem + *pos,
no_of_bytes_read)) {
+ mutex_unlock(&hdd_ctx->memdump_lock);
hdd_err("copy to user space failed");
return -EFAULT;
}
@@ -752,6 +757,8 @@ static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf,
if (*pos >= hdd_ctx->driver_dump_size)
hdd_driver_mem_cleanup();
+ mutex_unlock(&hdd_ctx->memdump_lock);
+
return no_of_bytes_read;
}