qcacld-3.0: Race condition while memdump read

There can be a race condition if two threads tries to execute
memdump read which may lead to use-after-free case.

To address this issue implement the use and free of the memory into
the lock.

Change-Id: Ie4d15e9a6414f556a622869d561c331c6bc5d85e
CRs-Fixed: 2023313
This commit is contained in:
Ashish Kumar Dhanotiya 2017-04-07 13:03:36 +05:30 • committed by Sandeep Puligilla
commit 1f75a53ecc

View file

@ -404,29 +404,36 @@ static ssize_t memdump_read(struct file *file, char __user *buf,
return -EINVAL;
}
mutex_lock(&hdd_ctx->memdump_lock);
if (!hdd_ctx->memdump_in_progress) {
hdd_err("Current mem dump request timed out/failed");
return -EINVAL;
status = -EINVAL;
goto memdump_read_fail;
}
if (*pos < 0) {
hdd_err("Invalid start offset for memdump read");
return -EINVAL;
status = -EINVAL;
goto memdump_read_fail;
} else if (*pos >= FW_MEM_DUMP_SIZE || !count) {
hdd_debug("No more data to copy");
return 0;
status = 0;
goto memdump_read_fail;
} else if (count > FW_MEM_DUMP_SIZE - *pos) {
count = FW_MEM_DUMP_SIZE - *pos;
}
if (!hdd_ctx->fw_dump_loc) {
hdd_err("Invalid fw mem dump location");
return -EINVAL;
status = -EINVAL;
goto memdump_read_fail;
}
if (copy_to_user(buf, hdd_ctx->fw_dump_loc + *pos, count)) {
hdd_err("copy to user space failed");
return -EFAULT;
status = -EFAULT;
goto memdump_read_fail;
}
/* offset(pos) should be updated here based on the copy done*/
@ -435,7 +442,6 @@ static ssize_t memdump_read(struct file *file, char __user *buf,
/* Entire FW memory dump copy completed */
if (*pos >= FW_MEM_DUMP_SIZE) {
paddr = hdd_ctx->dump_loc_paddr;
mutex_lock(&hdd_ctx->memdump_lock);
qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
FW_MEM_DUMP_SIZE, hdd_ctx->fw_dump_loc, paddr, dma_ctx);
hdd_ctx->fw_dump_loc = NULL;
@ -445,10 +451,12 @@ static ssize_t memdump_read(struct file *file, char __user *buf,
&hdd_ctx->memdump_cleanup_timer)) {
qdf_mc_timer_stop(&hdd_ctx->memdump_cleanup_timer);
}
mutex_unlock(&hdd_ctx->memdump_lock);
}
return count;
}
status = count;
memdump_read_fail:
mutex_unlock(&hdd_ctx->memdump_lock);
return status;
}
/**