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

DRM magic auth tokens leaked to unprivileged users via sysctl hw.dri.N.clients (cross-file drm_sysctl.c)

Summary

drm_getmagic allocates per-fd auth magic token (drm_auth.c:65) intended as shared secret between DRM client and master. Same token exposed world-readably by drm_clients_info sysctl handler in drm_sysctl.c:290-294 which prints priv->magic for every open DRM file to ANY user reading sysctl hw.dri.N.clients. DragonFlyBSD sysctls readable by unprivileged users by default (kern_sysctl.c only privilege-checks writers line 1446). Sysctl OID created CTLFLAG_RD only (drm_sysctl.c:94) no CTLFLAG_SECURE no per-node privilege check. Tokens are low-entropy: idr_alloc starts at id 1 no randomization, sequential integers (1,2,3,...) independently guessable. Breaks DRI auth handshake security model: magic supposed to be capability token proving client handed something to master out-of-band. With all magics world-readable, malicious local user can impersonate another users client to a master that trusts magic-as-credential, or correlate magic with pid to track sessions. AV:L/PR:L/AC:L, C:L. drm_getclient ioctl already fixed to zero out client->magic (drm_ioctl.c:196) for this reason; sysctl handler should match.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2020 Β· 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 618 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-2020 PoC

See the parent finding markdown at findings/DF-2020-*.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-2020 (Low)

Verdict: REPRODUCED (source-only)

Impact: leak:DRM auth magic tokens via world-readable sysctl; HW-gated (needs DRM/GPU), source-confirmed

Confidence: likely

Mechanism (source-traced)

drm_getmagic allocates a per-fd auth magic token (drm_auth.c:64-68 via idr_alloc starting at id 1, sequential integers). The same token is printed world-readably by drm_clients_info (drm_sysctl.c:290-294) which prints priv->magic for every open DRM file under the CTLFLAG_RD-only sysctl hw.dri.N.clients. The drm_getclient ioctl already zeroes client->magic (drm_ioctl.c:196) for this reason; the sysctl handler does not match.

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_sysctl.c:290-294: redact priv->magic (print '-') in the world-readable hw.dri.N.clients sysctl, matching the drm_getclient ioctl fix.

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_clients_info prints priv->magic in world-readable hw.dri.N.clients sysctl. drm_getclient ioctl already zeroes it; sysctl does not.

Verified recommended fix

Redact priv->magic in sysctl (print '-').

Verdict

HW-GATED (no DRM). Source-CONFIRMED. drm_clients_info prints priv->magic in world-readable hw.dri.N.clients sysctl. drm_getclient ioctl already zeroes it; sysctl does not.