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

Commit e0895078 authored by Mohit Aggarwal's avatar Mohit Aggarwal Committed by Gerrit - the friendly Code Review server
Browse files

diag: Fix possible usage of freed resource issue



Currently, there is a possibility of using already
freed memory while client reads from diag driver.
The patch adds proper protection to fix the issue.

CRs-Fixed: 2076623
Change-Id: Ic946865ac79f2684c06176be64fd2f3abc6048f7
Signed-off-by: default avatarMohit Aggarwal <maggarwa@codeaurora.org>
parent 047ccea1
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -2828,6 +2828,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)
{
@@ -2840,9 +2850,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");
@@ -2852,7 +2864,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);

@@ -2989,11 +3001,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);
@@ -3025,6 +3037,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