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

cuse_server_open re-initializes global cuse_global_mtx on every /dev/cuse open corrupting lock state

Summary

cuse_server_open at cuse.c:791: lockinit(&cuse_global_mtx,...) unconditionally zeroes lk_count/lk_lockholder. Global mtx already init at boot :293. Concurrent holder (cuse_server_unref TAILQ_REMOVE :701) loses lock -> two threads in global critical section -> cuse_server_head TAILQ corruption -> UAF/double-free. Copy-paste of boot init, should only init pcs->mtx. Root only (/dev/cuse 0600). Fix: delete line 791.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1404 Β· 8 files
FileTypeDescriptionSize
fix.diff suggested-fix Delete the erroneous lockinit(&cuse_global_mtx,...) line in cuse_server_open (copy-paste of boot init). 371 B view raw
VERDICT.md verdict Full source-trace analysis 2.2 KB ↓ raw
build.sh build-script Kernel build validation 529 B view raw
run.sh run-script PoC runner (not runnable on guest) 608 B view raw
fix_build.log build-log Full kernel build output (make nativekernel rc=0) 5.6 MB ↓ download
env.txt environment Guest environment 277 B view raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
VERDICT.md verdict Full source-trace analysis
↓ download raw

DF-1404 β€” Verification Verdict

Verdict: CONFIRMED-BY-SOURCE-TRACE (root/operator-only, module not loaded)

Status: inconclusive (HW-gated / not reachable as unprivileged maxx) Impact: none (cannot reproduce on QEMU guest β€” no GPU/HW, or root/operator-only) Confidence: certain (source-trace confirmed bug is real)

Mechanism

cuse_server_open (:791): lockinit(&cuse_global_mtx,...) unconditionally zeroes lk_count/lk_lockholder. Global mtx already initialized at boot (:293). Concurrent holder (cuse_server_unref TAILQ_REMOVE :701) loses lock β†’ two threads in global critical section β†’ cuse_server_head TAILQ corruption β†’ UAF/double-free. This is a copy-paste of boot init; should only init pcs->mtx (which :793 already does correctly).

Source: sys/dev/misc/cuse/cuse.c:791

Why it cannot be reproduced on this guest

NOT reachable as maxx. cuse.ko is not loaded, no /dev/cuse exists. Even when loaded, /dev/cuse is 0600 root:operator (maxx not in operator).

Phase 6: Escalation Assessment

This is a Root/operator-only (cuse module not loaded) finding. The primitive is not reachable from the unprivileged maxx user on this guest (no hardware / module not loaded / root-only device). No escalation chain is possible because the trigger path is not exercisable.

For GPU findings: the module (radeon.ko/amdgpu.ko/i915.ko) is a loadable module not present in the GENERIC kernel and requires actual GPU hardware absent from the QEMU guest. For root/operator findings: the device node is mode 0600 or 0640 root:operator, and maxx (uid 1001) has no operator group membership.

Fix

Delete line 791 (the erroneous lockinit of cuse_global_mtx). Line 793 already correctly inits pcs->mtx.

Fix description: Delete the erroneous lockinit(&cuse_global_mtx,...) line in cuse_server_open (copy-paste of boot init).

The full git-apply-able diff is in fix.diff. It applies cleanly to the audit source tree and compiles as part of the kernel build (validated via make nativekernel rc=0).

Classification

  • status: inconclusive
  • reproduced: 0
  • impact: none
  • fix_status: not_testable (HW-gated: PoC cannot run on guest; diff applies + compiles verified)

Confirmed kernel references

Detail

Exploit chain

none (mutex re-init β†’ TAILQ corruption β†’ UAF/double-free race. Would be a write-capable primitive if reachable, but /dev/cuse is root/operator-only. Not reachable from unprivileged maxx.)

Evidence (decisive lines)

Source trace: cuse.c:791 'lockinit(&cuse_global_mtx, "cuse-global-lock", 0, LK_CANRECURSE)' β€” re-inits global, should be deleted. :793 'lockinit(&pcs->mtx, "cuse-mtx", 0, LK_CANRECURSE)' β€” correct. Guest: ls /dev/cuse β†’ No such file.

PoC changes

Authored fix.diff: delete the erroneous lockinit(&cuse_global_mtx,...) line (line 791). Line 793 already correctly inits pcs->mtx.

Verified recommended fix

Delete the erroneous lockinit(&cuse_global_mtx,...) in cuse_server_open β€” it is a copy-paste of boot init. matches finding proposal. Full diff in findings/poc/DF-1404/fix.diff.

Verdict

CONFIRMED BY SOURCE TRACE. cuse_server_open at cuse.c:791: lockinit(&cuse_global_mtx,...) unconditionally zeroes the global mutex (already initialized at boot :293). Concurrent holder (cuse_server_unref TAILQ_REMOVE :701) loses lock β†’ two threads in global critical section β†’ TAILQ corruption β†’ UAF/double-free. Copy-paste error; :793 correctly inits pcs->mtx. Bug is real but NOT reachable as maxx: cuse.ko not loaded, no /dev/cuse. Even when loaded, /dev/cuse is 0600 root:operator (maxx not in operator).