β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2018

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2018 Β· 7 files
FileTypeDescriptionSize
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
README.md readme original PoC README
↓ download 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.md verdict full source-trace verdict
↓ download raw

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_testable
baseline reproduced→ patch + rebuild →patched clean

VALIDATED build.

VALIDATED build.
↓ fix.diffdrm.ko build rc=0 -Werror

Confirmed kernel references

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.