# DF-5755 — VERDICT

**Status: reproduced** (`certain`). Fix authored and **validated** on the
guest (`fix_status: fixed`).

## What was run

Guest `DragonFly dfbsd 6.5-DEVELOPMENT #0 … x86_64` (logs/env.txt), stock
kernel + `msdos_iconv.ko` + `libiconv.ko`. All triggers run as root for the
mount, then **drop to uid/gid 65534 (nobody)** before creating files —
`kiconv5755.c` (`setgroups/setgid/setuid` before the `open(O_CREAT)` loop).
The kernel-side primitive was additionally proven in-module by
`cesu_witness.ko`, which `iconv_open()`s the exact pair msdosfs opens
(`UTF-16BE←UTF-8`, auto-registered by `iconv_ucs_init`,
`sys/libiconv/iconv_ucs.c:377-383`) and `iconv_convchr()`s the adversarial
sequences with an 8-byte out buffer.

## Reproduced manifestations (baseline)

| evidence | file:line | observation |
|---|---|---|
| kernel converter | `sys/libiconv/iconv_ucs.c:419-477` (`utf8_to_ucs4`, no shortest-form check) | `"\xC0\xAF"` → `ret=0`, `out=00 2f`; `"\xF0\x8F\xBF\xBF"` → `ret=0`, `out=db ff df ff` (witness.log) |
| surrogate wrap | `iconv_ucs.c:215-218` + `:524-528` (`encode_surrogate` with `code<0x10000`) | the `db ff df ff` above — `code-0x10000` wraps to `0xFFFFFFFF` |
| msdosfs create | `msdosfs_conv.c:990` (`unix2winchr`→`convchr(pm_u2w)`) → `:559-579` (`unix2winfn`, unvalidated write) | nobody's `open("OV\xC0\xAFSLASH")` succeeds (run.log) |
| readdir spoof | `msdosfs_conv.c:669-713` (LFN `/` rejected) + 8.3 fallback `:243-294` (`dos2unixfn`, no filter) | dirent `name="OV/SLASH"` hex `4f 56 2f 53 4c 41 53 48`; also `"OV.DOT"` alias |
| on-disk metadata | raw image dump | LFN units `4f 00 56 00 2f 00 53 00 4c 00` (seq=0x41, attr=0x0f) and 8.3 alias `4f 56 2f 53 4c 41 53 48 20 20 20` |
| userland contrast | `logs/difftest.log` | base-system `iconv(3)`: **EILSEQ** for all overlong inputs |

## Why it matters (impact ceiling)

Not memory corruption. It is **filesystem metadata corruption + filename
spoofing** reachable by an unprivileged local user with write access to any
KICONV msdosfs mount (root mounts — identical setup bar to DF-5746):

* `/` inside on-disk names is invalid on every other FAT consumer
  (Windows/chkdsk, non-KICONV mounts fall back to the 8.3 alias — also
  corrupted here);
* readdir hands userland a filename containing `/` — tar/backup/script
  consumers interpret it as a path;
* overlong encodings alias with canonical ones (`"OV\xC0\xAEDOT"` reads back
  as `"OV.DOT"`), enabling name-hiding/spoofing games.

## Fix validation (fix.diff: shortest-form rejection in utf8_to_ucs4)

Applied to the guest's `/usr/src/sys/libiconv/iconv_ucs.c` (stacked with
DF-5756's fix), `libiconv.ko` rebuilt (`-Werror` clean,
`logs/module_build_patched.log`), loaded before `msdos_iconv.ko`. Rerun of
the **exact** baseline sequence:

| trigger | baseline | patched |
|---|---|---|
| witness `overlong-slash` | `ret=0 out=00 2f` | **`ret=-1`, out untouched** |
| witness `overlong-4b` | `ret=0 out=db ff df ff` | **`ret=-1`** |
| create `OV\xC0\xAFSLASH` etc. (nobody) | OK, `/` on disk | **`EINVAL`** |
| control create `plainok` | OK | **OK** (no regression) |
| image dump patterns (7) | all FOUND | **all absent** |
| witness `valid-slash` / `valid-pair` | `00 2f` / `f0 9f 99 88` | **identical** |

`fix_status: fixed`, `fix_baseline_reproduced: 1`, `fix_patched_reproduced: 0`
(bad behavior gone), with no regression on valid conversions.

## Notes

* Upstream FreeBSD `sys/libkern/iconv_ucs.c` (compared 2026-10-11) is
  identical in the affected function — the defect is upstream-shared.
* DF-2235 (read-before-bounds-check at `iconv_ucs.c:247-254`) is a different
  defect and is not re-reported here.
* PoC fixes vs. the seed (there was no seed; authored fresh): msdosfs
  `args.mask`/`args.dirmask` are literal mode bits, msdosfs `chmod` cannot
  add bits, `dirent` has no `d_reclen` on DF (use `_DIRENT_DIRSIZ`).

## 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.
