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

Commit 979b784f authored by Utkarsh Saxena's avatar Utkarsh Saxena Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Add mutext protection when updating notify req cache



IOCTL interface to send QMI NOTIFY REQ messages can be called
from multiple contexts which can result into buffer overflow of
msg cache. Make a change to add mutext protection to prevent
buffer overflow.

Change-Id: Ib6d879e29971ae40398a9dc8759fb4dbbf166429
Acked-by: default avatarChaitanya Pratapa <cpratapa@qti.qualcomm.com>
Signed-off-by: default avatarUtkarsh Saxena <usaxena@codeaurora.org>
parent 68b6c46c
Loading
Loading
Loading
Loading
+46 −19
Original line number Original line Diff line number Diff line
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, 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
@@ -52,6 +52,8 @@ struct ipa3_qmi_context *ipa3_qmi_ctx;
static bool workqueues_stopped;
static bool workqueues_stopped;
static bool ipa3_modem_init_cmplt;
static bool ipa3_modem_init_cmplt;
static bool first_time_handshake;
static bool first_time_handshake;
struct mutex ipa3_qmi_lock;

/* QMI A5 service */
/* QMI A5 service */


static struct msg_desc ipa3_indication_reg_req_desc = {
static struct msg_desc ipa3_indication_reg_req_desc = {
@@ -607,12 +609,17 @@ int ipa3_qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req)
		req->filter_spec_ex_list_len);
		req->filter_spec_ex_list_len);
	}
	}


	mutex_lock(&ipa3_qmi_lock);
	if (ipa3_qmi_ctx != NULL) {
		/* cache the qmi_filter_request */
		/* cache the qmi_filter_request */
		memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
		memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[
			ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
			ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg]),
			req, sizeof(struct ipa_install_fltr_rule_req_msg_v01));
			req,
			sizeof(struct ipa_install_fltr_rule_req_msg_v01));
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg++;
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10;
	}
	mutex_unlock(&ipa3_qmi_lock);


	req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01;
	req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01;
	req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01;
	req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01;
@@ -650,12 +657,17 @@ int ipa3_qmi_filter_request_ex_send(
		req->filter_spec_ex_list_len);
		req->filter_spec_ex_list_len);
	}
	}


	mutex_lock(&ipa3_qmi_lock);
	if (ipa3_qmi_ctx != NULL) {
		/* cache the qmi_filter_request */
		/* cache the qmi_filter_request */
		memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_ex_msg_cache[
		memcpy(&(ipa3_qmi_ctx->ipa_install_fltr_rule_req_ex_msg_cache[
			ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg]),
			ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg]),
		req, sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01));
			req,
			sizeof(struct ipa_install_fltr_rule_req_ex_msg_v01));
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg++;
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg++;
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg %= 10;
		ipa3_qmi_ctx->num_ipa_install_fltr_rule_req_ex_msg %= 10;
	}
	mutex_unlock(&ipa3_qmi_lock);


	req_desc.max_msg_len =
	req_desc.max_msg_len =
		QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_MAX_MSG_LEN_V01;
		QMI_IPA_INSTALL_FILTER_RULE_EX_REQ_MAX_MSG_LEN_V01;
@@ -786,12 +798,17 @@ int ipa3_qmi_filter_notify_send(
		return -EINVAL;
		return -EINVAL;
	}
	}


	mutex_lock(&ipa3_qmi_lock);
	if (ipa3_qmi_ctx != NULL) {
		/* cache the qmi_filter_request */
		/* cache the qmi_filter_request */
		memcpy(&(ipa3_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
		memcpy(&(ipa3_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[
			ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
			ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]),
		req, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
			req,
			sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
		ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
		ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++;
		ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
		ipa3_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10;
	}
	mutex_unlock(&ipa3_qmi_lock);


	req_desc.max_msg_len =
	req_desc.max_msg_len =
	QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01;
	QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01;
@@ -1320,3 +1337,13 @@ int ipa3_qmi_stop_data_qouta(void)
		resp.resp.error, "ipa_stop_data_usage_quota_req_msg_v01");
		resp.resp.error, "ipa_stop_data_usage_quota_req_msg_v01");
}
}


void ipa3_qmi_init(void)
{
	mutex_init(&ipa3_qmi_lock);
}

void ipa3_qmi_cleanup(void)
{
	mutex_destroy(&ipa3_qmi_lock);
}
+13 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, 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
@@ -201,6 +201,10 @@ int ipa3_qmi_stop_data_qouta(void);


void ipa3_q6_handshake_complete(bool ssr_bootup);
void ipa3_q6_handshake_complete(bool ssr_bootup);


void ipa3_qmi_init(void);

void ipa3_qmi_cleanup(void);

#else /* CONFIG_RMNET_IPA3 */
#else /* CONFIG_RMNET_IPA3 */


static inline int ipa3_qmi_service_init(uint32_t wan_platform_type)
static inline int ipa3_qmi_service_init(uint32_t wan_platform_type)
@@ -312,6 +316,14 @@ static inline int ipa3_qmi_stop_data_qouta(void)


static inline void ipa3_q6_handshake_complete(bool ssr_bootup) { }
static inline void ipa3_q6_handshake_complete(bool ssr_bootup) { }


static inline void ipa3_qmi_init(void)
{
}

static inline void ipa3_qmi_cleanup(void)
{
}

#endif /* CONFIG_RMNET_IPA3 */
#endif /* CONFIG_RMNET_IPA3 */


#endif /* IPA_QMI_SERVICE_H */
#endif /* IPA_QMI_SERVICE_H */
+4 −0
Original line number Original line Diff line number Diff line
@@ -2952,6 +2952,9 @@ static int __init ipa3_wwan_init(void)
	mutex_init(&rmnet_ipa3_ctx->pipe_handle_guard);
	mutex_init(&rmnet_ipa3_ctx->pipe_handle_guard);
	rmnet_ipa3_ctx->ipa3_to_apps_hdl = -1;
	rmnet_ipa3_ctx->ipa3_to_apps_hdl = -1;
	rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;
	rmnet_ipa3_ctx->apps_to_ipa3_hdl = -1;

	ipa3_qmi_init();

	/* Register for Modem SSR */
	/* Register for Modem SSR */
	rmnet_ipa3_ctx->subsys_notify_handle = subsys_notif_register_notifier(
	rmnet_ipa3_ctx->subsys_notify_handle = subsys_notif_register_notifier(
			SUBSYS_MODEM,
			SUBSYS_MODEM,
@@ -2965,6 +2968,7 @@ static int __init ipa3_wwan_init(void)
static void __exit ipa3_wwan_cleanup(void)
static void __exit ipa3_wwan_cleanup(void)
{
{
	int ret;
	int ret;
	ipa3_qmi_cleanup();
	mutex_destroy(&rmnet_ipa3_ctx->pipe_handle_guard);
	mutex_destroy(&rmnet_ipa3_ctx->pipe_handle_guard);
	ret = subsys_notif_unregister_notifier(
	ret = subsys_notif_unregister_notifier(
		rmnet_ipa3_ctx->subsys_notify_handle, &ipa3_ssr_notifier);
		rmnet_ipa3_ctx->subsys_notify_handle, &ipa3_ssr_notifier);