drm_legacy_sg_free clears dev->sg before validating the handle: a failed match permanently orphans the sg allocation and a re-alloc stacks a second one on top (latent: root-only ioctl, no DRIVER_SG/LEGACY driver in tree)
Summary
clear-before-validate orphans the KVA range + arrays on a bad handle with no recovery path; repeating bad-free/re-alloc drains kernel_map monotonically. Latent twice over (root-only + no in-tree DRIVER_SG driver). Validate-under-DRM_LOCK-before-clear fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-5193 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| drm_sg_probe.c | β | 1.3 KB | view raw | |
| build.sh | β | 66 B | view raw | |
| run.sh | β | 90 B | view raw | |
| build.log | β | 9 B | view raw | |
| run.log | β | 628 B | view raw | |
| fix.diff | β | 832 B | view raw | |
| verdict.json | β | 2.9 KB | view raw | |
| env.txt | β | 401 B | view raw |
Fix verification
not_testableNo baseline exists to validate against (no DRIVER_SG driver in the tree, no DRM device on the guest). fix.diff authored for the day the path revives (it mirrors upstream Linux ordering discipline).
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
run.log (open of every DRM node -> ENOENT; kldstat shows no drm modules); VERDICT.md (privilege + feature gate citations, plus the negative kill-list: no busaddr-size overflow possible, size-0 wrap benign, dev->sg lifecycle fully serialized under drm_global_mutex so no double-free race)
PoC changes
n/a (finding originated in this run)
Verified recommended fix
drm_legacy_sg_free: take DRM_LOCK, validate entry && entry->vaddr == request->handle before clearing dev->sg, and only then NULL it and clean up.
Verdict
Code-level defect confirmed (clear-before-validate in drm_legacy_sg_free orphans the sg allocation on a handle mismatch and permits a second SG_ALLOC on top of the leak), but it is unreachable in this tree and on this guest: the SG ioctls are DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY (capable(CAP_SYS_ADMIN) enforced at drm_ioctl.c:538), and no in-tree driver sets DRIVER_SG or DRIVER_LEGACY, so both handlers return -EOPNOTSUPP at drm_scatter.c:69-73/:125-129 even for root; the QEMU guest additionally has no DRM device nodes at all (run.log). Double-latent; filed Info for the record with a fix.diff, consistent with the drm-family latent findings (DF-5187/DF-5188/DF-5190).
No comments yet.