summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/diag/diag_dci.c9
-rw-r--r--drivers/char/diag/diagchar_core.c20
2 files changed, 23 insertions, 6 deletions
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index b0b36d00415d..4051521583b0 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, 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
@@ -2296,8 +2296,8 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
pid_struct = find_get_pid(entry->tgid);
if (!pid_struct) {
DIAG_LOG(DIAG_DEBUG_DCI,
- "diag: valid pid doesn't exist for pid = %d\n",
- entry->tgid);
+ "diag: Exited pid (%d) doesn't match dci client of pid (%d)\n",
+ tgid, entry->tgid);
continue;
}
task_s = get_pid_task(pid_struct, PIDTYPE_PID);
@@ -3085,6 +3085,9 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
if (!list_empty(&entry->track))
list_del(&entry->track);
driver->num_dci_client--;
+
+ put_task_struct(entry->client);
+ entry->client = NULL;
/*
* Clear the client's log and event masks, update the cumulative
* masks and send the masks to peripherals
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index d6c92d6d417c..5deeac9d80e8 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -22,6 +22,7 @@
#include <linux/sched.h>
#include <linux/ratelimit.h>
#include <linux/timer.h>
+#include <linux/sched.h>
#include <linux/platform_device.h>
#include <linux/msm_mhi.h>
#ifdef CONFIG_DIAG_OVER_USB
@@ -583,8 +584,8 @@ static int diag_remove_client_entry(struct file *file)
static int diagchar_close(struct inode *inode, struct file *file)
{
int ret;
- DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: process exit %s\n",
- current->comm);
+ DIAG_LOG(DIAG_DEBUG_USERSPACE, "diag: %s process exit with pid = %d\n",
+ current->comm, current->tgid);
ret = diag_remove_client_entry(file);
mutex_lock(&driver->diag_maskclear_mutex);
driver->mask_clear = 0;
@@ -3124,6 +3125,8 @@ static ssize_t diagchar_read(struct file *file, char __user *buf, size_t count,
int exit_stat = 0;
int write_len = 0;
struct diag_md_session_t *session_info = NULL;
+ struct pid *pid_struct = NULL;
+ struct task_struct *task_s = NULL;
mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients; i++)
@@ -3331,8 +3334,19 @@ exit:
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl,
track);
- if (entry->client->tgid != current->tgid)
+ pid_struct = find_get_pid(entry->tgid);
+ if (!pid_struct)
+ continue;
+ task_s = get_pid_task(pid_struct, PIDTYPE_PID);
+ if (!task_s) {
+ DIAG_LOG(DIAG_DEBUG_DCI,
+ "diag: valid task doesn't exist for pid = %d\n",
+ entry->tgid);
continue;
+ }
+ if (task_s == entry->client)
+ if (entry->client->tgid != current->tgid)
+ continue;
if (!entry->in_service)
continue;
if (copy_to_user(buf + ret, &data_type, sizeof(int))) {