summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorYao Jiang <yaojia@codeaurora.org>2018-09-27 15:31:11 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-10-07 18:34:52 -0700
commit5fef3cdf5adcd68c76430356e3abc7b092b6a5ba (patch)
treebdad8eafc323819a0e84cf4583674da6be208de3 /drivers
parent3acc958e8df36b84ee25c950b1f7e39931a6e0bc (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.c14
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);