From 0ac5f6f2f221efb93fc0ddb1fec6487c76d95acd Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Tue, 14 Feb 2017 19:10:47 -0800 Subject: qcacld-2.0: Acquire lock to protect hdd_ctx in hdd_driver_memdump_read() 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 --- CORE/HDD/src/wlan_hdd_memdump.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CORE/HDD/src/wlan_hdd_memdump.c b/CORE/HDD/src/wlan_hdd_memdump.c index 4433107..778ec07 100644 --- a/CORE/HDD/src/wlan_hdd_memdump.c +++ b/CORE/HDD/src/wlan_hdd_memdump.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -741,11 +741,14 @@ static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf, if (0 != status) return -EINVAL; + mutex_lock(&hdd_ctx->memdump_lock); if (*pos < 0) { + mutex_unlock(&hdd_ctx->memdump_lock); hddLog(LOGE, FL("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); hddLog(LOGE, FL("No more data to copy")); return 0; } else if ((*pos == 0) || (hdd_ctx->driver_dump_mem == NULL)) { @@ -756,6 +759,7 @@ static ssize_t hdd_driver_memdump_read(struct file *file, char __user *buf, hdd_ctx->driver_dump_mem = vos_mem_malloc(DRIVER_MEM_DUMP_SIZE); if (!hdd_ctx->driver_dump_mem) { + mutex_unlock(&hdd_ctx->memdump_lock); hddLog(LOGE, FL("vos_mem_malloc failed")); return -ENOMEM; } @@ -784,6 +788,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); hddLog(LOGE, FL("copy to user space failed")); return -EFAULT; } @@ -795,6 +800,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; } -- cgit v1.1