โฌข DragonFlyBSD Kernel Audit
DF-2931 / verdict.json
โ† back to finding โ†“ download raw
{
  "finding_id": "DF-2931",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "REPRODUCED end-to-end as unprivileged uid 1001: uuidgen(2) v1 UUIDs on the stock vtnet guest carry node 01:00:00:00:00:00, which is the 6 bytes at first_ether_softc+offsetof(struct arpcom,ac_enaddr)=sc+928 (vtnet_vlan_shadow[100..101]) with the multicast bit ORed โ€” NOT the interface MAC (52:54:00:12:34:56). if_getanyethermac (sys/net/if.c:3033) type-confuses if_softc with struct arpcom*; the offset is valid only for arpcom-first softcs, which vtnet/ena/oce violate, so driver-internal kernel memory (or, for a sub-928-byte softc, adjacent heap) is disclosed to any local user, jail included. KLD module uuidoff.ko proves the address arithmetic (sizeof(ifnet)=928=offsetof(ac_enaddr), sizeof(vtnet_softc)=1040) and the counter-control: for arpcom-first tap0 the same read returns its exact MAC 00:bd:e8:3f:01:00 (that MAC branch is DF-2932).",
  "exploit_chain": "",
  "evidence": [
    "run.first.log โ€” uid 1001: 4ร— v1 UUIDs, node 01:00:00:00:00:00, decoded timestamp == wall clock",
    "run.determinism.log โ€” node constant across 3 runs (fixed memory read, not read_random)",
    "module.log โ€” in-kernel proof: bytes at vtnet_softc+928 = 00:00:00:00:00:00 vs real MAC 52:54:00:12:34:56",
    "module.tap.log โ€” conforming tap0: bytes at sc+928 == exact MAC 00:bd:e8:3f:01:00 (both branches in one dump)",
    "VERDICT.md โ€” full narrative incl. run.vlan.log negative mutation attempt (VLAN filter not negotiated by QEMU)"
  ],
  "kernel_refs": [
    "sys/kern/kern_uuid.c:88",
    "sys/kern/kern_uuid.c:90",
    "sys/net/if.c:3033",
    "sys/net/if_arp.h:117",
    "sys/net/if_var.h:153",
    "sys/dev/virtual/virtio/net/if_vtnetvar.h:57",
    "sys/dev/virtual/amazon/ena/ena.h:315",
    "sys/dev/netif/oce/oce_if.h:797"
  ],
  "poc_changes": "No orchestrator seed existed (new pass-2 finding); trigger written from scratch: direct syscall(392) since libc uuidgen(3) wrapper availability was uncertain; added RFC4122 v1 timestamp decoding to simultaneously demonstrate the wall-clock disclosure; structural proof module uuidoff.ko written and iterated 4 compile rounds (device_if.h/bus_if.h generation, if_media.h/ifq_var.h/sys/bus.h includes).",
  "attempts": 4,
  "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": 480,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -o /tmp/uuidleak /tmp/uuidleak.c ; (root) cd /tmp/uuidoffmod && make",
  "run_cmd": "/tmp/uuidleak (as uid 1001); kldload /tmp/uuidoffmod/uuidoff.ko && dmesg | tail",
  "code_hash": "3da1904abf6ab697031ccb4a7b40e69c4f2100f0f04147c98d6434ee2032bd72",
  "notes": "Read-only disclosure primitive (fixed offset, no attacker-controlled index) โ€” no uid=0 route exists for this class; primary objective (2) satisfied: leak manifests, ceiling = 6 bytes of driver-softc kernel memory per call, unlimited rate, jail-reachable (sys_uuidgen has no prison check). OOB variant (softc < 928 bytes) is speculative for current in-tree violators (vtnet=1040, ena/oce larger); wrong-field leak is certain and live. Side effect: all vtnet VMs share node 01:00:00:00:00:00, voiding v1 cross-host uniqueness. Guest state reverted after run (vlan/tap destroyed, module unloaded; if_vlan.ko/if_tap.ko remain autoloaded, /tmp artifacts remain โ€” no kernel-state dirt).",
  "recommended_fix": "if_getanyethermac: copy the MAC from the link-level sockaddr (bcopy(LLADDR(sdl), node, minlen)) instead of the arpcom type-confusion cast on if_softc.",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "3-line fix.diff authored and verified git-apply-clean against sys/net/if.c; kernel rebuild validation skipped per contract (mandatory only for memory-corruption findings; this is leak-class) to keep the single-tenant guest clean.",
  "fix_evidence": "findings/poc/DF-2931/fix.diff (git apply --check: clean)"
}