Re: [syzbot] [dri?] KASAN: slab-use-after-free Read in drm_gem_object_release_handle

Hillf Danton
2026-04-15T07:52:50Z

> Date: Mon, 13 Apr 2026 10:16:36 -0700 [thread overview]
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: f5459048c38a Merge tag 'i2c-for-7.0-final' of git://git.ke..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1028d106580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=6754c86e8d9e4c91
> dashboard link: https://syzkaller.appspot.com/bug?extid=b2e951687503f32f74ce
> compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1428d106580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=17509036580000

#syz test

--- x/drivers/gpu/drm/drm_gem.c
+++ y/drivers/gpu/drm/drm_gem.c
@@ -404,7 +404,8 @@ drm_gem_handle_delete(struct drm_file *f
spin_lock(&filp->table_lock);

/* Check if we currently have a reference on the object */
- obj = idr_replace(&filp->object_idr, NULL, handle);
+ obj = idr_find(&filp->object_idr, handle);
+ idr_remove(&filp->object_idr, handle);
spin_unlock(&filp->table_lock);
if (IS_ERR_OR_NULL(obj))
return -EINVAL;
@@ -412,11 +413,6 @@ drm_gem_handle_delete(struct drm_file *f
/* Release driver's reference and decrement refcount. */
drm_gem_object_release_handle(handle, obj, filp);

- /* And finally make the handle available for future allocations. */
- spin_lock(&filp->table_lock);
- idr_remove(&filp->object_idr, handle);
- spin_unlock(&filp->table_lock);
-
return 0;
}
EXPORT_SYMBOL(drm_gem_handle_delete);
@@ -1085,9 +1081,23 @@ drm_gem_open(struct drm_device *dev, str
void
drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
{
- idr_for_each(&file_private->object_idr,
- &drm_gem_object_release_handle, file_private);
+ struct drm_gem_object *obj;
+ int id;
+
+ mutex_lock(&file_private->prime.lock);
+ for (;;) {
+ id = 0;
+ spin_lock(&file_private->table_lock);
+ obj = idr_get_next(&file_private->object_idr, &id);
+ if (obj)
+ idr_remove(&file_private->object_idr, id);
+ spin_unlock(&file_private->table_lock);
+ if (!obj)
+ break;
+ drm_gem_object_release_handle(id, obj, file_private);
+ }
idr_destroy(&file_private->object_idr);
+ mutex_unlock(&file_private->prime.lock);
}

/**
--