Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* RDMA/rxe: use-after-free of rxe_qp when destroy_qp proceeds with a bound type-2 MW still holding a QP reference
@ 2026-09-30 16:49 AYS
  2026-09-30 18:01 ` Zhu Yanjun
  0 siblings, 1 reply; 2+ messages in thread
From: AYS @ 2026-09-30 16:49 UTC (permalink / raw)
  To: zyjzyj2000; +Cc: linux-rdma, security

Summary
  Component : drivers/infiniband/sw/rxe (Soft-RoCE)
  File/func : rxe_mw.c rxe_do_bind_mw() (takes the ref) and rxe_mw_cleanup()
              (uses it); rxe_qp.c rxe_qp_chk_destroy() (missing guard);
              rxe_pool.c __rxe_cleanup() (timeout path)
  Affected  : present in 7.3-rc4 (93f51579e7df). No commit touched
              drivers/infiniband/sw/rxe/ between 93f51579e7df and current
              master 551c722f4080 (2026-09-29) or rdma for-next, so
both are affected.
              (Distinct from ae36a5b6, which fixed a PD UAF on the rereg_mr
              path; this is a QP UAF on the destroy_qp path.)
  Config    : CONFIG_RDMA_RXE, CONFIG_INFINIBAND_USER_ACCESS
  Trigger   : local process able to open the rxe uverbs char device. One-time
              root setup; the trigger itself ran as uid 1000. IB_WR_BIND_MW is
              a local op, so no network/peer is needed.
  Primitive : use-after-free WRITE on a freed struct rxe_qp (kmalloc-2k): a 4B
              refcount_dec_and_test at offset 368, plus complete()/list work
              when it reaches zero.
  Found via : manual review. A reproducer exists and can be provided
              privately on request.

Details

A type-2 MW bind takes a reference on the QP:

/* rxe_mw.c rxe_do_bind_mw() */
if (mw->ibmw.type == IB_MW_TYPE_2) {
rxe_get(qp);
mw->qp = qp;
}

That reference is dropped only on IB_WR_LOCAL_INV (rxe_do_invalidate_mw()) or
when the MW itself is destroyed (rxe_mw_cleanup()). But destroy_qp does not
account for it: rxe_qp_chk_destroy() only refuses when qp->mcg_num != 0; it
does not check for bound type-2 MWs. So a QP with a live MW reference can be
torn down. __rxe_cleanup() then hits its -ETIMEDOUT path (the refcount has not
reached zero) and proceeds to free the QP anyway. Later, when the MW is
invalidated or deallocated, rxe_mw_cleanup() does rxe_put(mw->qp) on the freed
rxe_qp -- a refcount_dec_and_test write into freed memory, followed by
complete()/list manipulation if it hits zero.

Reproduced on a KASAN x86-64 build of 7.3-rc4 as uid 1000: KASAN
slab-use-after-free write via rxe_mw_cleanup -> __rxe_put on the freed
struct rxe_qp. Deterministic (not a race): bind a type-2 MW to an RTS QP,
destroy the QP, then deallocate the MW.

Suggested fix

Make rxe_qp_chk_destroy() refuse (or defer) destruction while the QP still has
bound type-2 MWs, analogous to the existing qp->mcg_num guard -- e.g. track a
bound-MW count on the QP and fail destroy_qp with -EBUSY, or drop the MW's QP
reference before the QP is freed.

I have not built/tested a patch; the Fixes: commit should be identified when
preparing one (introduced with type-2 MW support). A checkpatch-clean patch
can follow on request.

Signed-off-by: Youngsung Ahn <ays511.kr@gmail.com>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-30 18:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-30 16:49 RDMA/rxe: use-after-free of rxe_qp when destroy_qp proceeds with a bound type-2 MW still holding a QP reference AYS
2026-09-30 18:01 ` Zhu Yanjun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox