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

cs_local/cs_disk charset names copied from mount args without NUL-termination β€” bounded kernel-stack OOB read in iconv_lookupcs strcmp

Summary

iso_args.cs_local/cs_disk are char[ICONV_CSNMAXLEN=31] filled verbatim by copyin (:197) with no termination guarantee; iso_mountfs bcopy's them to stack arrays (:288-289, :492-493) and passes them to iconv_open(), whose iconv_lookupcs()/strcmp treats them as C strings. A 31-byte non-NUL name reads past the stack array into cs_disk and adjacent stack until an accidental zero byte. cd9660 twin of DF-0854 (msdosfs); bounded stack over-read at most an strcmp oracle on adjacent stack bytes - no demonstrated disclosure path. Requires the same privileged mount path as DF-3124. Fix: force termination after the bcopy (included in the DF-3124 pack's fix.diff). [VERIFIED pass2: iconv path reached via control-mount differential but bounded stack over-read unobservable; fix compile-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3125 Β· 9 files
FileTypeDescriptionSize
fix.diff β€” 622 B view raw
README.md β€” 634 B ↓ raw
VERDICT.md β€” 1.9 KB ↓ raw
build.sh β€” 166 B view raw
run.sh β€” 222 B view raw
manifest.json β€” 721 B view raw
verdict.json β€” 1.6 KB view raw
fix.diff β€” 622 B view raw
env.txt β€” 272 B view raw

DF-3125 -- verification pack

Finding: cd9660 cs_local/cs_disk copied from mount args without NUL termination

Status: not_reproduced / impact leak / confidence likely

What was run

host: python3 ../DF-3206/craft_dotdot_iso.py img (any valid ISO)

How to reproduce

guest: kldload libiconv cd9660_iconv; mount_cd9660 -o ro -C <31-char-garbage> /dev/vn2 /mnt (fails at iconv lookup) vs -C ISO8859-1 (succeeds)

Expected

31-byte non-NUL charset: mount fails in iconv; valid charset: mount succeeds

See VERDICT.md for the full narrative and verdict.json for the persisted machine verdict. Artifacts: fix.diff.

VERDICT.md
↓ download raw

DF-3125 verification

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

Bottom line

The mount path was reached and fails cleanly: mount_cd9660 -C with a 31-byte non-NUL charset returns cd9660_iconv Invalid argument after the kernel bcopy and the iconv_open strcmp walk; a control mount with a valid charset succeeds on the same image. The over-read itself (strcmp past the 31-byte stack array until an accidental zero) is bounded and produces no externally observable state on this kernel, and the stock mount_cd9660 CLI additionally validates charset names in userland first, so the un-terminated strcmp walk requires a direct mount(2) caller. Bounded stack over-read, no demonstrated disclosure. Fix forces termination after the bcopy; compile-validated.

Kernel references

Exploit chain

(none: availability/correctness finding; no privilege chain)

Fix

cs_local/cs_disk forced NUL-terminated after the bcopy

See fix.diff in this directory (git-apply-able against the read-only sys/ tree; applied only inside the disposable verification guest).

Reproduction

build: host: python3 ../DF-3206/craft_dotdot_iso.py img (any valid ISO)

run: guest: kldload libiconv cd9660_iconv; mount_cd9660 -o ro -C <31-char-garbage> /dev/vn2 /mnt (fails at iconv lookup) vs -C ISO8859-1 (succeeds)

expected: 31-byte non-NUL charset: mount fails in iconv; valid charset: mount succeeds

Notes on the PoC (what changed vs the finding sketch)

(none)

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-3125

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log (control mount OK vs 31-byte garbage EINVAL at the iconv layer)

Verified recommended fix

cs_local/cs_disk forced NUL-terminated after the bcopy

Verdict

The mount path was reached and fails cleanly: mount_cd9660 -C with a 31-byte non-NUL charset returns cd9660_iconv Invalid argument after the kernel bcopy and the iconv_open strcmp walk; a control mount with a valid charset succeeds on the same image. The over-read itself (strcmp past the 31-byte stack array until an accidental zero) is bounded and produces no externally observable state on this kernel, and the stock mount_cd9660 CLI additionally validates charset names in userland first, so the un-terminated strcmp walk requires a direct mount(2) caller. Bounded stack over-read, no demonstrated disclosure. Fix forces termination after the bcopy; compile-validated.