summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-08-23 09:30:03 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-08-23 09:30:03 -0700
commitd4c70706b7d8cf897a770ac05a253863c3154355 (patch)
tree502480e08cdceb8a7e1692a15c3e5501e10b7058 /drivers/char
parente243bb85026ba9a88de4e860b265594da4f73706 (diff)
parentdb3571191155d72ebe5b94ad40cff5574f2d9543 (diff)
Merge "diag: Fix possible usage of freed resource issue"
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/diag/diagchar_core.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index eaed3b101095..4111e599877a 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -3029,6 +3029,16 @@ static int diag_user_process_apps_data(const char __user *buf, int len,
return 0;
}
+static int check_data_ready(int index)
+{
+ int data_type = 0;
+
+ mutex_lock(&driver->diagchar_mutex);
+ data_type = driver->data_ready[index];
+ mutex_unlock(&driver->diagchar_mutex);
+ return data_type;
+}
+
static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
@@ -3041,9 +3051,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
int write_len = 0;
struct diag_md_session_t *session_info = NULL;
+ mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid == current->tgid)
index = i;
+ mutex_unlock(&driver->diagchar_mutex);
if (index == -1) {
pr_err("diag: Client PID not found in table");
@@ -3053,7 +3065,7 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
pr_err("diag: bad address from user side\n");
return -EFAULT;
}
- wait_event_interruptible(driver->wait_q, driver->data_ready[index]);
+ wait_event_interruptible(driver->wait_q, (check_data_ready(index)) > 0);
mutex_lock(&driver->diagchar_mutex);
@@ -3194,11 +3206,11 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
}
exit:
- mutex_unlock(&driver->diagchar_mutex);
if (driver->data_ready[index] & DCI_DATA_TYPE) {
- mutex_lock(&driver->dci_mutex);
- /* Copy the type of data being passed */
data_type = driver->data_ready[index] & DCI_DATA_TYPE;
+ mutex_unlock(&driver->diagchar_mutex);
+ /* Copy the type of data being passed */
+ mutex_lock(&driver->dci_mutex);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl,
track);
@@ -3230,6 +3242,7 @@ exit:
mutex_unlock(&driver->dci_mutex);
goto end;
}
+ mutex_unlock(&driver->diagchar_mutex);
end:
/*
* Flush any read that is currently pending on DCI data and