diff options
author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-08-23 09:30:03 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-08-23 09:30:03 -0700 |
commit | d4c70706b7d8cf897a770ac05a253863c3154355 (patch) | |
tree | 502480e08cdceb8a7e1692a15c3e5501e10b7058 /drivers/char | |
parent | e243bb85026ba9a88de4e860b265594da4f73706 (diff) | |
parent | db3571191155d72ebe5b94ad40cff5574f2d9543 (diff) |
Merge "diag: Fix possible usage of freed resource issue"
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/diag/diagchar_core.c | 21 |
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 |