
Proof-of-concept and KASAN-confirmed KUnit reproducer for CVE-2026-98180, a drm/msm use-after-free of scheduler-containing ring and VM objects reachable via unprivileged SYNC_IOC_FILE_INFO.
A drm_sched_fence exported to userspace keeps a raw pointer to the
drm_gpu_scheduler that produced it. In drm/msm that scheduler is embedded
in struct msm_ringbuffer and struct msm_gem_vm, both of which were freed
with a plain kfree(). A finished fence held by userspace therefore outlives
its scheduler, and a later SYNC_IOC_FILE_INFO — an unprivileged ioctl —
makes drm_sched_fence_get_timeline_name() dereference freed slab memory.
BUG: KASAN: slab-use-after-free in drm_sched_fence_get_timeline_name
Read of size 8
drm_sched_fence_get_timeline_name() is return fence->sched->name;.
The scheduler fence ops keep a .release callback, so the fence is not
ops-detached when it signals. A signalled fence exported via sync_file or
drm_syncobj keeps pointing at the embedded scheduler after the ring or VM is
freed. Per the dma-fence lifetime contract the exporter must keep the data
backing a signalled fence alive for an RCU grace period; drm/msm did not.
| Fix | 01c8d1f385f7 — drm/msm: RCU-free the scheduler-containing ring and VM objects |
| Introduced by | 1d8a5ca436ee (drm/msm: Conversion to drm scheduler), 92395af63a99 (drm/msm: Add VM_BIND submitqueue) |
| Backported | 6.18-stable, 7.2-stable (Greg Kroah-Hartman, 2026-09-22) |
| Reachability | unprivileged — SYNC_IOC_FILE_INFO on a fence fd |
| Impact | UAF read of freed slab (info-leak / arbitrary read of the freed object's name pointer) |
The fix replaces kfree() with kfree_rcu() for both containing objects:
- kfree(vm);
+ kfree_rcu(vm, rcu);
...
- kfree(ring);
+ kfree_rcu(ring, rcu);
The bug is in generic drm/sched lifetime handling, so it reproduces without
Adreno hardware using a KUnit mock scheduler. That is the evidence in
evidence/kasan-report.txt.
cd poc && ./run-repro.sh # applies 0001-…patch, builds KUnit + KASAN, runs
poc/0001-drm-sched-kunit-uaf-repro.patch — hardware-independent KUnit reproducer (KASAN-confirmed)poc/poc_userspace_drm_sched_uaf.c — the unprivileged userspace ioctl sequence on an affected driverpoc/kunitconfig, poc/run-repro.sh — build/run harnessevidence/kasan-report.txt — the KASAN slab-use-after-free reportpoc_userspace_drm_sched_uaf.c is written against AMD XDNA as the worked
example because that device was available; the identical shape applies to msm
(MSM_SUBMITQUEUE / VM_BIND export a finished fence through
sync_file_create() + fd_install()) and to nouveau.
The same dma-fence lifetime class was also fixed in the core:
3ed11c671ff7
— dma-buf/dma-fence: fix checking signaling bit for timeline and driver name v3
(authored by Christian König; reported and tested by the author of this repo).
Found and fixed by JongHyuk Kim(MalHyuk) — [email protected].
Patch signed off by Rob Clark and Greg Kroah-Hartman.
Patchwork: https://patchwork.freedesktop.org/patch/750234/
Reproducer code is GPL-2.0, matching the kernel sources it derives from.