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

Commit 4ae8b91f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: Add proper synchronization checks to msg mask table"

parents 34bc35a0 9a44d8dd
Loading
Loading
Loading
Loading
+45 −28
Original line number Diff line number Diff line
@@ -113,10 +113,12 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
	else
		mask_info = &log_mask;

	if (!mask_info)
	if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
		return;

	mask = (struct diag_log_mask_t *)mask_info->ptr;
	if (!mask->ptr)
		return;
	buf = mask_info->update_buf;

	switch (mask_info->status) {
@@ -225,7 +227,7 @@ static void diag_send_event_mask_update(uint8_t peripheral)
	else
		mask_info = &event_mask;

	if (!mask_info)
	if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
		return;

	buf = mask_info->update_buf;
@@ -306,10 +308,14 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
	else
		mask_info = &msg_mask;

	if (!mask_info)
	if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
		return;

	mutex_lock(&driver->msg_mask_lock);
	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	if (!mask->ptr) {
		mutex_unlock(&driver->msg_mask_lock);
		return;
	}
	buf = mask_info->update_buf;
	mutex_lock(&mask_info->lock);
	switch (mask_info->status) {
@@ -382,6 +388,7 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
	}
err:
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->msg_mask_lock);
}

static void diag_send_time_sync_update(uint8_t peripheral)
@@ -495,7 +502,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,

	if (!diag_apps_responds())
		return 0;

	mutex_lock(&driver->msg_mask_lock);
	rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
	rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
	rsp.status = MSG_STATUS_SUCCESS;
@@ -503,7 +510,6 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
	rsp.count = driver->msg_mask_tbl_count;
	memcpy(dest_buf, &rsp, sizeof(rsp));
	write_len += sizeof(rsp);

	mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr;
	for (i = 0; i <  driver->msg_mask_tbl_count; i++, mask_ptr++) {
		if (write_len + sizeof(ssid_range) > dest_len) {
@@ -516,7 +522,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
		memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range));
		write_len += sizeof(ssid_range);
	}

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

@@ -540,7 +546,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,

	if (!diag_apps_responds())
		return 0;

	mutex_lock(&driver->msg_mask_lock);
	req = (struct diag_build_mask_req_t *)src_buf;
	rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
	rsp.sub_cmd = DIAG_CMD_OP_GET_BUILD_MASK;
@@ -548,9 +554,8 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
	rsp.ssid_last = req->ssid_last;
	rsp.status = MSG_STATUS_FAIL;
	rsp.padding = 0;

	build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) {
	for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
		if (build_mask->ssid_first != req->ssid_first)
			continue;
		num_entries = req->ssid_last - req->ssid_first + 1;
@@ -571,7 +576,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
	}
	memcpy(dest_buf, &rsp, sizeof(rsp));
	write_len += sizeof(rsp);

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

@@ -599,6 +604,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
	if (!diag_apps_responds())
		return 0;

	mutex_lock(&driver->msg_mask_lock);
	req = (struct diag_build_mask_req_t *)src_buf;
	rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
	rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK;
@@ -606,7 +612,6 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
	rsp.ssid_last = req->ssid_last;
	rsp.status = MSG_STATUS_FAIL;
	rsp.padding = 0;

	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
		if ((req->ssid_first < mask->ssid_first) ||
@@ -624,7 +629,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
	}
	memcpy(dest_buf, &rsp, sizeof(rsp));
	write_len += sizeof(rsp);

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

@@ -655,7 +660,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
	}

	req = (struct diag_msg_build_mask_t *)src_buf;

	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&mask_info->lock);
	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -715,7 +720,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
		break;
	}
	mutex_unlock(&mask_info->lock);

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

@@ -768,7 +773,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
	}

	req = (struct diag_msg_config_rsp_t *)src_buf;

	mutex_lock(&driver->msg_mask_lock);
	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	mutex_lock(&mask_info->lock);
	mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
@@ -780,6 +785,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
		mutex_unlock(&mask->lock);
	}
	mutex_unlock(&mask_info->lock);
	mutex_unlock(&driver->msg_mask_lock);

	if (diag_check_update(APPS_DATA))
		diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -1283,6 +1289,7 @@ static int diag_create_msg_mask_table(void)
	struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr;
	struct diag_ssid_range_t range;

	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&msg_mask.lock);
	driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1293,6 +1300,7 @@ static int diag_create_msg_mask_table(void)
			break;
	}
	mutex_unlock(&msg_mask.lock);
	mutex_unlock(&driver->msg_mask_lock);
	return err;
}

@@ -1305,9 +1313,11 @@ static int diag_create_build_time_mask(void)
	struct diag_msg_mask_t *build_mask = NULL;
	struct diag_ssid_range_t range;

	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&msg_bt_mask.lock);
	driver->bt_msg_mask_tbl_count = MSG_MASK_TBL_CNT;
	build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) {
	for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
		range.ssid_first = msg_mask_tbl[i].ssid_first;
		range.ssid_last = msg_mask_tbl[i].ssid_last;
		err = diag_create_msg_mask_table_entry(build_mask, &range);
@@ -1418,6 +1428,7 @@ static int diag_create_build_time_mask(void)
		memcpy(build_mask->ptr, tbl, tbl_size);
	}
	mutex_unlock(&msg_bt_mask.lock);
	mutex_unlock(&driver->msg_mask_lock);

	return err;
}
@@ -1565,10 +1576,11 @@ static int diag_msg_mask_init(void)
		pr_err("diag: Unable to create msg masks, err: %d\n", err);
		return err;
	}
	mutex_lock(&driver->msg_mask_lock);
	driver->msg_mask = &msg_mask;

	for (i = 0; i < NUM_PERIPHERALS; i++)
		driver->max_ssid_count[i] = 0;
	mutex_unlock(&driver->msg_mask_lock);

	return 0;
}
@@ -1587,7 +1599,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
	err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE);
	if (err)
		return err;

	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&dest->lock);
	src_mask = (struct diag_msg_mask_t *)src->ptr;
	dest_mask = (struct diag_msg_mask_t *)dest->ptr;
@@ -1606,6 +1618,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
		dest_mask++;
	}
	mutex_unlock(&dest->lock);
	mutex_unlock(&driver->msg_mask_lock);

	return err;
}
@@ -1617,7 +1630,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info)

	if (!mask_info)
		return;

	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&mask_info->lock);
	mask = (struct diag_msg_mask_t *)mask_info->ptr;
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1625,7 +1638,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info)
		mask->ptr = NULL;
	}
	mutex_unlock(&mask_info->lock);

	mutex_unlock(&driver->msg_mask_lock);
	__diag_mask_exit(mask_info);
}

@@ -1633,15 +1646,17 @@ static void diag_msg_mask_exit(void)
{
	int i;
	struct diag_msg_mask_t *mask = NULL;

	mutex_lock(&driver->msg_mask_lock);
	mask = (struct diag_msg_mask_t *)(msg_mask.ptr);
	if (mask) {
		for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++)
			kfree(mask->ptr);
		kfree(msg_mask.ptr);
		msg_mask.ptr = NULL;
	}

	kfree(msg_mask.update_buf);
	msg_mask.update_buf = NULL;
	mutex_unlock(&driver->msg_mask_lock);
}

static int diag_build_time_mask_init(void)
@@ -1666,13 +1681,15 @@ static void diag_build_time_mask_exit(void)
{
	int i;
	struct diag_msg_mask_t *mask = NULL;

	mutex_lock(&driver->msg_mask_lock);
	mask = (struct diag_msg_mask_t *)(msg_bt_mask.ptr);
	if (mask) {
		for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++)
		for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, mask++)
			kfree(mask->ptr);
		kfree(msg_mask.ptr);
		kfree(msg_bt_mask.ptr);
		msg_bt_mask.ptr = NULL;
	}
	mutex_unlock(&driver->msg_mask_lock);
}

static int diag_log_mask_init(void)
@@ -1790,7 +1807,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
		return -EIO;
	}
	mutex_unlock(&driver->diag_maskclear_mutex);

	mutex_lock(&driver->msg_mask_lock);
	mutex_lock(&mask_info->lock);
	mask = (struct diag_msg_mask_t *)(mask_info->ptr);
	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1829,7 +1846,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
		total_len += len;
	}
	mutex_unlock(&mask_info->lock);

	mutex_unlock(&driver->msg_mask_lock);
	return err ? err : total_len;
}

+2 −0
Original line number Diff line number Diff line
@@ -625,8 +625,10 @@ struct diagchar_dev {
	struct diag_mask_info *event_mask;
	struct diag_mask_info *build_time_mask;
	uint8_t msg_mask_tbl_count;
	uint8_t bt_msg_mask_tbl_count;
	uint16_t event_mask_size;
	uint16_t last_event_id;
	struct mutex msg_mask_lock;
	/* Variables for Mask Centralization */
	uint16_t num_event_id[NUM_PERIPHERALS];
	uint32_t num_equip_id[NUM_PERIPHERALS];
+1 −0
Original line number Diff line number Diff line
@@ -3467,6 +3467,7 @@ static int __init diagchar_init(void)
	mutex_init(&driver->diag_file_mutex);
	mutex_init(&driver->delayed_rsp_mutex);
	mutex_init(&apps_data_mutex);
	mutex_init(&driver->msg_mask_lock);
	for (i = 0; i < NUM_PERIPHERALS; i++)
		mutex_init(&driver->diagfwd_channel_mutex[i]);
	init_waitqueue_head(&driver->wait_q);
+7 −4
Original line number Diff line number Diff line
@@ -511,6 +511,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len,
	/* Don't account for pkt_id and length */
	read_len += header_len - (2 * sizeof(uint32_t));

	mutex_lock(&driver->msg_mask_lock);
	driver->max_ssid_count[peripheral] = header->count;
	for (i = 0; i < header->count && read_len < len; i++) {
		ssid_range = (struct diag_ssid_range_t *)ptr;
@@ -554,6 +555,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len,
		}
		driver->msg_mask_tbl_count += 1;
	}
	mutex_unlock(&driver->msg_mask_lock);
}

static void diag_build_time_mask_update(uint8_t *buf,
@@ -578,11 +580,11 @@ static void diag_build_time_mask_update(uint8_t *buf,
		       __func__, range->ssid_first, range->ssid_last);
		return;
	}

	mutex_lock(&driver->msg_mask_lock);
	build_mask = (struct diag_msg_mask_t *)(driver->build_time_mask->ptr);
	num_items = range->ssid_last - range->ssid_first + 1;

	for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) {
	for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) {
		if (build_mask->ssid_first != range->ssid_first)
			continue;
		found = 1;
@@ -601,7 +603,7 @@ static void diag_build_time_mask_update(uint8_t *buf,

	if (found)
		goto end;
	new_size = (driver->msg_mask_tbl_count + 1) *
	new_size = (driver->bt_msg_mask_tbl_count + 1) *
		   sizeof(struct diag_msg_mask_t);
	temp = krealloc(driver->build_time_mask->ptr, new_size, GFP_KERNEL);
	if (!temp) {
@@ -616,8 +618,9 @@ static void diag_build_time_mask_update(uint8_t *buf,
		       __func__, err);
		goto end;
	}
	driver->msg_mask_tbl_count += 1;
	driver->bt_msg_mask_tbl_count += 1;
end:
	mutex_unlock(&driver->msg_mask_lock);
	return;
}

+51 −8
Original line number Diff line number Diff line
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-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
@@ -462,6 +462,43 @@ static int diag_glink_write(void *ctxt, unsigned char *buf, int len)
	return err;

}

static void diag_glink_connect_work_fn(struct work_struct *work)
{
	struct diag_glink_info *glink_info = container_of(work,
							struct diag_glink_info,
							connect_work);
	if (!glink_info || !glink_info->hdl)
		return;
	atomic_set(&glink_info->opened, 1);
	diagfwd_channel_open(glink_info->fwd_ctxt);
	diagfwd_late_open(glink_info->fwd_ctxt);
}

static void diag_glink_remote_disconnect_work_fn(struct work_struct *work)
{
	struct diag_glink_info *glink_info = container_of(work,
							struct diag_glink_info,
							remote_disconnect_work);
	if (!glink_info || !glink_info->hdl)
		return;
	atomic_set(&glink_info->opened, 0);
	diagfwd_channel_close(glink_info->fwd_ctxt);
	atomic_set(&glink_info->tx_intent_ready, 0);
}

static void diag_glink_late_init_work_fn(struct work_struct *work)
{
	struct diag_glink_info *glink_info = container_of(work,
							struct diag_glink_info,
							late_init_work);
	if (!glink_info || !glink_info->hdl)
		return;
	DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "p: %d t: %d\n",
			glink_info->peripheral, glink_info->type);
	diagfwd_channel_open(glink_info->fwd_ctxt);
}

static void diag_glink_transport_notify_state(void *handle, const void *priv,
						unsigned int event)
{
@@ -475,9 +512,7 @@ static void diag_glink_transport_notify_state(void *handle, const void *priv,
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"%s received channel connect for periph:%d\n",
			 glink_info->name, glink_info->peripheral);
		atomic_set(&glink_info->opened, 1);
		diagfwd_channel_open(glink_info->fwd_ctxt);
		diagfwd_late_open(glink_info->fwd_ctxt);
		queue_work(glink_info->wq, &glink_info->connect_work);
		break;
	case GLINK_LOCAL_DISCONNECTED:
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
@@ -489,9 +524,7 @@ static void diag_glink_transport_notify_state(void *handle, const void *priv,
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"%s received channel remote disconnect for periph:%d\n",
			 glink_info->name, glink_info->peripheral);
		atomic_set(&glink_info->opened, 0);
		diagfwd_channel_close(glink_info->fwd_ctxt);
		atomic_set(&glink_info->tx_intent_ready, 0);
		queue_work(glink_info->wq, &glink_info->remote_disconnect_work);
		break;
	default:
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
@@ -596,7 +629,7 @@ static void glink_late_init(struct diag_glink_info *glink_info)
	glink_info->inited = 1;

	if (atomic_read(&glink_info->opened))
		diagfwd_channel_open(glink_info->fwd_ctxt);
		queue_work(glink_info->wq, &(glink_info->late_init_work));

	DIAG_LOG(DIAG_DEBUG_PERIPHERALS, "%s exiting\n",
		 glink_info->name);
@@ -641,6 +674,10 @@ static void __diag_glink_init(struct diag_glink_info *glink_info)
	INIT_WORK(&(glink_info->open_work), diag_glink_open_work_fn);
	INIT_WORK(&(glink_info->close_work), diag_glink_close_work_fn);
	INIT_WORK(&(glink_info->read_work), diag_glink_read_work_fn);
	INIT_WORK(&(glink_info->connect_work), diag_glink_connect_work_fn);
	INIT_WORK(&(glink_info->remote_disconnect_work),
		diag_glink_remote_disconnect_work_fn);
	INIT_WORK(&(glink_info->late_init_work), diag_glink_late_init_work_fn);
	link_info.glink_link_state_notif_cb = diag_glink_notify_cb;
	link_info.transport = NULL;
	link_info.edge = glink_info->edge;
@@ -681,6 +718,8 @@ int diag_glink_init(void)
	struct diag_glink_info *glink_info = NULL;

	for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
		if (peripheral != PERIPHERAL_WDSP)
			continue;
		glink_info = &glink_cntl[peripheral];
		__diag_glink_init(glink_info);
		diagfwd_cntl_register(TRANSPORT_GLINK, glink_info->peripheral,
@@ -719,6 +758,8 @@ void diag_glink_early_exit(void)
	int peripheral = 0;

	for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
		if (peripheral != PERIPHERAL_WDSP)
			continue;
		__diag_glink_exit(&glink_cntl[peripheral]);
		glink_unregister_link_state_cb(&glink_cntl[peripheral].hdl);
	}
@@ -729,6 +770,8 @@ void diag_glink_exit(void)
	int peripheral = 0;

	for (peripheral = 0; peripheral < NUM_PERIPHERALS; peripheral++) {
		if (peripheral != PERIPHERAL_WDSP)
			continue;
		__diag_glink_exit(&glink_data[peripheral]);
		__diag_glink_exit(&glink_cmd[peripheral]);
		__diag_glink_exit(&glink_dci[peripheral]);
Loading