diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2017-03-30 07:20:35 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-03-30 07:20:34 -0700 |
| commit | 1743983a435e023b1ef27726e9943a61eaeb8633 (patch) | |
| tree | 3a61bac477078e82e6af35f0532013398144fd83 | |
| parent | 74611ac55aa86ee954afb32e4fd981d12d3e0a37 (diff) | |
| parent | 898a25d9ade3682252f994a474a20bdf87b67d89 (diff) | |
Merge "diag: Fix race condition while accessing mdlog session info"
| -rw-r--r-- | drivers/char/diag/diagchar.h | 1 | ||||
| -rw-r--r-- | drivers/char/diag/diagchar_core.c | 20 | ||||
| -rw-r--r-- | drivers/char/diag/diagfwd_cntl.c | 6 |
3 files changed, 21 insertions, 6 deletions
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index 9d235b7abc58..dbbd5514cdcc 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -418,6 +418,7 @@ struct diag_md_session_t { struct diag_mask_info *msg_mask; struct diag_mask_info *log_mask; struct diag_mask_info *event_mask; + struct thread_info *md_client_thread_info; struct task_struct *task; }; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index 335064352789..009a2a4f90a2 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1237,11 +1237,10 @@ int diag_md_session_create(int mode, int peripheral_mask, int proc) mutex_unlock(&driver->md_session_lock); return -ENOMEM; } - new_session->peripheral_mask = 0; new_session->pid = current->tgid; new_session->task = current; - + new_session->md_client_thread_info = current_thread_info(); new_session->log_mask = kzalloc(sizeof(struct diag_mask_info), GFP_KERNEL); if (!new_session->log_mask) { @@ -1359,7 +1358,6 @@ static void diag_md_session_close(struct diag_md_session_t *session_info) struct diag_md_session_t *diag_md_session_get_pid(int pid) { int i; - for (i = 0; i < NUM_MD_SESSIONS; i++) { if (driver->md_session_map[i] && driver->md_session_map[i]->pid == pid) @@ -1475,7 +1473,10 @@ static int diag_md_session_check(int curr_mode, int req_mode, * If this session owns all the requested peripherals, then * call function to switch the modes/masks for the md_session */ + mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); + if (!session_info) { *change_mode = 1; return 0; @@ -1504,7 +1505,9 @@ static int diag_md_session_check(int curr_mode, int req_mode, * owned by this md session */ change_mask = driver->md_session_mask & param->peripheral_mask; + mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); if (session_info) { if ((session_info->peripheral_mask & change_mask) @@ -1892,8 +1895,9 @@ static int diag_ioctl_hdlc_toggle(unsigned long ioarg) { uint8_t hdlc_support; struct diag_md_session_t *session_info = NULL; - + mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); if (copy_from_user(&hdlc_support, (void __user *)ioarg, sizeof(uint8_t))) return -EFAULT; @@ -2603,7 +2607,9 @@ static int diag_user_process_raw_data(const char __user *buf, int len) } else { wait_event_interruptible(driver->wait_q, (driver->in_busy_pktdata == 0)); + mutex_lock(&driver->md_session_lock); info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); ret = diag_process_apps_pkt(user_space_data, len, info); if (ret == 1) diag_send_error_rsp((void *)(user_space_data), len, @@ -2671,7 +2677,9 @@ static int diag_user_process_userspace_data(const char __user *buf, int len) /* send masks to local processor now */ if (!remote_proc) { + mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); if (!session_info) { pr_err("diag:In %s request came from invalid md session pid:%d", __func__, current->tgid); @@ -2832,7 +2840,9 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int)); /* place holder for number of data field */ ret += sizeof(int); + mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); exit_stat = diag_md_copy_to_user(buf, &ret, count, session_info); goto exit; @@ -2846,7 +2856,9 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count, data_type = driver->data_ready[index] & HDLC_SUPPORT_TYPE; driver->data_ready[index] ^= HDLC_SUPPORT_TYPE; COPY_USER_SPACE_OR_EXIT(buf, data_type, sizeof(int)); + mutex_lock(&driver->md_session_lock); session_info = diag_md_session_get_pid(current->tgid); + mutex_unlock(&driver->md_session_lock); if (session_info) COPY_USER_SPACE_OR_EXIT(buf+4, session_info->hdlc_disabled, diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index 62c8d0028af9..96f4a15a5d67 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -124,7 +124,9 @@ void diag_notify_md_client(uint8_t peripheral, int data) info.si_signo = SIGCONT; if (driver->md_session_map[peripheral] && driver->md_session_map[peripheral]->task) { - if (driver->md_session_map[peripheral]->pid == + if (driver->md_session_map[peripheral]-> + md_client_thread_info->task != NULL + && driver->md_session_map[peripheral]->pid == driver->md_session_map[peripheral]->task->tgid) { DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "md_session %d pid = %d, md_session %d task tgid = %d\n", |
