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)
PoC verification
Evidence pack
findings/poc/DF-2444 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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.
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_testableConfirmed 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.
No comments yet.