{
  "finding_id": "DF-2622",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "CONFIRMED live on the stock kernel: both mount(2) inputs that make label==devstr (volume string exactly \"@\" and volume string \"\") reach vfsops.c:1020 and execute slice = label[-1] = devstr[-1], reading one byte BELOW the 80-byte devstr[MNAMELEN] stack array. The byte's class leaks to the console through the label choice printed at :1037 ('a'->BOOT, 'd'->ROOT, else->DATA, ~1.6 bits) before the mount fails ENOENT in hammer2_init_devvp(\"\"). The instrumented kernel printed the actual byte: 0x00 on one call and 0xff on the immediately following call - live stack garbage below the array varying with stack history, proving the read is out of bounds of any valid object. Honest ceiling: no memory content reaches userland, the console is the same privileged context that issued the mount, and no corruption occurs - Low severity as filed is correct; the defect itself (unconditional label[-1]) is real and trivially fixed. fix.diff guards with (label > devstr) and defaults slice=0; on kernel #2 the '@'/'' triggers show identical user-visible behavior (label=DATA, ENOENT) with devstr[-1] never dereferenced, and in-bounds cases (root mount 'vbd0s1d'->ROOT, '/dev/vn0@'->DATA) are unchanged.",
  "exploit_chain": "",
  "evidence": [
    "run_stock.log - './mnt2622 @ /mnt/h2x' and './mnt2622 \"\" /mnt/h2x' both FAILED errno=2 while the console printed hammer2_mount: device=\"\" label=\"DATA\" (the OOB-read-dependent label decision)",
    "console_excerpts.txt [B] - instrumented kernel: DF2622: label==devstr=1 devstr[-1]=00 on one call, devstr[-1]=ff on the next (varying stale stack byte, both labeled OUT-OF-BOUNDS by the instrumentation)",
    "console_excerpts.txt [B] - in-bounds references: boot root mount devstr=\"vbd0s1d\" label[-1]='d' -> ROOT; \"/dev/vn0@\" -> label[-1]='0' -> DATA",
    "console_excerpts.txt [C] - fix kernel #2: same triggers, label=DATA, no dereference below devstr",
    "mnt2622.c - direct mount(2) with attacker-controlled hammer2_mount_info.volume"
  ],
  "kernel_refs": [
    "sys/vfs/hammer2/hammer2_vfsops.c:1007-1031",
    "sys/vfs/hammer2/hammer2_vfsops.c:989",
    "sys/vfs/hammer2/hammer2_vfsops.c:1037"
  ],
  "poc_changes": "No seed code. Wrote a direct mount(2) trigger (struct hammer2_mount_info per hammer2_mount.h) because the userland mount(8) path was unnecessary; confirmed copyinstr at :989 accepts both \"@\" and \"\" and the :1008 guard does not reject them. Captured console via the QEMU serial log.",
  "attempts": 1,
  "guest_uname": "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",
  "runtime_sec": 300,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o mnt2622 mnt2622.c (guest)",
  "run_cmd": "./mnt2622 '@' /mnt/h2x ; ./mnt2622 '' /mnt/h2x ; dmesg | tail (console oracle)",
  "code_hash": "mnt2622.c sha256 74bfb8e08f00bd8ed418439da7697c19579303768dcb77e73fc53a188a482851; run_2622.sh sha256 23d26d0a12623991639da3c92a895ceede18d0a855bb419a3dc041bb6701b6d6",
  "notes": "Reachable only with mount privilege (root, or a user with the fs mount cap when vfs.usermount=1); the oracle output (console kprintf) is normally visible only in that same privileged context, hence impact=none rather than leak. The byte at devstr[-1] on this build sits below the array in unused/red-zone stack; it changed between two back-to-back mount(2) calls (0x00 -> 0xff).",
  "recommended_fix": "In hammer2_vfs_mount only read label[-1] when label > devstr; otherwise default the slice to 0 (empty device string has no partition letter).",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #2: Sat Aug 29 00:17:00 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff (label > devstr guard, slice=0 default) included in the combined kernel #2 build (fix_build.log). Re-running the exact triggers: '@' and '' mounts fail ENOENT exactly as before and the console still shows device=\"\" label=\"DATA\" (the sane default), with devstr[-1] now never dereferenced; the in-bounds slice-letter feature is preserved (boot root mount still selects ROOT via 'd'). No OOB read is possible on the patched path by construction.",
  "fix_evidence": [
    "fix.diff",
    "console_excerpts.txt [C]",
    "fix_build.log / fix_install.log"
  ]
}
