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

Commit 600f6a1a authored by Karthikeyan Ramasubramanian's avatar Karthikeyan Ramasubramanian Committed by Dhoat Harpal
Browse files

soc: qcom: glink: Fix channel migration logic



Channel migration logic assumes that the remote & local channel contexts
are always different and exist in different transports. If the remote
& local channel contexts exist in the same transport, then it leads to
a use-after-free scenario.

Fix the channel migration logic by not freeing the channel context if
the local & remote side opens in the same initial transport.

CRs-Fixed: 1002362
Change-Id: I319a93c49022b08e5c33b561d982a751d5223a58
Signed-off-by: default avatarKarthikeyan Ramasubramanian <kramasub@codeaurora.org>
parent 77a6b6a1
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -4339,6 +4339,9 @@ static bool ch_migrate(struct channel_ctx *l_ctx, struct channel_ctx *r_ctx)
	list_del_init(&l_ctx->port_list_node);
	spin_unlock_irqrestore(&l_ctx->transport_ptr->xprt_ctx_lock_lhb1,
									flags);
	mutex_lock(&l_ctx->transport_ptr->xprt_dbgfs_lock_lhb3);
	glink_debugfs_remove_channel(l_ctx, l_ctx->transport_ptr);
	mutex_unlock(&l_ctx->transport_ptr->xprt_dbgfs_lock_lhb3);

	memcpy(ctx_clone, l_ctx, sizeof(*ctx_clone));
	ctx_clone->local_xprt_req = 0;
@@ -4373,11 +4376,13 @@ static bool ch_migrate(struct channel_ctx *l_ctx, struct channel_ctx *r_ctx)
	l_ctx->transport_ptr = xprt;
	l_ctx->local_xprt_req = 0;
	l_ctx->local_xprt_resp = 0;
	if (new_xprt != r_ctx->transport_ptr->id || l_ctx == r_ctx) {
		if (new_xprt != r_ctx->transport_ptr->id) {
			r_ctx->local_xprt_req = 0;
			r_ctx->local_xprt_resp = 0;
			r_ctx->remote_xprt_req = 0;
			r_ctx->remote_xprt_resp = 0;
		}

		l_ctx->remote_xprt_req = 0;
		l_ctx->remote_xprt_resp = 0;
@@ -4410,6 +4415,9 @@ static bool ch_migrate(struct channel_ctx *l_ctx, struct channel_ctx *r_ctx)
		spin_unlock_irqrestore(&xprt->xprt_ctx_lock_lhb1, flags);
	}

	mutex_lock(&xprt->xprt_dbgfs_lock_lhb3);
	glink_debugfs_add_channel(l_ctx, xprt);
	mutex_unlock(&xprt->xprt_dbgfs_lock_lhb3);

	mutex_lock(&transport_list_lock_lha0);
	list_for_each_entry(xprt, &transport_list, list_node)