diff options
author | Yao Jiang <yaojia@codeaurora.org> | 2018-09-27 15:31:11 +0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-10-07 18:34:52 -0700 |
commit | 5fef3cdf5adcd68c76430356e3abc7b092b6a5ba (patch) | |
tree | bdad8eafc323819a0e84cf4583674da6be208de3 /drivers | |
parent | 3acc958e8df36b84ee25c950b1f7e39931a6e0bc (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/soc/qcom/hab/hab_vchan.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/soc/qcom/hab/hab_vchan.c b/drivers/soc/qcom/hab/hab_vchan.c index e42b27f5048d..d572e4c8a34b 100644 --- a/drivers/soc/qcom/hab/hab_vchan.c +++ b/drivers/soc/qcom/hab/hab_vchan.c @@ -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); |