]> www.infradead.org Git - users/hch/dma-mapping.git/commitdiff
drm/syncobj: Fix syncobj leak in drm_syncobj_eventfd_ioctl
authorT.J. Mercier <tjmercier@google.com>
Mon, 9 Sep 2024 20:53:59 +0000 (20:53 +0000)
committerChristian König <christian.koenig@amd.com>
Tue, 10 Sep 2024 15:14:52 +0000 (17:14 +0200)
A syncobj reference is taken in drm_syncobj_find, but not released if
eventfd_ctx_fdget or kzalloc fails. Put the reference in these error
paths.

Reported-by: Xingyu Jin <xingyuj@google.com>
Fixes: c7a472297169 ("drm/syncobj: add IOCTL to register an eventfd")
Signed-off-by: T.J. Mercier <tjmercier@google.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Reviewed-by. Christian König <christian.koenig@amd.com>
CC: stable@vger.kernel.org # 6.6+
Link: https://patchwork.freedesktop.org/patch/msgid/20240909205400.3498337-1-tjmercier@google.com
Signed-off-by: Christian König <christian.koenig@amd.com>
drivers/gpu/drm/drm_syncobj.c

index a0e94217b511a1551a0077b98e2bebc99d98513e..4fcfc0b9b386cffd0e36803ed256f24ee13bac70 100644 (file)
@@ -1464,6 +1464,7 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data,
        struct drm_syncobj *syncobj;
        struct eventfd_ctx *ev_fd_ctx;
        struct syncobj_eventfd_entry *entry;
+       int ret;
 
        if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
                return -EOPNOTSUPP;
@@ -1479,13 +1480,15 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data,
                return -ENOENT;
 
        ev_fd_ctx = eventfd_ctx_fdget(args->fd);
-       if (IS_ERR(ev_fd_ctx))
-               return PTR_ERR(ev_fd_ctx);
+       if (IS_ERR(ev_fd_ctx)) {
+               ret = PTR_ERR(ev_fd_ctx);
+               goto err_fdget;
+       }
 
        entry = kzalloc(sizeof(*entry), GFP_KERNEL);
        if (!entry) {
-               eventfd_ctx_put(ev_fd_ctx);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_kzalloc;
        }
        entry->syncobj = syncobj;
        entry->ev_fd_ctx = ev_fd_ctx;
@@ -1496,6 +1499,12 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data,
        drm_syncobj_put(syncobj);
 
        return 0;
+
+err_kzalloc:
+       eventfd_ctx_put(ev_fd_ctx);
+err_fdget:
+       drm_syncobj_put(syncobj);
+       return ret;
 }
 
 int