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

Commit dd179028 authored by Katish Paran's avatar Katish Paran Committed by Gerrit - the friendly Code Review server
Browse files

diag: dci: Mutex protect the client details



While updating the global mask details, the client entry is not
mutex protected. It may happen in some cases that stale entries
might be accessed. This patch ensures that updation of global
mask details happens under mutex protection.

Change-Id: I614872c2bd73ffd53368490a52a54dad13b08e70
Signed-off-by: default avatarKatish Paran <kparan@codeaurora.org>
parent bbfb0c59
Loading
Loading
Loading
Loading
+22 −2
Original line number Original line Diff line number Diff line
@@ -730,7 +730,6 @@ static struct dci_pkt_req_entry_t *diag_register_dci_transaction(int uid,
	if (!entry)
	if (!entry)
		return NULL;
		return NULL;


	mutex_lock(&driver->dci_mutex);
	driver->dci_tag++;
	driver->dci_tag++;
	entry->client_id = client_id;
	entry->client_id = client_id;
	entry->uid = uid;
	entry->uid = uid;
@@ -738,7 +737,6 @@ static struct dci_pkt_req_entry_t *diag_register_dci_transaction(int uid,
	pr_debug("diag: Registering DCI cmd req, client_id: %d, uid: %d, tag:%d\n",
	pr_debug("diag: Registering DCI cmd req, client_id: %d, uid: %d, tag:%d\n",
				entry->client_id, entry->uid, entry->tag);
				entry->client_id, entry->uid, entry->tag);
	list_add_tail(&entry->track, &driver->dci_req_list);
	list_add_tail(&entry->track, &driver->dci_req_list);
	mutex_unlock(&driver->dci_mutex);


	return entry;
	return entry;
}
}
@@ -1781,10 +1779,12 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
		return -EIO;
		return -EIO;
	}
	}


	mutex_lock(&driver->dci_mutex);
	dci_entry = diag_dci_get_client_entry(req_hdr.client_id);
	dci_entry = diag_dci_get_client_entry(req_hdr.client_id);
	if (!dci_entry) {
	if (!dci_entry) {
		pr_err("diag: Invalid client %d in %s\n",
		pr_err("diag: Invalid client %d in %s\n",
		       req_hdr.client_id, __func__);
		       req_hdr.client_id, __func__);
		mutex_unlock(&driver->dci_mutex);
		return DIAG_DCI_NO_REG;
		return DIAG_DCI_NO_REG;
	}
	}


@@ -1793,6 +1793,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
		pr_debug("diag: command not supported %d %d %d",
		pr_debug("diag: command not supported %d %d %d",
			 header->cmd_code, header->subsys_id,
			 header->cmd_code, header->subsys_id,
			 header->subsys_cmd_code);
			 header->subsys_cmd_code);
		mutex_unlock(&driver->dci_mutex);
		return DIAG_DCI_SEND_DATA_FAIL;
		return DIAG_DCI_SEND_DATA_FAIL;
	}
	}


@@ -1800,6 +1801,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
	if (common_cmd < 0) {
	if (common_cmd < 0) {
		pr_debug("diag: error in checking common command, %d\n",
		pr_debug("diag: error in checking common command, %d\n",
			 common_cmd);
			 common_cmd);
		mutex_unlock(&driver->dci_mutex);
		return DIAG_DCI_SEND_DATA_FAIL;
		return DIAG_DCI_SEND_DATA_FAIL;
	}
	}


@@ -1818,6 +1820,7 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
	if (driver->in_busy_dcipktdata) {
	if (driver->in_busy_dcipktdata) {
		pr_err("diag: In %s, apps dci buffer is still busy. Dropping packet\n",
		pr_err("diag: In %s, apps dci buffer is still busy. Dropping packet\n",
								__func__);
								__func__);
		mutex_unlock(&driver->dci_mutex);
		return -EAGAIN;
		return -EAGAIN;
	}
	}


@@ -1826,8 +1829,10 @@ static int diag_process_dci_pkt_rsp(unsigned char *buf, int len)
						  req_hdr.client_id);
						  req_hdr.client_id);
	if (!req_entry) {
	if (!req_entry) {
		pr_alert("diag: registering new DCI transaction failed\n");
		pr_alert("diag: registering new DCI transaction failed\n");
		mutex_unlock(&driver->dci_mutex);
		return DIAG_DCI_NO_REG;
		return DIAG_DCI_NO_REG;
	}
	}
	mutex_unlock(&driver->dci_mutex);


	/*
	/*
	 * If the client has registered for remote data, route the packet to the
	 * If the client has registered for remote data, route the packet to the
@@ -1904,9 +1909,11 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
		read_len += sizeof(int);
		read_len += sizeof(int);


		/* find client table entry */
		/* find client table entry */
		mutex_lock(&driver->dci_mutex);
		dci_entry = diag_dci_get_client_entry(client_id);
		dci_entry = diag_dci_get_client_entry(client_id);
		if (!dci_entry) {
		if (!dci_entry) {
			pr_err("diag: In %s, invalid client\n", __func__);
			pr_err("diag: In %s, invalid client\n", __func__);
			mutex_unlock(&driver->dci_mutex);
			return ret;
			return ret;
		}
		}
		client_token = dci_entry->client_info.token;
		client_token = dci_entry->client_info.token;
@@ -1914,6 +1921,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
		if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
		if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
			pr_err("diag: dci: Invalid number of log codes %d\n",
			pr_err("diag: dci: Invalid number of log codes %d\n",
								num_codes);
								num_codes);
			mutex_unlock(&driver->dci_mutex);
			return -EIO;
			return -EIO;
		}
		}


@@ -1921,6 +1929,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
		if (!head_log_mask_ptr) {
		if (!head_log_mask_ptr) {
			pr_err("diag: dci: Invalid Log mask pointer in %s\n",
			pr_err("diag: dci: Invalid Log mask pointer in %s\n",
								__func__);
								__func__);
			mutex_unlock(&driver->dci_mutex);
			return -ENOMEM;
			return -ENOMEM;
		}
		}
		pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
		pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
@@ -1930,6 +1939,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
			if (read_len >= USER_SPACE_DATA) {
			if (read_len >= USER_SPACE_DATA) {
				pr_err("diag: dci: Invalid length for log type in %s",
				pr_err("diag: dci: Invalid length for log type in %s",
								__func__);
								__func__);
				mutex_unlock(&driver->dci_mutex);
				return -EIO;
				return -EIO;
			}
			}
			log_code = *(uint16_t *)temp;
			log_code = *(uint16_t *)temp;
@@ -1938,6 +1948,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
			byte_index = item_num/8 + 2;
			byte_index = item_num/8 + 2;
			if (byte_index >= (DCI_MAX_ITEMS_PER_LOG_CODE+2)) {
			if (byte_index >= (DCI_MAX_ITEMS_PER_LOG_CODE+2)) {
				pr_err("diag: dci: Log type, invalid byte index\n");
				pr_err("diag: dci: Log type, invalid byte index\n");
				mutex_unlock(&driver->dci_mutex);
				return ret;
				return ret;
			}
			}
			byte_mask = 0x01 << (item_num % 8);
			byte_mask = 0x01 << (item_num % 8);
@@ -1963,6 +1974,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
			}
			}
			if (!found) {
			if (!found) {
				pr_err("diag: dci equip id not found\n");
				pr_err("diag: dci equip id not found\n");
				mutex_unlock(&driver->dci_mutex);
				return ret;
				return ret;
			}
			}
			*(log_mask_ptr+1) = 1; /* set the dirty byte */
			*(log_mask_ptr+1) = 1; /* set the dirty byte */
@@ -1985,6 +1997,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
			diag_update_userspace_clients(DCI_LOG_MASKS_TYPE);
			diag_update_userspace_clients(DCI_LOG_MASKS_TYPE);
		/* send updated mask to peripherals */
		/* send updated mask to peripherals */
		ret = dci_ops_tbl[client_token].send_log_mask(client_token);
		ret = dci_ops_tbl[client_token].send_log_mask(client_token);
		mutex_unlock(&driver->dci_mutex);
	} else if (*(int *)temp == DCI_EVENT_TYPE) {
	} else if (*(int *)temp == DCI_EVENT_TYPE) {
		/* Minimum length of a event mask config is 12 + 4 bytes for
		/* Minimum length of a event mask config is 12 + 4 bytes for
		  atleast one event id to be set or reset. */
		  atleast one event id to be set or reset. */
@@ -2007,9 +2020,11 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
		read_len += sizeof(int);
		read_len += sizeof(int);


		/* find client table entry */
		/* find client table entry */
		mutex_lock(&driver->dci_mutex);
		dci_entry = diag_dci_get_client_entry(client_id);
		dci_entry = diag_dci_get_client_entry(client_id);
		if (!dci_entry) {
		if (!dci_entry) {
			pr_err("diag: In %s, invalid client\n", __func__);
			pr_err("diag: In %s, invalid client\n", __func__);
			mutex_unlock(&driver->dci_mutex);
			return ret;
			return ret;
		}
		}
		client_token = dci_entry->client_info.token;
		client_token = dci_entry->client_info.token;
@@ -2020,6 +2035,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
		if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
		if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
			pr_err("diag: dci: Invalid number of event ids %d\n",
			pr_err("diag: dci: Invalid number of event ids %d\n",
								num_codes);
								num_codes);
			mutex_unlock(&driver->dci_mutex);
			return -EIO;
			return -EIO;
		}
		}


@@ -2027,6 +2043,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
		if (!event_mask_ptr) {
		if (!event_mask_ptr) {
			pr_err("diag: dci: Invalid event mask pointer in %s\n",
			pr_err("diag: dci: Invalid event mask pointer in %s\n",
								__func__);
								__func__);
			mutex_unlock(&driver->dci_mutex);
			return -ENOMEM;
			return -ENOMEM;
		}
		}
		pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
		pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
@@ -2035,12 +2052,14 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
			if (read_len >= USER_SPACE_DATA) {
			if (read_len >= USER_SPACE_DATA) {
				pr_err("diag: dci: Invalid length for event type in %s",
				pr_err("diag: dci: Invalid length for event type in %s",
								__func__);
								__func__);
				mutex_unlock(&driver->dci_mutex);
				return -EIO;
				return -EIO;
			}
			}
			event_id = *(int *)temp;
			event_id = *(int *)temp;
			byte_index = event_id/8;
			byte_index = event_id/8;
			if (byte_index >= DCI_EVENT_MASK_SIZE) {
			if (byte_index >= DCI_EVENT_MASK_SIZE) {
				pr_err("diag: dci: Event type, invalid byte index\n");
				pr_err("diag: dci: Event type, invalid byte index\n");
				mutex_unlock(&driver->dci_mutex);
				return ret;
				return ret;
			}
			}
			bit_index = event_id % 8;
			bit_index = event_id % 8;
@@ -2066,6 +2085,7 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
			diag_update_userspace_clients(DCI_EVENT_MASKS_TYPE);
			diag_update_userspace_clients(DCI_EVENT_MASKS_TYPE);
		/* send updated mask to peripherals */
		/* send updated mask to peripherals */
		ret = dci_ops_tbl[client_token].send_event_mask(client_token);
		ret = dci_ops_tbl[client_token].send_event_mask(client_token);
		mutex_unlock(&driver->dci_mutex);
	} else {
	} else {
		pr_alert("diag: Incorrect DCI transaction\n");
		pr_alert("diag: Incorrect DCI transaction\n");
	}
	}