* [PATCH] RDMA/rxe: check the PD when invalidating an MR or MW
@ 2026-09-29 3:18 Yehyeong Lee
2026-09-29 3:29 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Yehyeong Lee @ 2026-09-29 3:18 UTC (permalink / raw)
To: Zhu Yanjun, Jason Gunthorpe, Leon Romanovsky
Cc: linux-rdma, linux-kernel, Yehyeong Lee, stable
rxe_invalidate_mr() and rxe_invalidate_mw() look the object up by index in
the device-wide pool and then only compare the key, so a QP can invalidate
an MR or MW that belongs to a different protection domain on the same rxe
device. Both entry points are affected: IB_WR_LOCAL_INV from the requester
and SEND_WITH_INVALIDATE from the responder, where the rkey comes off the
wire.
Everything else that resolves one of these objects already refuses a
foreign PD. lookup_mr() rejects mr_pd(mr) != pd, rxe_reg_fast_mr() rejects
qp->ibqp.pd != mr->ibmr.pd, and rxe_check_bind_mw() was given the same
check in commit fbbe1d5cd7d4 ("RDMA/rxe: Check PDs for memory window
binds"). Remote access is therefore scoped to a PD while remote
invalidation is not.
A peer on one connection can invalidate a kernel ULP's fast-reg MR on
another, which ends that ULP's I/O. Reject a foreign PD in both
functions; -EINVAL turns into RESPST_ERR_INVALIDATE_RKEY for the
responder and a failed work request for the requester.
The MR side has behaved this way since the driver was merged, where
do_complete() freed the MR it found by index; rxe_invalidate_mw() arrived
later carrying the same omission.
Fixes: 8700e3e7c485 ("Soft RoCE driver")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
---
Reproduced on rxe with two protection domains on one device. PD-A holds the
attacking QP, nvme-rdma holds PD-B and is running I/O. The RXEINV/RXEPD lines
below are instrumentation I added to observe it and are not part of this patch:
RXEINV prints the two PDs and the MR state inside rxe_invalidate_mr(), and the
attacker takes the target rkey from rxe_reg_fast_mr() rather than guessing it.
Before, a SEND_WITH_INVALIDATE naming nvme-rdma's rkey is accepted:
RXEPD: hunter: TARGET is a foreign-PD fast-reg MR: rkey=0x29ba mr_pd=00000000185f3e0e (mine: A=00000000d715b639 B=000000001440b63b) iova=0xffff888065174000
RXEPD: hunter: firing SEND_WITH_INV from QP-A(PD-A=00000000d715b639) at rkey=0x29ba
rdma_rxe: RXEINV: REMOTE entry rxe_resp.c execute() qp=27 wire_rkey=0x29ba
rdma_rxe: RXEINV: enter rxe_invalidate_mr qp=27 qp_pd=00000000d715b639 mr_pd=00000000185f3e0e cross_pd=1 key=0x29ba state_before=2
rdma_rxe: RXEINV: done rxe_invalidate_mr key=0x29ba state_after=1 (RXE_MR_STATE_FREE=1)
RXEPD: hunter SEND_WITH_INV -> wc.status=0 (success)
and nvme-rdma's I/O stops:
nvme nvme0: RECV for CQE 0x00000000448b8c67 failed with status WR flushed (5)
nvme nvme0: starting error recovery
nvme nvme0: Reconnecting in 10 seconds...
The controller does not recover, because each reconnect registers a new MR that
is invalidated the same way.
After, the same attack is refused:
RXEPD: hunter: TARGET is a foreign-PD fast-reg MR: rkey=0x90a0 mr_pd=0000000049ba8cc5 (mine: A=00000000a32c3059 B=000000006c5e8389) iova=0xffff88806bbb0000
RXEPD: hunter: firing SEND_WITH_INV from QP-A(PD-A=00000000a32c3059) at rkey=0x90a0
RXEPD: hunter SEND_WITH_INV -> wc.status=5 (WR flushed)
rxe_invalidate_mr() is not reached for a foreign PD, so no cross_pd=1 entry is
traced (4 before, 0 after), nvme-rdma keeps running,
BCHECK[D] DONE iters=524 clean_p0=524 ioerr=0 CORRUPT_HITS=0 POST_COMPLETION=0
Only the MR path is exercised above. The rxe_invalidate_mw() hunk is the same
omission in the MW path and is fixed for symmetry; I did not reproduce a
cross-PD MW invalidation.
nvme-rdma's own same-PD invalidations keep working: 3180 of them are traced with the
check in place.
drivers/infiniband/sw/rxe/rxe_mr.c | 6 ++++++
drivers/infiniband/sw/rxe/rxe_mw.c | 5 +++++
2 files changed, 11 insertions(+)
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index 71d9ea4772890..2da5134560730 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -743,6 +743,12 @@ int rxe_invalidate_mr(struct rxe_qp *qp, u32 key)
goto err_drop_ref;
}
+ if (unlikely(qp->ibqp.pd != mr->ibmr.pd)) {
+ rxe_dbg_mr(mr, "qp->pd and mr->pd don't match\n");
+ ret = -EINVAL;
+ goto err_drop_ref;
+ }
+
if (atomic_read(&mr->num_mw) > 0) {
rxe_dbg_mr(mr, "Attempt to invalidate an MR while bound to MWs\n");
ret = -EINVAL;
diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c
index bddb7a2578313..ab2212eabd71e 100644
--- a/drivers/infiniband/sw/rxe/rxe_mw.c
+++ b/drivers/infiniband/sw/rxe/rxe_mw.c
@@ -276,6 +276,11 @@ int rxe_invalidate_mw(struct rxe_qp *qp, u32 rkey)
goto err_drop_ref;
}
+ if (unlikely(qp->pd != rxe_mw_pd(mw))) {
+ ret = -EINVAL;
+ goto err_drop_ref;
+ }
+
spin_lock_bh(&mw->lock);
ret = rxe_check_invalidate_mw(qp, mw);
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] RDMA/rxe: check the PD when invalidating an MR or MW
2026-09-29 3:18 [PATCH] RDMA/rxe: check the PD when invalidating an MR or MW Yehyeong Lee
@ 2026-09-29 3:29 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-09-29 3:29 UTC (permalink / raw)
To: Yehyeong Lee; +Cc: linux-rdma
> rxe_invalidate_mr() and rxe_invalidate_mw() look the object up by index in
> the device-wide pool and then only compare the key, so a QP can invalidate
> an MR or MW that belongs to a different protection domain on the same rxe
> device. Both entry points are affected: IB_WR_LOCAL_INV from the requester
> and SEND_WITH_INVALIDATE from the responder, where the rkey comes off the
> wire.
>
> Everything else that resolves one of these objects already refuses a
> foreign PD. lookup_mr() rejects mr_pd(mr) != pd, rxe_reg_fast_mr() rejects
> qp->ibqp.pd != mr->ibmr.pd, and rxe_check_bind_mw() was given the same
> check in commit fbbe1d5cd7d4 ("RDMA/rxe: Check PDs for memory window
> binds"). Remote access is therefore scoped to a PD while remote
> invalidation is not.
>
> A peer on one connection can invalidate a kernel ULP's fast-reg MR on
> another, which ends that ULP's I/O. Reject a foreign PD in both
> functions; -EINVAL turns into RESPST_ERR_INVALIDATE_RKEY for the
> responder and a failed work request for the requester.
>
> The MR side has behaved this way since the driver was merged, where
> do_complete() freed the MR it found by index; rxe_invalidate_mw() arrived
> later carrying the same omission.
>
> Fixes: 8700e3e7c485 ("Soft RoCE driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260929031811.1550334-1-yhlee@isslab.korea.ac.kr?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-29 3:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 3:18 [PATCH] RDMA/rxe: check the PD when invalidating an MR or MW Yehyeong Lee
2026-09-29 3:29 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox