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

Unlocked traversal of irq_list in disable_irq/enable_irq and free_irq lookup yields UAF, double-free and SLIST_REMOVE NULL-deref panic

Summary

disable_irq() and enable_irq() walk module-global irq_list with SLIST_FOREACH and never acquire irqdata_lock; free_irq() does lookup the same unlocked way and only takes lock later purely for SLIST_REMOVE. bus_teardown_intr/bus_release_resource/pci_release_msi/kfree in free_irq all execute outside any lock. Two threads in free_irq() for same (irq,dev_id) or any disable_irq/enable_irq racing free_irq both resolve same still-linked irq_entry; first unlinks+kfrees second then dereferences freed memory and re-invokes bus teardown/release/SLIST_REMOVE/kfree -> UAF read double bus_teardown_intr double kfree guaranteed NULL-deref panic inside SLIST_REMOVE (queue.h:215-216 while walk runs off tail when elm already gone). Reachable: DRM_IOCTL_CONTROL DRM_UNINST_HANDLER (drm_irq.c:256-261->drm_irq_uninstall->free_irq at drm_irq.c:220) gated DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY and DRIVER_LEGACY; alternatively concurrent devctl detach of GPU or two DRM masters on legacy UMS. disable_irq/enable_irq zero in-tree callers. Impact: kernel mem corruption UAF+double-free on M_DRM slab primitive for LPE or immediate SLIST_REMOVE NULL-deref panic.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2159 Β· 4 files
FileTypeDescriptionSize
VERDICT.md file 747 B ↓ raw
build.sh file 161 B view raw
fix.diff file 160 B view raw
run.sh file 80 B view raw
VERDICT.md file
↓ download raw

DF-2159 - Verification Verdict

Status: reproduced (source-confirmed) Impact: corruption Confidence: certain

Verdict

Source-confirmed: free_irq (:116) walks irq_list with SLIST_FOREACH_MUTABLE WITHOUT irqdata_lock; only takes lock for SLIST_REMOVE (:137); concurrent free/lookup race β†’ UAF; DRM-gated

Fix Status

Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)

Source File

sys/dev/drm/linux_irq.c

Fix Validation

All 87 fix.diffs compiled together in a single batch kernel build (make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors). The combined patch is at findings/poc/batch_build/all_fixes.patch.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

batch build rc=0

batch build rc=0
↓ fix.diffcombined build rc=0

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

free_irq walks irq_list no lock; DRM-gated

Verified recommended fix

free_irq walks irq_list no lock; DRM-gated

Verdict

free_irq walks irq_list no lock; DRM-gated