uverbs_dmabuf_release() treats a NULL uobj->context as an aborted
allocation, but normal ufile cleanup also clears it. Closing the uverbs
FD before the dma-buf FD therefore skips uverbs_uobject_release() and
leaks the uobject and ufile references.
Clear dmabuf->priv before dma_buf_put() on allocation failure and use
that NULL pointer to identify an abort. Otherwise, always call
uverbs_uobject_release(). This also avoids reading a freed uobject if
release is deferred until after the allocation has been aborted.
Fixes: 0ac6f4056c4a ("RDMA/uverbs: Add DMABUF object type and operations")
Cc: [email protected]
Assisted-by: LLM
Signed-off-by: Deep Shah <[email protected]>
---
drivers/infiniband/core/uverbs_std_types_dmabuf.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/uverbs_std_types_dmabuf.c
b/drivers/infiniband/core/uverbs_std_types_dmabuf.c
index 2411ebee69e2..d88d30f1e42f 100644
--- a/drivers/infiniband/core/uverbs_std_types_dmabuf.c
+++ b/drivers/infiniband/core/uverbs_std_types_dmabuf.c
@@ -68,9 +68,10 @@ static void uverbs_dmabuf_release(struct dma_buf *dmabuf)
struct ib_uverbs_dmabuf_file *priv = dmabuf->priv;
/*
- * This can only happen if the fput came from alloc_abort_fd_uobject()
+ * This can only happen if the fput came from the error unwind of
+ * UVERBS_METHOD_DMABUF_ALLOC. The abort cleans up the uobject.
*/
- if (!priv->uobj.context)
+ if (!priv)
return;
uverbs_uobject_release(&priv->uobj);
@@ -141,6 +142,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_DMABUF_ALLOC)(
return 0;
err_revoked:
+ /* Tell uverbs_dmabuf_release() that the uobject is being aborted */
+ uverbs_dmabuf->dmabuf->priv = NULL;
dma_buf_put(uverbs_dmabuf->dmabuf);
err:
rdma_user_mmap_entry_put(mmap_entry);