
Proof-of-Concept und KASAN-bestätigter KUnit-Reproduzierer für CVE-2026-98180, einen drm/msm Use-after-free von schedulerhaltigen Ring- und VM-Objekten, die über unprivilegiertes SYNC_IOC_FILE_INFO erreichbar sind.
Ein an den Userspace exportiertes drm_sched_fence behält einen rohen Zeiger auf den
drm_gpu_scheduler, der es erzeugt hat. In drm/msm ist dieser Scheduler eingebettet
in struct msm_ringbuffer und struct msm_gem_vm, die beide mit einem einfachen
kfree() freigegeben wurden. Ein abgeschlossenes Fence, das vom Userspace gehalten wird,
überlebt daher seinen Scheduler, und ein späteres SYNC_IOC_FILE_INFO — ein unprivilegierter
ioctl — veranlasst drm_sched_fence_get_timeline_name(), auf freigegebenen Slab-Speicher
zuzugreifen.
BUG: KASAN: slab-use-after-free in drm_sched_fence_get_timeline_name
Read of size 8
drm_sched_fence_get_timeline_name() ist return fence->sched->name;.
Die Scheduler-Fence-Ops behalten einen .release-Callback, daher wird das Fence beim
Signalisieren nicht von den Ops abgekoppelt. Ein signalisiertes Fence, das über
sync_file oder drm_syncobj exportiert wurde, zeigt weiterhin auf den eingebetteten
Scheduler, nachdem der Ring oder die VM freigegeben wurde. Gemäß dem dma-fence-Lebensdauer-
Vertrag muss der Exporter die Daten, die ein signalisiertes Fence stützen, für eine
RCU-Grace-Period am Leben halten; drm/msm tat dies nicht.
| Fix | 01c8d1f385f7 — drm/msm: RCU-free the scheduler-containing ring and VM objects |
| Eingeführt durch | 1d8a5ca436ee (drm/msm: Conversion to drm scheduler), 92395af63a99 (drm/msm: Add VM_BIND submitqueue) |
| Backportiert | 6.18-stable, 7.2-stable (Greg Kroah-Hartman, 2026-09-22) |
| Erreichbarkeit | unprivilegiert — SYNC_IOC_FILE_INFO auf einem Fence-fd |
| Auswirkung | UAF-Lesezugriff auf freigegebenen Slab (Info-Leak / beliebiges Lesen des Namenszeigers des freigegebenen Objekts) |
Der Fix ersetzt kfree() durch kfree_rcu() für beide enthaltenden Objekte:
- kfree(vm);
+ kfree_rcu(vm, rcu);
...
- kfree(ring);
+ kfree_rcu(ring, rcu);
Der Fehler liegt in der generischen drm/sched-Lebensdauerverwaltung, daher lässt er sich
ohne Adreno-Hardware mit einem KUnit-Mock-Scheduler reproduzieren. Das ist der
Nachweis 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 — hardwareunabhängiger KUnit-Reproduzierer (KASAN-bestätigt)poc/poc_userspace_drm_sched_uaf.c — die unprivilegierte Userspace-ioctl-Sequenz auf einem betroffenen Treiberpoc/kunitconfig, poc/run-repro.sh — Build-/Run-Harnessevidence/kasan-report.txt — der KASAN-slab-use-after-free-Berichtpoc_userspace_drm_sched_uaf.c ist gegen AMD XDNA als ausgearbeitetes Beispiel geschrieben,
weil dieses Gerät verfügbar war; die identische Form gilt für msm
(MSM_SUBMITQUEUE / VM_BIND exportieren ein abgeschlossenes Fence über
sync_file_create() + fd_install()) und für nouveau.
Dieselbe dma-fence-Lebensdauerkategorie wurde auch im Core behoben:
3ed11c671ff7
— dma-buf/dma-fence: fix checking signaling bit for timeline and driver name v3
(verfasst von Christian König; gemeldet und getestet vom Autor dieses Repos).
Gefunden und behoben von JongHyuk Kim(MalHyuk) — [email protected].
Patch signiert von Rob Clark und Greg Kroah-Hartman.
Patchwork: https://patchwork.freedesktop.org/patch/750234/
Der Reproducer-Code ist GPL-2.0, passend zu den Kernel-Quellen, von denen er abgeleitet ist.