drm_is_current_master returns stale is_master flag instead of comparing master pointers, defeating DRM_MASTER privilege revocation
Summary
drm_is_current_master (drm_auth.c:333-336) returns fpriv->is_master -- a STICKY bit set once at drm_new_set_master (line 160), never cleared when dev->master is reassigned away from this fd. Modern upstream Linux uses "fpriv->allowed_master || fpriv->master == fpriv->minor->dev->master". Once an fd has is_master=1, it permanently passes every DRM_MASTER ioctl permit check (drm_ioctl.c:547-549) even after dev->master reassigned to different master. Compounds with DF-2017: after mastership stolen via disabled-check, displaced (old) master retains full DRM_MASTER authority and can call drm_dropmaster_ioctl to drop NEW master ref because drm_drop_master unconditionally executes drm_master_put(&dev->master) without verifying dev->master == fpriv->master. Impact: integrity/availability disruption of display subsystem not confidentiality/code execution. AV:L/AC:H/PR:L, I:L/A:L.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2018 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | readme | original PoC README | 176 B | β raw |
| VERDICT.md | verdict | full source-trace verdict | 1.3 KB | β raw |
| build.sh | build-script | build/verify instructions | 438 B | view raw |
| env.txt | environment | guest environment (no matching HW) | 814 B | view raw |
| fix.diff | suggested-fix | git-apply-able fix, verified to compile -Werror | 540 B | view raw |
| fix_build.log | build-log | Phase 8 module build evidence (-Werror rc=0) | 1.5 KB | view raw |
| run.sh | run-script | run instructions (HW-gated) | 320 B | view raw |
DF-2018 PoC
See the parent finding markdown at findings/DF-2018-*.md for the full threat
model and PoC steps. This directory is the evidence-pack slot for the PoC
runner.
VERDICT -- DF-2018 (Low)
Verdict: REPRODUCED (source-only)
Impact: DRM_MASTER privilege revocation defeated (logic); HW-gated (needs DRM/GPU), source-confirmed
Confidence: likely
Mechanism (source-traced)
drm_is_current_master (drm_auth.c:333-336) returns fpriv->is_master -- a sticky bit set once at drm_new_set_master (drm_auth.c:160), never cleared when dev->master is reassigned. Modern upstream Linux uses 'fpriv->allowed_master || fpriv->master == fpriv->minor->dev->master'. Once an fd has is_master=1 it permanently passes every DRM_MASTER ioctl permit check (drm_ioctl.c:547-549) even after the device master moves to a different fd.
Why not runtime-reproduced
The guest (DragonFlyBSD 6.5-DEVELOPMENT #0 master DEV, KVM) has NO matching
hardware: pciconf shows no mfi/tws/iir RAID controller and no amdgpu/DRM GPU;
the driver therefore cannot attach and the vulnerable path is not runtime-
triggerable here. The defect was confirmed at the source level by tracing
the cited path:line against sys/, and the proposed fix was applied and the
affected module (drm) built clean with -Werror (see fix_build.log).
Fix
drm_auth.c:333-336: return fpriv->is_master && fpriv->master == fpriv->minor->dev->master so authority tracks the live device master pointer, not a sticky flag.
The standalone, git-apply-able diff is fix.diff.
Fix verification
not_testableVALIDATED build.
VALIDATED build.
Confirmed kernel references
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- d
- r
- m
- _
- a
- u
- t
- h
- .
- c
- :
- 3
- 3
- 3
- s
- y
- s
- /
- d
- e
- v
- /
- d
- r
- m
- /
- d
- r
- m
- _
- a
- u
- t
- h
- .
- c
- :
- 1
- 6
- 0
Detail
Exploit chain
none (HW-gated).
Evidence (decisive lines)
HW-GATED (no DRM). Source-CONFIRMED. drm_is_current_master returns sticky fpriv->is_master flag, not live master pointer comparison. DRM_MASTER authority persists after master reassignment.
Verified recommended fix
Return fpriv->is_master && fpriv->master==fpriv->minor->dev->master.
Verdict
HW-GATED (no DRM). Source-CONFIRMED. drm_is_current_master returns sticky fpriv->is_master flag, not live master pointer comparison. DRM_MASTER authority persists after master reassignment.
No comments yet.