Commit fcc57a7b authored by Weihang Li's avatar Weihang Li Committed by Jason Gunthorpe

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.comSigned-off-by: default avatarWeihang Li <liweihang@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 60dff56d
...@@ -61,7 +61,7 @@ int iwpm_init(u8 nl_client) ...@@ -61,7 +61,7 @@ int iwpm_init(u8 nl_client)
{ {
int ret = 0; int ret = 0;
mutex_lock(&iwpm_admin_lock); 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, iwpm_hash_bucket = kcalloc(IWPM_MAPINFO_HASH_SIZE,
sizeof(struct hlist_head), sizeof(struct hlist_head),
GFP_KERNEL); GFP_KERNEL);
...@@ -77,8 +77,12 @@ int iwpm_init(u8 nl_client) ...@@ -77,8 +77,12 @@ int iwpm_init(u8 nl_client)
ret = -ENOMEM; ret = -ENOMEM;
goto init_exit; goto init_exit;
} }
refcount_set(&iwpm_admin.refcount, 1);
} else {
refcount_inc(&iwpm_admin.refcount);
} }
atomic_inc(&iwpm_admin.refcount);
init_exit: init_exit:
mutex_unlock(&iwpm_admin_lock); mutex_unlock(&iwpm_admin_lock);
if (!ret) { if (!ret) {
...@@ -105,12 +109,12 @@ int iwpm_exit(u8 nl_client) ...@@ -105,12 +109,12 @@ int iwpm_exit(u8 nl_client)
if (!iwpm_valid_client(nl_client)) if (!iwpm_valid_client(nl_client))
return -EINVAL; return -EINVAL;
mutex_lock(&iwpm_admin_lock); mutex_lock(&iwpm_admin_lock);
if (atomic_read(&iwpm_admin.refcount) == 0) { if (!refcount_read(&iwpm_admin.refcount)) {
mutex_unlock(&iwpm_admin_lock); mutex_unlock(&iwpm_admin_lock);
pr_err("%s Incorrect usage - negative refcount\n", __func__); pr_err("%s Incorrect usage - negative refcount\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (atomic_dec_and_test(&iwpm_admin.refcount)) { if (refcount_dec_and_test(&iwpm_admin.refcount)) {
free_hash_bucket(); free_hash_bucket();
free_reminfo_bucket(); free_reminfo_bucket();
pr_debug("%s: Resources are destroyed\n", __func__); pr_debug("%s: Resources are destroyed\n", __func__);
......
...@@ -90,7 +90,7 @@ struct iwpm_remote_info { ...@@ -90,7 +90,7 @@ struct iwpm_remote_info {
}; };
struct iwpm_admin_data { struct iwpm_admin_data {
atomic_t refcount; refcount_t refcount;
atomic_t nlmsg_seq; atomic_t nlmsg_seq;
int client_list[RDMA_NL_NUM_CLIENTS]; int client_list[RDMA_NL_NUM_CLIENTS];
u32 reg_list[RDMA_NL_NUM_CLIENTS]; u32 reg_list[RDMA_NL_NUM_CLIENTS];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment