aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeihang Li <liweihang@huawei.com>2021-05-28 17:37:33 +0800
committerJason Gunthorpe <jgg@nvidia.com>2021-06-08 14:36:24 -0300
commitfcc57a7b2bba3374da1b7df3f65aec35dac37917 (patch)
tree6b282a359ebe9b840dff5d2ef277bc607b4ed3d7
parentRDMA/core: Use refcount_t instead of atomic_t on refcount of iwcm_id_private (diff)
downloadlinux-dev-fcc57a7b2bba3374da1b7df3f65aec35dac37917.tar.xz
linux-dev-fcc57a7b2bba3374da1b7df3f65aec35dac37917.zip
RDMA/core: Use refcount_t instead of atomic_t on refcount of iwpm_admin_data
The refcount_t API will WARN on underflow and overflow of a reference counter, and avoid use-after-free risks. Increase refcount_t from 0 to 1 is regarded as there is a risk about use-after-free. So it should be set to 1 directly during initialization. Link: https://lore.kernel.org/r/1622194663-2383-3-git-send-email-liweihang@huawei.com Signed-off-by: Weihang Li <liweihang@huawei.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
-rw-r--r--drivers/infiniband/core/iwpm_util.c12
-rw-r--r--drivers/infiniband/core/iwpm_util.h2
2 files changed, 9 insertions, 5 deletions
diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c
index f80e5550b51f..b8f40e698ba1 100644
--- a/drivers/infiniband/core/iwpm_util.c
+++ b/drivers/infiniband/core/iwpm_util.c
@@ -61,7 +61,7 @@ int iwpm_init(u8 nl_client)
{
int ret = 0;
mutex_lock(&iwpm_admin_lock);
- if (atomic_read(&iwpm_admin.refcount) == 0) {
+ if (!refcount_read(&iwpm_admin.refcount)) {
iwpm_hash_bucket = kcalloc(IWPM_MAPINFO_HASH_SIZE,
sizeof(struct hlist_head),
GFP_KERNEL);
@@ -77,8 +77,12 @@ int iwpm_init(u8 nl_client)
ret = -ENOMEM;
goto init_exit;
}
+
+ refcount_set(&iwpm_admin.refcount, 1);
+ } else {
+ refcount_inc(&iwpm_admin.refcount);
}
- atomic_inc(&iwpm_admin.refcount);
+
init_exit:
mutex_unlock(&iwpm_admin_lock);
if (!ret) {
@@ -105,12 +109,12 @@ int iwpm_exit(u8 nl_client)
if (!iwpm_valid_client(nl_client))
return -EINVAL;
mutex_lock(&iwpm_admin_lock);
- if (atomic_read(&iwpm_admin.refcount) == 0) {
+ if (!refcount_read(&iwpm_admin.refcount)) {
mutex_unlock(&iwpm_admin_lock);
pr_err("%s Incorrect usage - negative refcount\n", __func__);
return -EINVAL;
}
- if (atomic_dec_and_test(&iwpm_admin.refcount)) {
+ if (refcount_dec_and_test(&iwpm_admin.refcount)) {
free_hash_bucket();
free_reminfo_bucket();
pr_debug("%s: Resources are destroyed\n", __func__);
diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h
index eeb8e6010907..5002ac6dfbc3 100644
--- a/drivers/infiniband/core/iwpm_util.h
+++ b/drivers/infiniband/core/iwpm_util.h
@@ -90,7 +90,7 @@ struct iwpm_remote_info {
};
struct iwpm_admin_data {
- atomic_t refcount;
+ refcount_t refcount;
atomic_t nlmsg_seq;
int client_list[RDMA_NL_NUM_CLIENTS];
u32 reg_list[RDMA_NL_NUM_CLIENTS];