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

Commit 5fef3cdf authored by Yao Jiang's avatar Yao Jiang Committed by Gerrit - the friendly Code Review server
Browse files

soc: qcom: hab: fix the leak risk in hab_vchan_get



When getting a vchan after receiving a message, it has probability that
this vchan is closed concurrently. So when refcount is increased by
kref_get_unless_zero, but flag vchan->otherend_closed or vchan->closed
is true at this time, it will return vchan as NULL, and the hab_vchan_put
will not be called in hab_msg_rev. So adjust the timing here can avoid the
leak risk.

Change-Id: If78c1c41bc4fd05b3288c0324bb9e0aed8493c5f
Signed-off-by: default avatarYao Jiang <yaojia@codeaurora.org>
parent 3acc958e
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header)
				get_refcnt(vchan->refcount),
				payload_type, sizebytes);
			vchan = NULL;
		} else if (vchan->otherend_closed || vchan->closed) {
			pr_err("closed already remote %d local %d vcid %x remote %x session %d refcnt %d header %x session %d type %d sz %zd\n",
				vchan->otherend_closed, vchan->closed,
				vchan->id, vchan->otherend_id,
				vchan->session_id, get_refcnt(vchan->refcount),
				vchan_id, session_id, payload_type, sizebytes);
			vchan = NULL;
		} else if (!kref_get_unless_zero(&vchan->refcount)) {
			/*
			 * this happens when refcnt is already zero
@@ -154,13 +161,6 @@ hab_vchan_get(struct physical_channel *pchan, struct hab_header *header)
				vchan->session_id, get_refcnt(vchan->refcount),
				vchan_id, session_id, payload_type, sizebytes);
			vchan = NULL;
		} else if (vchan->otherend_closed || vchan->closed) {
			pr_err("closed already remote %d local %d vcid %x remote %x session %d refcnt %d header %x session %d type %d sz %zd\n",
				vchan->otherend_closed, vchan->closed,
				vchan->id, vchan->otherend_id,
				vchan->session_id, get_refcnt(vchan->refcount),
				vchan_id, session_id, payload_type, sizebytes);
			vchan = NULL;
		}
	}
	spin_unlock_bh(&pchan->vid_lock);