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

Commit 808955b1 authored by Hardik Arya's avatar Hardik Arya
Browse files

diag: Fix possible use-after-free issue for mdlog session info



Currently there is a possibility of accessing freed mdlog
session info and it's attributes after closing the session.
The patch adds protection while accessing mdlog session info
for preventing use-after-free issue.

CRs-Fixed: 2133028
Change-Id: Iba603bc2d75f84a604df2627e8fcb2a18acf4637
Signed-off-by: default avatarHardik Arya <harya@codeaurora.org>
parent 3fe4f284
Loading
Loading
Loading
Loading
+100 −42
Original line number Original line Diff line number Diff line
/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2018, 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
@@ -537,8 +537,7 @@ static void diag_send_feature_mask_update(uint8_t peripheral)
}
}


static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
				   unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				   struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
@@ -546,23 +545,30 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
	struct diag_msg_ssid_query_t rsp;
	struct diag_msg_ssid_query_t rsp;
	struct diag_ssid_range_t ssid_range;
	struct diag_ssid_range_t ssid_range;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;


	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	    !mask_info) {
	    !mask_info) {
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (!diag_apps_responds())
	if (!diag_apps_responds()) {
		mutex_unlock(&driver->md_session_lock);
		return 0;
		return 0;
	}
	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&driver->msg_mask_lock);
	rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
	rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
	rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
	rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
@@ -584,12 +590,12 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
		write_len += sizeof(ssid_range);
		write_len += sizeof(ssid_range);
	}
	}
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&driver->md_session_lock);
	return write_len;
	return write_len;
}
}


static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
				   unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				   struct diag_md_session_t *info)
{
{
	int i = 0;
	int i = 0;
	int write_len = 0;
	int write_len = 0;
@@ -642,8 +648,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
}
}


static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
				 unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				 struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
@@ -652,6 +657,10 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
	struct diag_build_mask_req_t *req = NULL;
	struct diag_build_mask_req_t *req = NULL;
	struct diag_msg_build_mask_t rsp;
	struct diag_msg_build_mask_t rsp;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);


	mask_info = (!info) ? &msg_mask : info->msg_mask;
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -659,15 +668,19 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!diag_apps_responds())
	if (!diag_apps_responds()) {
		mutex_unlock(&driver->md_session_lock);
		return 0;
		return 0;
	}


	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&driver->msg_mask_lock);
	req = (struct diag_build_mask_req_t *)src_buf;
	req = (struct diag_build_mask_req_t *)src_buf;
@@ -682,6 +695,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
		pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
			__func__, mask->ptr);
			__func__, mask->ptr);
		mutex_unlock(&driver->msg_mask_lock);
		mutex_unlock(&driver->msg_mask_lock);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -701,12 +715,12 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
	memcpy(dest_buf, &rsp, sizeof(rsp));
	memcpy(dest_buf, &rsp, sizeof(rsp));
	write_len += sizeof(rsp);
	write_len += sizeof(rsp);
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&driver->md_session_lock);
	return write_len;
	return write_len;
}
}


static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
				 unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				 struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
@@ -720,6 +734,10 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_msg_mask_t *mask_next = NULL;
	struct diag_msg_mask_t *mask_next = NULL;
	uint32_t *temp = NULL;
	uint32_t *temp = NULL;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);


	mask_info = (!info) ? &msg_mask : info->msg_mask;
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -727,11 +745,13 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -744,6 +764,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
			__func__, mask->ptr);
			__func__, mask->ptr);
		mutex_unlock(&driver->msg_mask_lock);
		mutex_unlock(&driver->msg_mask_lock);
		mutex_unlock(&mask_info->lock);
		mutex_unlock(&mask_info->lock);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -786,6 +807,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
				mutex_unlock(&mask->lock);
				mutex_unlock(&mask->lock);
				mutex_unlock(&driver->msg_mask_lock);
				mutex_unlock(&driver->msg_mask_lock);
				mutex_unlock(&mask_info->lock);
				mutex_unlock(&mask_info->lock);
				mutex_unlock(&driver->md_session_lock);
				return -ENOMEM;
				return -ENOMEM;
			}
			}
			mask->ptr = temp;
			mask->ptr = temp;
@@ -806,6 +828,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	}
	}
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA))
	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(MSG_MASKS_TYPE);
		diag_update_userspace_clients(MSG_MASKS_TYPE);


@@ -839,8 +862,7 @@ end:
}
}


static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
				     unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				     struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
@@ -849,6 +871,10 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	struct diag_msg_config_rsp_t *req = NULL;
	struct diag_msg_config_rsp_t *req = NULL;
	struct diag_msg_mask_t *mask = NULL;
	struct diag_msg_mask_t *mask = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);


	mask_info = (!info) ? &msg_mask : info->msg_mask;
	mask_info = (!info) ? &msg_mask : info->msg_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -856,11 +882,13 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -875,6 +903,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
			__func__, mask->ptr);
			__func__, mask->ptr);
		mutex_unlock(&driver->msg_mask_lock);
		mutex_unlock(&driver->msg_mask_lock);
		mutex_unlock(&mask_info->lock);
		mutex_unlock(&mask_info->lock);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
	mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
@@ -887,7 +916,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	}
	}
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&driver->msg_mask_lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&mask_info->lock);

	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA))
	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(MSG_MASKS_TYPE);
		diag_update_userspace_clients(MSG_MASKS_TYPE);


@@ -915,8 +944,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
}
}


static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len,
				   unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				   struct diag_md_session_t *info)
{
{
	int write_len = 0;
	int write_len = 0;
	uint32_t mask_size;
	uint32_t mask_size;
@@ -951,8 +979,7 @@ static int diag_cmd_get_event_mask(unsigned char *src_buf, int src_len,
}
}


static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
				      unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				      struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
@@ -961,18 +988,23 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
	struct diag_event_mask_config_t rsp;
	struct diag_event_mask_config_t rsp;
	struct diag_event_mask_config_t *req;
	struct diag_event_mask_config_t *req;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;


	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);
	mask_info = (!info) ? &event_mask : info->event_mask;
	mask_info = (!info) ? &event_mask : info->event_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	    !mask_info) {
	    !mask_info) {
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	req = (struct diag_event_mask_config_t *)src_buf;
	req = (struct diag_event_mask_config_t *)src_buf;
@@ -980,6 +1012,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
	if (mask_len <= 0 || mask_len > event_mask.mask_len) {
	if (mask_len <= 0 || mask_len > event_mask.mask_len) {
		pr_err("diag: In %s, invalid event mask len: %d\n", __func__,
		pr_err("diag: In %s, invalid event mask len: %d\n", __func__,
		       mask_len);
		       mask_len);
		mutex_unlock(&driver->md_session_lock);
		return -EIO;
		return -EIO;
	}
	}


@@ -987,6 +1020,7 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
	memcpy(mask_info->ptr, src_buf + header_len, mask_len);
	memcpy(mask_info->ptr, src_buf + header_len, mask_len);
	mask_info->status = DIAG_CTRL_MASK_VALID;
	mask_info->status = DIAG_CTRL_MASK_VALID;
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA))
	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(EVENT_MASKS_TYPE);
		diag_update_userspace_clients(EVENT_MASKS_TYPE);


@@ -1015,26 +1049,30 @@ static int diag_cmd_update_event_mask(unsigned char *src_buf, int src_len,
}
}


static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
				  unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				  struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
	uint8_t toggle = 0;
	uint8_t toggle = 0;
	struct diag_event_report_t header;
	struct diag_event_report_t header;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;


	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);
	mask_info = (!info) ? &event_mask : info->event_mask;
	mask_info = (!info) ? &event_mask : info->event_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	    !mask_info) {
	    !mask_info) {
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -1048,6 +1086,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
		memset(mask_info->ptr, 0, mask_info->mask_len);
		memset(mask_info->ptr, 0, mask_info->mask_len);
	}
	}
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA))
	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(EVENT_MASKS_TYPE);
		diag_update_userspace_clients(EVENT_MASKS_TYPE);


@@ -1071,8 +1110,7 @@ static int diag_cmd_toggle_events(unsigned char *src_buf, int src_len,
}
}


static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
				 unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				 struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int status = LOG_STATUS_INVALID;
	int status = LOG_STATUS_INVALID;
@@ -1085,6 +1123,10 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
	struct diag_log_config_req_t *req;
	struct diag_log_config_req_t *req;
	struct diag_log_config_rsp_t rsp;
	struct diag_log_config_rsp_t rsp;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);


	mask_info = (!info) ? &log_mask : info->log_mask;
	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -1092,16 +1134,20 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (!diag_apps_responds())
	if (!diag_apps_responds()) {
		mutex_unlock(&driver->md_session_lock);
		return 0;
		return 0;
	}


	req = (struct diag_log_config_req_t *)src_buf;
	req = (struct diag_log_config_req_t *)src_buf;
	read_len += req_header_len;
	read_len += req_header_len;
@@ -1121,6 +1167,7 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
	if (!log_item->ptr) {
	if (!log_item->ptr) {
		pr_err("diag: Invalid input in %s, mask: %pK\n",
		pr_err("diag: Invalid input in %s, mask: %pK\n",
			__func__, log_item);
			__func__, log_item);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
	for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
@@ -1162,28 +1209,27 @@ static int diag_cmd_get_log_mask(unsigned char *src_buf, int src_len,
	rsp.status = status;
	rsp.status = status;
	memcpy(dest_buf, &rsp, rsp_header_len);
	memcpy(dest_buf, &rsp, rsp_header_len);


	mutex_unlock(&driver->md_session_lock);
	return write_len;
	return write_len;
}
}


static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len,
static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len,
				  unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				  struct diag_md_session_t *info)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
	struct diag_log_config_rsp_t rsp;
	struct diag_log_config_rsp_t rsp;
	struct diag_mask_info *mask_info = NULL;
	struct diag_log_mask_t *mask = (struct diag_log_mask_t *)log_mask.ptr;
	struct diag_log_mask_t *mask = (struct diag_log_mask_t *)log_mask.ptr;


	if (!mask)
		return -EINVAL;

	if (!diag_apps_responds())
	if (!diag_apps_responds())
		return 0;
		return 0;


	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0) {
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d\n",
	    !mask_info) {
		       __func__, src_buf, src_len, dest_buf, dest_len);
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -1206,7 +1252,7 @@ static int diag_cmd_get_log_range(unsigned char *src_buf, int src_len,


static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
				 unsigned char *dest_buf, int dest_len,
				 unsigned char *dest_buf, int dest_len,
				 struct diag_md_session_t *info)
				 int pid)
{
{
	int i;
	int i;
	int write_len = 0;
	int write_len = 0;
@@ -1221,6 +1267,10 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	struct diag_log_mask_t *mask = NULL;
	struct diag_log_mask_t *mask = NULL;
	unsigned char *temp_buf = NULL;
	unsigned char *temp_buf = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);


	mask_info = (!info) ? &log_mask : info->log_mask;
	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -1228,11 +1278,13 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -1242,6 +1294,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
	if (!mask->ptr) {
	if (!mask->ptr) {
		pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
		pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
			__func__, mask->ptr);
			__func__, mask->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (req->equip_id >= MAX_EQUIP_ID) {
	if (req->equip_id >= MAX_EQUIP_ID) {
@@ -1304,6 +1357,7 @@ static int diag_cmd_set_log_mask(unsigned char *src_buf, int src_len,
		break;
		break;
	}
	}
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA))
	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(LOG_MASKS_TYPE);
		diag_update_userspace_clients(LOG_MASKS_TYPE);


@@ -1344,14 +1398,16 @@ end:
}
}


static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
				     unsigned char *dest_buf, int dest_len,
			unsigned char *dest_buf, int dest_len, int pid)
				     struct diag_md_session_t *info)
{
{
	struct diag_mask_info *mask_info = NULL;
	struct diag_mask_info *mask_info = NULL;
	struct diag_log_mask_t *mask = NULL;
	struct diag_log_mask_t *mask = NULL;
	struct diag_log_config_rsp_t header;
	struct diag_log_config_rsp_t header;
	int write_len = 0;
	int write_len = 0, i;
	int i;
	struct diag_md_session_t *info = NULL;

	mutex_lock(&driver->md_session_lock);
	info = diag_md_session_get_pid(pid);


	mask_info = (!info) ? &log_mask : info->log_mask;
	mask_info = (!info) ? &log_mask : info->log_mask;
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
	if (!src_buf || !dest_buf || src_len <= 0 || dest_len <= 0 ||
@@ -1359,17 +1415,20 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		pr_err("diag: Invalid input in %s, src_buf: %pK, src_len: %d, dest_buf: %pK, dest_len: %d, mask_info: %pK\n",
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       __func__, src_buf, src_len, dest_buf, dest_len,
		       mask_info);
		       mask_info);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	if (!mask_info->ptr) {
	if (!mask_info->ptr) {
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
		pr_err("diag: In %s, invalid input mask_info->ptr: %pK\n",
			__func__, mask_info->ptr);
			__func__, mask_info->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	mask = (struct diag_log_mask_t *)mask_info->ptr;
	mask = (struct diag_log_mask_t *)mask_info->ptr;
	if (!mask->ptr) {
	if (!mask->ptr) {
		pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
		pr_err("diag: Invalid input in %s, mask->ptr: %pK\n",
			__func__, mask->ptr);
			__func__, mask->ptr);
		mutex_unlock(&driver->md_session_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
	for (i = 0; i < MAX_EQUIP_ID; i++, mask++) {
@@ -1378,6 +1437,7 @@ static int diag_cmd_disable_log_mask(unsigned char *src_buf, int src_len,
		mutex_unlock(&mask->lock);
		mutex_unlock(&mask->lock);
	}
	}
	mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED;
	mask_info->status = DIAG_CTRL_MASK_ALL_DISABLED;
	mutex_unlock(&driver->md_session_lock);
	if (diag_check_update(APPS_DATA))
	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(LOG_MASKS_TYPE);
		diag_update_userspace_clients(LOG_MASKS_TYPE);


@@ -2109,14 +2169,12 @@ void diag_send_updates_peripheral(uint8_t peripheral)
				&driver->buffering_mode[peripheral]);
				&driver->buffering_mode[peripheral]);
}
}


int diag_process_apps_masks(unsigned char *buf, int len,
int diag_process_apps_masks(unsigned char *buf, int len, int pid)
			    struct diag_md_session_t *info)
{
{
	int size = 0;
	int size = 0;
	int sub_cmd = 0;
	int sub_cmd = 0;
	int (*hdlr)(unsigned char *src_buf, int src_len,
	int (*hdlr)(unsigned char *src_buf, int src_len,
		    unsigned char *dest_buf, int dest_len,
		    unsigned char *dest_buf, int dest_len, int pid) = NULL;
		    struct diag_md_session_t *info) = NULL;


	if (!buf || len <= 0)
	if (!buf || len <= 0)
		return -EINVAL;
		return -EINVAL;
@@ -2166,7 +2224,7 @@ int diag_process_apps_masks(unsigned char *buf, int len,


	if (hdlr)
	if (hdlr)
		size = hdlr(buf, len, driver->apps_rsp_buf,
		size = hdlr(buf, len, driver->apps_rsp_buf,
			    DIAG_MAX_RSP_SIZE, info);
			    DIAG_MAX_RSP_SIZE, pid);


	return (size > 0) ? size : 0;
	return (size > 0) ? size : 0;
}
}
+2 −3
Original line number Original line Diff line number Diff line
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015, 2018 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
@@ -167,8 +167,7 @@ int diag_event_mask_copy(struct diag_mask_info *dest,
void diag_log_mask_free(struct diag_mask_info *mask_info);
void diag_log_mask_free(struct diag_mask_info *mask_info);
void diag_msg_mask_free(struct diag_mask_info *mask_info);
void diag_msg_mask_free(struct diag_mask_info *mask_info);
void diag_event_mask_free(struct diag_mask_info *mask_info);
void diag_event_mask_free(struct diag_mask_info *mask_info);
int diag_process_apps_masks(unsigned char *buf, int len,
int diag_process_apps_masks(unsigned char *buf, int len, int pid);
			    struct diag_md_session_t *info);
void diag_send_updates_peripheral(uint8_t peripheral);
void diag_send_updates_peripheral(uint8_t peripheral);


extern int diag_create_msg_mask_table_entry(struct diag_msg_mask_t *msg_mask,
extern int diag_create_msg_mask_table_entry(struct diag_msg_mask_t *msg_mask,
+10 −7
Original line number Original line Diff line number Diff line
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2018, 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
@@ -131,7 +131,7 @@ void diag_md_close_all()


int diag_md_write(int id, unsigned char *buf, int len, int ctx)
int diag_md_write(int id, unsigned char *buf, int len, int ctx)
{
{
	int i;
	int i, pid = 0;
	uint8_t found = 0;
	uint8_t found = 0;
	unsigned long flags;
	unsigned long flags;
	struct diag_md_info *ch = NULL;
	struct diag_md_info *ch = NULL;
@@ -149,10 +149,14 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
	if (peripheral < 0)
	if (peripheral < 0)
		return -EINVAL;
		return -EINVAL;


	session_info =
	mutex_lock(&driver->md_session_lock);
		diag_md_session_get_peripheral(peripheral);
	session_info = diag_md_session_get_peripheral(peripheral);
	if (!session_info)
	if (!session_info) {
		mutex_unlock(&driver->md_session_lock);
		return -EIO;
		return -EIO;
	}
	pid = session_info->pid;
	mutex_unlock(&driver->md_session_lock);


	ch = &diag_md[id];
	ch = &diag_md[id];
	if (!ch)
	if (!ch)
@@ -195,8 +199,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)


	found = 0;
	found = 0;
	for (i = 0; i < driver->num_clients && !found; i++) {
	for (i = 0; i < driver->num_clients && !found; i++) {
		if ((driver->client_map[i].pid !=
		if ((driver->client_map[i].pid != pid) ||
		     session_info->pid) ||
		    (driver->client_map[i].pid == 0))
		    (driver->client_map[i].pid == 0))
			continue;
			continue;


+2 −2
Original line number Original line Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, 2018 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
@@ -221,7 +221,7 @@ static void usb_disconnect(struct diag_usb_info *ch)


	if (!atomic_read(&ch->connected) &&
	if (!atomic_read(&ch->connected) &&
		driver->usb_connected && diag_mask_param())
		driver->usb_connected && diag_mask_param())
		diag_clear_masks(NULL);
		diag_clear_masks(0);


	if (ch && ch->ops && ch->ops->close)
	if (ch && ch->ops && ch->ops->close)
		ch->ops->close(ch->ctxt, DIAG_USB_MODE);
		ch->ops->close(ch->ctxt, DIAG_USB_MODE);
+1 −1
Original line number Original line Diff line number Diff line
@@ -676,7 +676,7 @@ void diag_cmd_remove_reg_by_pid(int pid);
void diag_cmd_remove_reg_by_proc(int proc);
void diag_cmd_remove_reg_by_proc(int proc);
int diag_cmd_chk_polling(struct diag_cmd_reg_entry_t *entry);
int diag_cmd_chk_polling(struct diag_cmd_reg_entry_t *entry);
int diag_mask_param(void);
int diag_mask_param(void);
void diag_clear_masks(struct diag_md_session_t *info);
void diag_clear_masks(int pid);
uint8_t diag_mask_to_pd_value(uint32_t peripheral_mask);
uint8_t diag_mask_to_pd_value(uint32_t peripheral_mask);


void diag_record_stats(int type, int flag);
void diag_record_stats(int type, int flag);
Loading