RDMA/hfi1: Convert from atomic_t to refcount_t on hfi1_devdata->user_refcount
refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations. Link: https://lore.kernel.org/r/1626674454-56075-1-git-send-email-xiyuyang19@fudan.edu.cn Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn> Signed-off-by: Xin Tan <tanxin.ctf@gmail.com> Tested-by: Josh Fisher <josh.fisher@cornelisnetworks.com> Acked-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Родитель
62004871e1
Коммит
a0293eb249
|
@ -15336,7 +15336,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd)
|
||||||
init_completion(&dd->user_comp);
|
init_completion(&dd->user_comp);
|
||||||
|
|
||||||
/* The user refcount starts with one to inidicate an active device */
|
/* The user refcount starts with one to inidicate an active device */
|
||||||
atomic_set(&dd->user_refcount, 1);
|
refcount_set(&dd->user_refcount, 1);
|
||||||
|
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
|
||||||
if (!((dd->flags & HFI1_PRESENT) && dd->kregbase1))
|
if (!((dd->flags & HFI1_PRESENT) && dd->kregbase1))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!atomic_inc_not_zero(&dd->user_refcount))
|
if (!refcount_inc_not_zero(&dd->user_refcount))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
/* The real work is performed later in assign_ctxt() */
|
/* The real work is performed later in assign_ctxt() */
|
||||||
|
@ -213,7 +213,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
|
||||||
nomem:
|
nomem:
|
||||||
kfree(fd);
|
kfree(fd);
|
||||||
fp->private_data = NULL;
|
fp->private_data = NULL;
|
||||||
if (atomic_dec_and_test(&dd->user_refcount))
|
if (refcount_dec_and_test(&dd->user_refcount))
|
||||||
complete(&dd->user_comp);
|
complete(&dd->user_comp);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -711,7 +711,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp)
|
||||||
deallocate_ctxt(uctxt);
|
deallocate_ctxt(uctxt);
|
||||||
done:
|
done:
|
||||||
|
|
||||||
if (atomic_dec_and_test(&dd->user_refcount))
|
if (refcount_dec_and_test(&dd->user_refcount))
|
||||||
complete(&dd->user_comp);
|
complete(&dd->user_comp);
|
||||||
|
|
||||||
cleanup_srcu_struct(&fdata->pq_srcu);
|
cleanup_srcu_struct(&fdata->pq_srcu);
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/refcount.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
|
@ -1384,7 +1385,7 @@ struct hfi1_devdata {
|
||||||
/* Number of verbs contexts which have disabled ASPM */
|
/* Number of verbs contexts which have disabled ASPM */
|
||||||
atomic_t aspm_disabled_cnt;
|
atomic_t aspm_disabled_cnt;
|
||||||
/* Keeps track of user space clients */
|
/* Keeps track of user space clients */
|
||||||
atomic_t user_refcount;
|
refcount_t user_refcount;
|
||||||
/* Used to wait for outstanding user space clients before dev removal */
|
/* Used to wait for outstanding user space clients before dev removal */
|
||||||
struct completion user_comp;
|
struct completion user_comp;
|
||||||
|
|
||||||
|
|
|
@ -1747,7 +1747,7 @@ static void wait_for_clients(struct hfi1_devdata *dd)
|
||||||
* Remove the device init value and complete the device if there is
|
* Remove the device init value and complete the device if there is
|
||||||
* no clients or wait for active clients to finish.
|
* no clients or wait for active clients to finish.
|
||||||
*/
|
*/
|
||||||
if (atomic_dec_and_test(&dd->user_refcount))
|
if (refcount_dec_and_test(&dd->user_refcount))
|
||||||
complete(&dd->user_comp);
|
complete(&dd->user_comp);
|
||||||
|
|
||||||
wait_for_completion(&dd->user_comp);
|
wait_for_completion(&dd->user_comp);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче