{
  "finding_id": "DF-5808",
  "status": "reproduced",
  "reproduced": true,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "hammer_vop_mountctl() double-counts the MOUNTCTL_MOUNTFLAGS result byte count (*ap->a_res already holds part1, then *ap->a_res += part1+part2), and sys_mountctl() copyout()s the VOP-reported length from the kmalloc(buflen+1) result buffer with no clamp; MOUNTCTL_MOUNTFLAGS is exempt from the root check, so any local user over-reads part1-2 bytes of adjacent kernel heap per call (observed ret=170 from an 87-byte allocation, 3/3 deterministic; tmpfs control clean). Fixed kernel returns ret == strlen.",
  "exploit_chain": "unprivileged mountctl(mount-root-path, MOUNTCTL_MOUNTFLAGS, buflen=strlen(flags)+1) -> kernel returns 2*part1 -> sys_mountctl copyout(buf, user, 2*part1) from buflen+1 heap buffer -> repeatable OOB kernel heap disclosure sized by the mounts flag string",
  "evidence": "run.log (3x ret=170 buflen=86 + tmpfs control ret=5); run_fixed.log (ret=85 after fix); mctl2.c; fix.diff",
  "kernel_refs": [
    "sys/vfs/hammer/hammer_vnops.c:2559-2582",
    "sys/kern/vfs_syscalls.c:1281-1284",
    "sys/kern/vfs_syscalls.c:1317-1332",
    "sys/kern/vfs_default.c:1310-1317"
  ],
  "poc_changes": "trigger written from scratch (mctl.c/mctl2.c); hammer1 test mount created on guest (vn+newfs_hammer -f); NULL-buflen variant of the same probe is filed separately as DF-5811",
  "attempts": 3,
  "guest_uname": "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",
  "runtime_sec": 900,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -o /tmp/mctl2 mctl2.c",
  "run_cmd": "(root) mount -t hammer -o ro,noexec,nosuid,nodev,nosymfollow,noatime,noclusterr,noclusterw /dev/vn1 /mnt/h; (user uid1001) /tmp/mctl2 /mnt/h 86 3",
  "code_hash": "sha256 of mctl2.c recorded in SHA256SUMS",
  "notes": "adjacent heap was zero-filled in this guest state; over-read extent and determinism are structural (copyout length 2x the allocation). On hammer1-root production hosts (DF <=5.x default) this is default-config unpriv leak; hammer2 unaffected (no mountctl override).",
  "recommended_fix": "hammer_vnops.c: *ap->a_res = usedbytes (not +=); plus clamp sysmsg_result to uap->buflen in sys_mountctl before copyout (both in fix.diff, validated)",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "baseline: ret=170 from 87-byte buffer 3/3; after fix.diff + kernel rebuild + reboot: ret=85 == strlen on all runs, tmpfs and hammer both clamped (run_fixed.log)",
  "fix_evidence": "run_fixed.log; fix.diff"
}