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

Commit 30e89851 authored by Mohit Aggarwal's avatar Mohit Aggarwal Committed by David Keitel
Browse files

diag: dci: Add protection while de-initializing clients



Currently, while de-initializing dci clients, there is
a possibility to access stale entries. This patch fixes
this issue by adding proper protection mechanism.

CRs-Fixed: 960958 968445
Change-Id: I829c9497eeb356662a6531592c66108e615ce6e4
Signed-off-by: default avatarMohit Aggarwal <maggarwa@codeaurora.org>
parent 91212fa8
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -2816,13 +2816,14 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
	if (!entry)
	if (!entry)
		return DIAG_DCI_NOT_SUPPORTED;
		return DIAG_DCI_NOT_SUPPORTED;


	token = entry->client_info.token;

	mutex_lock(&driver->dci_mutex);
	mutex_lock(&driver->dci_mutex);

	token = entry->client_info.token;
	/*
	/*
	 * Remove the entry from the list before freeing the buffers
	 * Remove the entry from the list before freeing the buffers
	 * to ensure that we don't have any invalid access.
	 * to ensure that we don't have any invalid access.
	 */
	 */
	if (!list_empty(&entry->track))
		list_del(&entry->track);
		list_del(&entry->track);
	driver->num_dci_client--;
	driver->num_dci_client--;
	/*
	/*
@@ -2852,6 +2853,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
		req_entry = list_entry(start, struct dci_pkt_req_entry_t,
		req_entry = list_entry(start, struct dci_pkt_req_entry_t,
				       track);
				       track);
		if (req_entry->client_id == entry->client_info.client_id) {
		if (req_entry->client_id == entry->client_info.client_id) {
			if (!list_empty(&req_entry->track))
				list_del(&req_entry->track);
				list_del(&req_entry->track);
			kfree(req_entry);
			kfree(req_entry);
		}
		}
@@ -2861,6 +2863,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
	mutex_lock(&entry->write_buf_mutex);
	mutex_lock(&entry->write_buf_mutex);
	list_for_each_entry_safe(buf_entry, temp, &entry->list_write_buf,
	list_for_each_entry_safe(buf_entry, temp, &entry->list_write_buf,
							buf_track) {
							buf_track) {
		if (!list_empty(&buf_entry->buf_track))
			list_del(&buf_entry->buf_track);
			list_del(&buf_entry->buf_track);
		if (buf_entry->buf_type == DCI_BUF_SECONDARY) {
		if (buf_entry->buf_type == DCI_BUF_SECONDARY) {
			mutex_lock(&buf_entry->data_mutex);
			mutex_lock(&buf_entry->data_mutex);
+17 −5
Original line number Original line Diff line number Diff line
/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License version 2 and
@@ -1968,12 +1968,18 @@ long diagchar_compat_ioctl(struct file *filp,
		result = diag_ioctl_dci_reg(ioarg);
		result = diag_ioctl_dci_reg(ioarg);
		break;
		break;
	case DIAG_IOCTL_DCI_DEINIT:
	case DIAG_IOCTL_DCI_DEINIT:
		mutex_lock(&driver->dci_mutex);
		if (copy_from_user((void *)&client_id, (void __user *)ioarg,
		if (copy_from_user((void *)&client_id, (void __user *)ioarg,
			sizeof(int)))
			sizeof(int))) {
			mutex_unlock(&driver->dci_mutex);
			return -EFAULT;
			return -EFAULT;
		}
		dci_client = diag_dci_get_client_entry(client_id);
		dci_client = diag_dci_get_client_entry(client_id);
		if (!dci_client)
		if (!dci_client) {
			mutex_unlock(&driver->dci_mutex);
			return DIAG_DCI_NOT_SUPPORTED;
			return DIAG_DCI_NOT_SUPPORTED;
		}
		mutex_unlock(&driver->dci_mutex);
		result = diag_dci_deinit_client(dci_client);
		result = diag_dci_deinit_client(dci_client);
		break;
		break;
	case DIAG_IOCTL_DCI_SUPPORT:
	case DIAG_IOCTL_DCI_SUPPORT:
@@ -2071,12 +2077,18 @@ long diagchar_ioctl(struct file *filp,
		result = diag_ioctl_dci_reg(ioarg);
		result = diag_ioctl_dci_reg(ioarg);
		break;
		break;
	case DIAG_IOCTL_DCI_DEINIT:
	case DIAG_IOCTL_DCI_DEINIT:
		mutex_lock(&driver->dci_mutex);
		if (copy_from_user((void *)&client_id, (void __user *)ioarg,
		if (copy_from_user((void *)&client_id, (void __user *)ioarg,
			sizeof(int)))
			sizeof(int))) {
			mutex_unlock(&driver->dci_mutex);
			return -EFAULT;
			return -EFAULT;
		}
		dci_client = diag_dci_get_client_entry(client_id);
		dci_client = diag_dci_get_client_entry(client_id);
		if (!dci_client)
		if (!dci_client) {
			mutex_unlock(&driver->dci_mutex);
			return DIAG_DCI_NOT_SUPPORTED;
			return DIAG_DCI_NOT_SUPPORTED;
		}
		mutex_unlock(&driver->dci_mutex);
		result = diag_dci_deinit_client(dci_client);
		result = diag_dci_deinit_client(dci_client);
		break;
		break;
	case DIAG_IOCTL_DCI_SUPPORT:
	case DIAG_IOCTL_DCI_SUPPORT: