All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bob Pearson <rpearsonhpe@gmail.com>
To: jgg@nvidia.com, zyjzyj2000@gmail.com, linux-rdma@vger.kernel.org
Cc: Bob Pearson <rpearsonhpe@gmail.com>
Subject: [PATCH for-next v11 10/13] RDMA/rxe: Stop lookup of partially built objects
Date: Thu,  3 Mar 2022 18:08:06 -0600	[thread overview]
Message-ID: <20220304000808.225811-11-rpearsonhpe@gmail.com> (raw)
In-Reply-To: <20220304000808.225811-1-rpearsonhpe@gmail.com>

Currently the rdma_rxe driver has a security weakness due to giving
objects which are partially initialized indices allowing external
actors to gain access to them by sending packets which refer to
their index (e.g. qpn, rkey, etc) causing unpredictable results.

This patch adds two new APIs rxe_show(obj) and rxe_hide(obj) which
enable or disable looking up pool objects from indices using
rxe_pool_get_index(). By default objects are disabled. These APIs
are used to enable looking up objects which have indices:
AH, SRQ, QP, MR, and MW. They are added in create verbs after the
objects are fully initialized and as soon as possible in destroy
verbs.

Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
---
 drivers/infiniband/sw/rxe/rxe_mr.c    |  2 ++
 drivers/infiniband/sw/rxe/rxe_mw.c    |  4 +++
 drivers/infiniband/sw/rxe/rxe_pool.c  | 40 +++++++++++++++++++++++++--
 drivers/infiniband/sw/rxe/rxe_pool.h  |  5 ++++
 drivers/infiniband/sw/rxe/rxe_verbs.c | 12 ++++++++
 5 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index 60a31b718774..e4ad2cc12584 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -689,6 +689,8 @@ int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
 		return -EINVAL;
 	}
 
+	rxe_hide(mr);
+
 	mr->state = RXE_MR_STATE_INVALID;
 	rxe_put(mr_pd(mr));
 	rxe_put(mr);
diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
index c86b2efd58f2..4edbed1410e9 100644
--- a/drivers/infiniband/sw/rxe/rxe_mw.c
+++ b/drivers/infiniband/sw/rxe/rxe_mw.c
@@ -25,6 +25,8 @@ int rxe_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata)
 			RXE_MW_STATE_FREE : RXE_MW_STATE_VALID;
 	spin_lock_init(&mw->lock);
 
+	rxe_show(mw);
+
 	return 0;
 }
 
@@ -56,6 +58,8 @@ int rxe_dealloc_mw(struct ib_mw *ibmw)
 	struct rxe_mw *mw = to_rmw(ibmw);
 	struct rxe_pd *pd = to_rpd(ibmw->pd);
 
+	rxe_hide(mw);
+
 	spin_lock_bh(&mw->lock);
 	rxe_do_dealloc_mw(mw);
 	spin_unlock_bh(&mw->lock);
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c
index b0dfeb08a470..c0b70687a83e 100644
--- a/drivers/infiniband/sw/rxe/rxe_pool.c
+++ b/drivers/infiniband/sw/rxe/rxe_pool.c
@@ -159,7 +159,7 @@ void *rxe_alloc(struct rxe_pool *pool)
 	elem->obj = obj;
 	kref_init(&elem->ref_cnt);
 
-	err = xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit,
+	err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
 			      &pool->next, GFP_KERNEL);
 	if (err)
 		goto err_free;
@@ -187,7 +187,7 @@ int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem)
 	elem->obj = (u8 *)elem - pool->elem_offset;
 	kref_init(&elem->ref_cnt);
 
-	err = xa_alloc_cyclic(&pool->xa, &elem->index, elem, pool->limit,
+	err = xa_alloc_cyclic(&pool->xa, &elem->index, NULL, pool->limit,
 			      &pool->next, GFP_KERNEL);
 	if (err)
 		goto err_cnt;
@@ -221,8 +221,12 @@ static void rxe_elem_release(struct kref *kref)
 {
 	struct rxe_pool_elem *elem = container_of(kref, typeof(*elem), ref_cnt);
 	struct rxe_pool *pool = elem->pool;
+	struct xarray *xa = &pool->xa;
+	unsigned long flags;
 
-	xa_erase(&pool->xa, elem->index);
+	xa_lock_irqsave(xa, flags);
+	__xa_erase(&pool->xa, elem->index);
+	xa_unlock_irqrestore(xa, flags);
 
 	if (pool->cleanup)
 		pool->cleanup(elem);
@@ -242,3 +246,33 @@ int __rxe_put(struct rxe_pool_elem *elem)
 {
 	return kref_put(&elem->ref_cnt, rxe_elem_release);
 }
+
+int __rxe_show(struct rxe_pool_elem *elem)
+{
+	struct xarray *xa = &elem->pool->xa;
+	unsigned long flags;
+	void *ret;
+
+	xa_lock_irqsave(xa, flags);
+	ret = __xa_store(&elem->pool->xa, elem->index, elem, GFP_KERNEL);
+	xa_unlock_irqrestore(xa, flags);
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+	else
+		return 0;
+}
+
+int __rxe_hide(struct rxe_pool_elem *elem)
+{
+	struct xarray *xa = &elem->pool->xa;
+	unsigned long flags;
+	void *ret;
+
+	xa_lock_irqsave(xa, flags);
+	ret = __xa_store(&elem->pool->xa, elem->index, NULL, GFP_KERNEL);
+	xa_unlock_irqrestore(xa, flags);
+	if (IS_ERR(ret))
+		return PTR_ERR(ret);
+	else
+		return 0;
+}
diff --git a/drivers/infiniband/sw/rxe/rxe_pool.h b/drivers/infiniband/sw/rxe/rxe_pool.h
index 24bcc786c1b3..c48d8f6f95f3 100644
--- a/drivers/infiniband/sw/rxe/rxe_pool.h
+++ b/drivers/infiniband/sw/rxe/rxe_pool.h
@@ -79,4 +79,9 @@ int __rxe_put(struct rxe_pool_elem *elem);
 
 #define rxe_read(obj) kref_read(&(obj)->elem.ref_cnt)
 
+int __rxe_show(struct rxe_pool_elem *elem);
+#define rxe_show(obj) __rxe_show(&(obj)->elem)
+int __rxe_hide(struct rxe_pool_elem *elem);
+#define rxe_hide(obj) __rxe_hide(&(obj)->elem)
+
 #endif /* RXE_POOL_H */
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 67184b0281a0..e010e8860492 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -197,6 +197,8 @@ static int rxe_create_ah(struct ib_ah *ibah,
 	}
 
 	rxe_init_av(init_attr->ah_attr, &ah->av);
+	rxe_show(ah);
+
 	return 0;
 }
 
@@ -228,6 +230,7 @@ static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags)
 {
 	struct rxe_ah *ah = to_rah(ibah);
 
+	rxe_hide(ah);
 	rxe_put(ah);
 	return 0;
 }
@@ -310,6 +313,7 @@ static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init,
 	if (err)
 		goto err2;
 
+	rxe_show(srq);
 	return 0;
 
 err2:
@@ -368,6 +372,7 @@ static int rxe_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
 {
 	struct rxe_srq *srq = to_rsrq(ibsrq);
 
+	rxe_hide(srq);
 	if (srq->rq.queue)
 		rxe_queue_cleanup(srq->rq.queue);
 
@@ -439,6 +444,7 @@ static int rxe_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init,
 	if (err)
 		goto qp_init;
 
+	rxe_show(qp);
 	return 0;
 
 qp_init:
@@ -491,6 +497,7 @@ static int rxe_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
 	struct rxe_qp *qp = to_rqp(ibqp);
 	int ret;
 
+	rxe_hide(qp);
 	ret = rxe_qp_chk_destroy(qp);
 	if (ret)
 		return ret;
@@ -904,6 +911,7 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)
 
 	rxe_get(pd);
 	rxe_mr_init_dma(pd, access, mr);
+	rxe_show(mr);
 
 	return &mr->ibmr;
 }
@@ -932,6 +940,8 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
 	if (err)
 		goto err3;
 
+	rxe_show(mr);
+
 	return &mr->ibmr;
 
 err3:
@@ -964,6 +974,8 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
 	if (err)
 		goto err2;
 
+	rxe_show(mr);
+
 	return &mr->ibmr;
 
 err2:
-- 
2.32.0


  parent reply	other threads:[~2022-03-04  0:08 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-03-04  0:07 [PATCH for-next v11 00/13] Fix race conditions in rxe_pool Bob Pearson
2022-03-04  0:07 ` [PATCH for-next v11 01/13] RDMA/rxe: Fix ref error in rxe_av.c Bob Pearson
2022-03-04  0:07 ` [PATCH for-next v11 02/13] RDMA/rxe: Replace mr by rkey in responder resources Bob Pearson
2022-03-04  0:07 ` [PATCH for-next v11 03/13] RDMA/rxe: Reverse the sense of RXE_POOL_NO_ALLOC Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 04/13] RDMA/rxe: Delete _locked() APIs for pool objects Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 05/13] RDMA/rxe: Replace obj by elem in declaration Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 06/13] RDMA/rxe: Move max_elem into rxe_type_info Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 07/13] RDMA/rxe: Shorten pool names in rxe_pool.c Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 08/13] RDMA/rxe: Replace red-black trees by xarrays Bob Pearson
2022-03-15 23:45   ` Jason Gunthorpe
2022-03-16  3:05     ` Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 09/13] RDMA/rxe: Use standard names for ref counting Bob Pearson
2022-03-04  0:08 ` Bob Pearson [this message]
2022-03-16  0:16   ` [PATCH for-next v11 10/13] RDMA/rxe: Stop lookup of partially built objects Jason Gunthorpe
2022-03-16  3:55     ` Bob Pearson
2022-03-16 13:42       ` Jason Gunthorpe
2022-03-04  0:08 ` [PATCH for-next v11 11/13] RDMA/rxe: Add wait_for_completion to pool objects Bob Pearson
2022-03-16  0:17   ` Jason Gunthorpe
2022-03-16  3:57     ` Bob Pearson
2022-03-16 13:43       ` Jason Gunthorpe
2022-03-04  0:08 ` [PATCH for-next v11 12/13] RDMA/rxe: Convert read side locking to rcu Bob Pearson
2022-03-16  0:18   ` Jason Gunthorpe
2022-03-16  4:05     ` Bob Pearson
2022-03-04  0:08 ` [PATCH for-next v11 13/13] RDMA/rxe: Cleanup rxe_pool.c Bob Pearson
2022-03-16  0:25 ` [PATCH for-next v11 00/13] Fix race conditions in rxe_pool Jason Gunthorpe
2022-03-16  4:05   ` Bob Pearson
2022-03-16 16:08     ` Jason Gunthorpe
2022-03-16 16:09       ` Pearson, Robert B

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220304000808.225811-11-rpearsonhpe@gmail.com \
    --to=rpearsonhpe@gmail.com \
    --cc=jgg@nvidia.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=zyjzyj2000@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.