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);

Reply via email to