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

dm_target_dmirror.c is non-compiling, unregistered dead scratch code whose latent memory-safety bugs must never be revived β€” delete it

Summary

Proven dead: 216 lines of compiler errors on guest build, absent from dm SUBDIR, no dm_target_insert, no .ko anywhere. Latent bugs catalogued (double vn_strategy of one bio, OOB disks[i], double biodone). Delete-the-directory fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4973 Β· 9 files
FileTypeDescriptionSize
README.md β€” 3.1 KB ↓ raw
VERDICT.md β€” 3.3 KB ↓ raw
build.sh β€” 138 B view raw
run.sh β€” 168 B view raw
build.log β€” 16.0 KB view raw
run.log β€” 171 B view raw
env.txt β€” 333 B view raw
manifest.json β€” 1.2 KB view raw
verdict.json β€” 1013 B view raw

DF-4973 β€” dm_target_dmirror.c is non-compiling, unregistered dead code (no attack surface)

Claim

sys/dev/disk/dm/dmirror/dm_target_dmirror.c (384 LOC) is a 2010-era scratch file that was committed mid-thought. It:

  • cannot compile β€” dozens of hard errors (verified by building the kmod on the audit guest, full log in build.log);
  • is not referenced by any build β€” absent from sys/dev/disk/dm/Makefile SUBDIR= linear striped crypt delay flakey (dmirror/Makefile is an orphan kmod makefile), and has zero references in sys/conf/, sys/config/;
  • registers nothing β€” every real dm target ends with DM_TARGET_MODULE(...) + dm_target_insert() (e.g. sys/dev/disk/dm/linear/dm_target_linear.c); this file has no module handler, no dm_target_insert, and no init/destroy/table/status/deps handlers at all (its own last line: /* XXX: add missing dm functions */).

Therefore the dm "dmirror" target has zero runtime attack surface on any DragonFly system: no kernel or module built from this tree contains any of its code, and no dmsetup create … dmirror table load can reach it (no registered target named dmirror exists).

Latent bugs (why this file must be deleted, not "finished")

If anyone ever made this compile, it would ship immediately-fatal bugs:

  • dm_target_dmirror_strategy() default case dispatches the same bio twice to two different vnodes (vn_strategy(priv->pdev[0]->pdev_vnode, &bp->b_bio1) then priv->pdev[1] with the identical bio, dm_target_dmirror.c:376-377) β€” double completion β†’ buf UAF;
  • m_disk = &config->disks[i] with i == config->ndisks after the loop (dm_target_dmirror.c:295) β€” OOB index into disks[4];
  • dmirror_write() fan-out completes the parent bio once per mirror leg (dmirror_write_done() does biodone(pop_bio(bio)) on both clones, dm_target_dmirror.c:135-137) β€” double biodone;
  • placeholders throughout: XXX config->ndisks (:157, :251), XXX disk1/disk2 (:174-175), foo |= flag (:186), foo &= ~flag (:196), biodone(foo) (:262), undeclared nestbuf/next_disk, undefined SEGNO_FROM_OFFSET/SEGDESC_FROM_OFFSET/OFFSET_FROM_SEGNO macros, and a redeclared struct buf *bp (:310) shadowing the function parameter.

Reproduce

# on the audit guest (source tree at /usr/src):
cd /usr/src/sys/dev/disk/dm/dmirror && make        # β†’ errors, exit 1
ls /boot/kernel/dm_target_dmirror* /boot/modules/dm_target_dmirror*   # β†’ none

Expected result

make fails with a wall of compile errors (request for member … not a structure or union, implicit declaration of …, …) and produces no dm_target_dmirror.ko; no such module exists in /boot. This is the demonstration of the finding: the code is dead and cannot be loaded or reached by any means, so none of its latent memory-safety bugs are exploitable.

Delete sys/dev/disk/dm/dmirror/ (the .c, the orphan Makefile, and dmirror_notes.txt design notes β€” or move the notes to a docs area). The dmirror design in dmirror_notes.txt should be re-implemented from scratch with the dm-target registration discipline every other target follows.

VERDICT.md
↓ download raw

DF-4973 VERDICT

Finding under test

sys/dev/disk/dm/dmirror/dm_target_dmirror.c is non-compiling, unbuildable, unregistered dead code β€” hence no attack surface β€” despite containing latent memory-safety defects (double vn_strategy on one bio at dm_target_dmirror.c:376-377, post-loop OOB &config->disks[i] at :295, double biodone of the parent bio at :135-137/170-175, and XXX/foo placeholders at :157, :174-175, :186, :196, :262).

What was done (guest, DragonFly 6.5-DEVELOPMENT #0, X86_64_GENERIC)

  1. Verified the wiring on the source tree: * sys/dev/disk/dm/Makefile β€” SUBDIR= linear striped crypt delay flakey; dmirror is not in it; * grep -rn dm_target_dmirror sys/conf/ sys/config/ β†’ no references; * contrast sys/dev/disk/dm/linear/dm_target_linear.c (tail): every live target self-registers via DM_TARGET_MODULE + dm_target_insert; dmirror has neither, and no init/strategy-facing table at all (/* XXX: add missing dm functions */, :384).
  2. Ran the authoritative build of the orphan kmod on the guest: cd /usr/src/sys/dev/disk/dm/dmirror && make β†’ exit 1, 216 lines of compiler output (build.log), including: * error: request for member 'block_offset' in something not a structure or union (the file's dm_target_crypt_config_t confusion), * error: request for member 'pdev' in something not a structure or union (:376-377), * implicit declaration of function 'dmirror_write' (:365), * plus the undeclared-identifier / placeholder errors (XXX, foo, nestbuf, next_disk, SEGNO_FROM_OFFSET …). No dm_target_dmirror.ko was produced.
  3. Confirmed no prebuilt module exists anywhere on the running system: /boot/kernel/dm_target_dmirror* and /boot/modules/dm_target_dmirror* β†’ No such file or directory (env.txt).

Result: claim CONFIRMED (evidence-pack status build_failed = the demonstration)

The module cannot be compiled, is not part of any kernel/module build, is not shipped prebuilt, and registers no dm target even in intent. There is no reachable code path from dmsetup/devfs/ioctl to any function in this file. All latent bugs in it are inert.

Impact: none (informational). The security-relevant statement is the negative one: the last un-audited dm target contributes zero attack surface.

Why no fix validation was run

The recommended fix is deletion of a directory that no build references; there is no kernel to rebuild or PoC behavior to re-test (nothing changes in any produced binary). fix_status = not_testable for that reason.

Environment

env.txt: DragonFly dfbsd 6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 UTC 2026, cc 8.3 [DragonFly], kern.osreldate 600519, hw.ncpu 6. Guest left clean (only /tmp/dmirror_build.log + a failed module obj dir in /usr/src, which was never installed; guest not dirtied otherwise).

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.

(No fix.diff for this item: documented recommendation only - see Fix above.)

Fix verification

not_testable
per-fix-DF-4973

Confirmed kernel references

Detail

Exploit chain

none - cannot compile, not wired into any build

Evidence (decisive lines)

findings/poc/DF-4973/ (build.log, env.txt, run.log)

Verdict

Dead scratch code with ZERO attack surface (proven: guest build = 216 lines of hard compiler errors exit 1, absent from dm SUBDIR, no dm_target_insert registration, no prebuilt .ko anywhere): the last unaudited dm target is a 2010 mid-implementation commit. Latent bugs catalogued so they are never revived: double vn_strategy of the SAME bio (:376-377), post-loop OOB &config->disks[i] with i==ndisks (:295), double biodone of the parent bio via both write clones (:135-137/:170-175), undefined macros and XXX/foo placeholders. Delete-the-directory fix (or write a real mirror target from scratch).