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

dm_dev_create assigns freed dmv to *dmvp on insert-failure path

Summary

When dm_dev_insert fails (returns EEXIST) dm_dev_create calls dm_dev_destroy(dmv) which frees dmv but then unconditionally executes *dmvp=dmv handing caller pointer to freed kernel memory. Currently benign: sole caller dm_dev_create_ioctl only dereferences dmv when r==0 but latent caller-side UAF any future caller that uses *dmvp unconditionally or any code that inspects out-parameter would touch freed memory. [VERIFIED pass2: reproduced structurally - EEXIST path assigns destroyed dmv to out-param; benign today sole caller checks r!=0; latent API hazard; success-only-assign fix-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2444 Β· 10 files
FileTypeDescriptionSize
README.md β€” 303 B ↓ raw
VERDICT.md β€” 1.2 KB ↓ raw
build.sh β€” 87 B view raw
dfmisc.c β€” 12.5 KB view raw
env.txt β€” 254 B view raw
fix.diff β€” 396 B view raw
manifest.json β€” 691 B view raw
run.log β€” 552 B view raw
run.sh β€” 110 B view raw
verdict.json β€” 1.5 KB view raw

DF-2444 -- evidence pack

Verdict: reproduced (reproduced=1, impact=none, confidence=certain)

Build: see build.sh (dfmisc.ko + dm.ko) Run: sysctl kern.dfmiscgo=dmeexist

See VERDICT.md for the full narrative, run.log/panic.txt for the decisive output, fix.diff for the post-verification fix.

VERDICT.md
↓ download raw

DF-2444 VERDICT

Status: reproduced Impact: none Confidence: certain

dm_dev_create on the EEXIST path hands out a pointer to freed memory: production call #1 (name df2444x) returned 0; production call #2 with the same name returned EEXIST (17) AND set the out-parameter dmv=0xfffff8008de708c0 - the object dm_dev_destroy just destroyed (dm_dev.c:264-267: destroy then dmvp = dmv). Currently benign: the sole caller checks r != 0 and never touches dmvp, so no corruption is reachable today; the defect is a latent caller-side UAF API hazard.

Kernel references

Guest

DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

Notes

root-only ioctl surface (dmsetup)

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
↓ fix.diffper-fix-DF-2444

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log (r1=0 / r2=17 with non-NULL stale out-param)

PoC changes

direct production dm_dev_create calls from the rig (dm.ko symbol)

Verified recommended fix

set *dmvp = dmv only on success (move the assignment above the insert-failure destroy, or NULL it on failure)

Verdict

dm_dev_create on the EEXIST path hands out a pointer to freed memory: production call #1 (name df2444x) returned 0; production call #2 with the same name returned EEXIST (17) AND set the out-parameter dmv=0xfffff8008de708c0 - the object dm_dev_destroy just destroyed (dm_dev.c:264-267: destroy then dmvp = dmv). Currently benign: the sole caller checks r != 0 and never touches dmvp, so no corruption is reachable today; the defect is a latent caller-side UAF API hazard.