[PATCH] RDMA/core: fix refcount leak in __ib_alloc_pd()
From: Wentao Liang
Date: Mon Jun 08 2026 - 05:05:37 EST
The error handling in __ib_alloc_pd() has a refcount leak. When
get_dma_mr() fails it calls ib_dealloc_pd() which invokes
ib_dealloc_pd_user(). If the driver's dealloc_pd operation returns
an error, ib_dealloc_pd_user() returns early and skips both
rdma_restrack_del() and kfree(pd). This leaves the resource tracking
kref held and the pd memory unfreed. Because ib_dealloc_pd() has a
void return, __ib_alloc_pd() cannot detect the failure, so the leak
persists.
Fix it by always calling rdma_restrack_del() and kfree(pd) in
ib_dealloc_pd_user(), even when the driver callback fails. This
ensures the software state is cleaned up regardless of the hardware
operation result.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: 91a7c58fce06 ("RDMA: Restore ability to fail on PD deallocate")
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/infiniband/core/verbs.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index bac87de9cc67..6437ede11908 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -398,8 +398,11 @@ int ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)
}
ret = pd->device->ops.dealloc_pd(pd, udata);
- if (ret)
+ if (ret) {
+ rdma_restrack_del(&pd->res);
+ kfree(pd);
return ret;
+ }
rdma_restrack_del(&pd->res);
kfree(pd);
--
2.34.1