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

* Re: 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 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
  0 siblings, 0 replies; 2+ messages in thread
From: Zhu Yanjun @ 2026-09-30 18:01 UTC (permalink / raw)
  To: AYS, zyjzyj2000; +Cc: linux-rdma, security


在 2026/9/30 9:49, AYS 写道:
> 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.

I can not see the code snippet. Please resend this commit following the 
kernel style in document/process.

Thanks a lot.

Yanjun Zhu

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

-- 
Best Regards,
Yanjun.Zhu


^ 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