diff mbox series

[for-next,v4,13/13] RDMA/rxe: Protect against race between get_index and drop_ref

Message ID 20211103050241.61293-14-rpearsonhpe@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series Correct race conditions in rdma_rxe | expand

Commit Message

Bob Pearson Nov. 3, 2021, 5:02 a.m. UTC
Use refcount_inc_not_zero instead of kref_get to protect object
pointer returned by rxe_pool_get_index() to prevent chance of a
race between get_index and drop_ref by another thread.

Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
---
 drivers/infiniband/sw/rxe/rxe_pool.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Jason Gunthorpe Nov. 19, 2021, 5:46 p.m. UTC | #1
On Wed, Nov 03, 2021 at 12:02:42AM -0500, Bob Pearson wrote:
> Use refcount_inc_not_zero instead of kref_get to protect object
> pointer returned by rxe_pool_get_index() to prevent chance of a
> race between get_index and drop_ref by another thread.
> 
> Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
>  drivers/infiniband/sw/rxe/rxe_pool.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
> index 863fa62da077..688944fa3926 100644
> +++ b/drivers/infiniband/sw/rxe/rxe_pool.c
> @@ -272,8 +272,13 @@ void *rxe_pool_get_index(struct rxe_pool *pool, unsigned long index)
>  	}
>  
>  	elem = xa_load(&pool->xarray.xa, index);
> +
>  	if (elem) {
> -		kref_get(&elem->ref_cnt);
> +		/* protect against a race with someone else dropping
> +		 * the last reference to the object
> +		 */
> +		if (!__rxe_add_ref(elem))
> +			return NULL;
>  		obj = elem->obj;

That doesn't really work without RCU, since now you just use after
free on the ref_cnt atomic.

Jason
diff mbox series

Patch

diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
index 863fa62da077..688944fa3926 100644
--- a/drivers/infiniband/sw/rxe/rxe_pool.c
+++ b/drivers/infiniband/sw/rxe/rxe_pool.c
@@ -272,8 +272,13 @@  void *rxe_pool_get_index(struct rxe_pool *pool, unsigned long index)
 	}
 
 	elem = xa_load(&pool->xarray.xa, index);
+
 	if (elem) {
-		kref_get(&elem->ref_cnt);
+		/* protect against a race with someone else dropping
+		 * the last reference to the object
+		 */
+		if (!__rxe_add_ref(elem))
+			return NULL;
 		obj = elem->obj;
 	} else {
 		obj = NULL;