Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8f18c9f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: dci: Prevent task deallocation and possible resource leak"

parents c6da4f4a 03c2a8cc
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
/* 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
+17 −3
Original line number Diff line number Diff line
@@ -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,6 +3334,17 @@ exit:
		list_for_each_safe(start, temp, &driver->dci_client_list) {
			entry = list_entry(start, struct diag_dci_client_tbl,
									track);
			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)