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: Yao Jiang <yaojia@codeaurora.org>
This commit is contained in:
Yao Jiang 2018-09-27 15:31:11 +08:00 committed by Gerrit - the friendly Code Review server
parent 3acc958e8d
commit 5fef3cdf5a

View file

@ -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);