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

Commit 898a25d9 authored by Gopikrishna Mogasati's avatar Gopikrishna Mogasati
Browse files

diag: Fix race condition while accessing mdlog session info



This fix allows to avoid possible race condition while
accessing mdlog session info. Without this check there
is a possibility of poison overwritten occurrence.
Also this fix allows mdlog client to check the validity
of process descriptor. Without this fix there is
possibility of crash.

CRs-Fixed: 2022664
Change-Id: Ia10e83c7376de5cab92dd2ec4ec4aa8074223ff3
Signed-off-by: default avatarGopikrishna Mogasati <gmogas@codeaurora.org>
parent ba53c451
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
};

+16 −4
Original line number Diff line number Diff line
@@ -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,
+4 −2
Original line number Diff line number Diff line
/* 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",