⬢ DragonFlyBSD Kernel Audit
DF-5599 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5599",
  "status": "not_reproduced",
  "reproduced": false,
  "impact": "none",
  "confidence": "certain",
  "verdict": "ichsmb_pci_attach() requests 16 I/O-port bytes first with a 32-byte fallback (ichsmb_pci.c:233-237) although every device ID in the table from ICH5 (0x24d3) onward has an SMBus BAR that decodes 32 bytes (64 under QEMUs ICH9 model, measured). On a firmware-programmed BAR the default-window request is silently upgraded to the resource-list entrys full count (subr_bus.c:2697-2700, count = ulmax(count, rle->count)) -- live-measured on the q35 rig: requested 16, rman allocated 0x700-0x73f (64 bytes), so no under-claim manifests there. The hazard lives on the BIOS-unprogrammed/disabled-BAR path: pci_add_map deliberately records no rl entry when base==0 or the BIOS wrote all-1s (pci.c:2598-2610), so pci_alloc_resource routes the request to pci_alloc_map with count=16 (pci.c:4058-4061) and reserves only 16 bytes while the fixed hardware decode still covers the full 32/64-byte window -- the tail bytes are then decoded-by-SMBus but owned-by-nobody in the global I/O rman, and any later allocation landing there aliases into SMBus register space. Root/config-triggered, no in-tree claimant on the standard rig, not exercisable without changing firmware behavior: Info hardening. fix.diff swaps the request order to 32-first/16-fallback so the pci_alloc_map path always reserves the full window on ICH5+.",
  "exploit_chain": "",
  "evidence": "run.log (pciconf -lb: bar [20] = type I/O Port, range 32, base 0x700, size 64, enabled vs devinfo -r allocation 0x700-0x73f = 64 bytes for a 16-byte request); VERDICT.md (both code paths cited); run.sh",
  "kernel_refs": [
    "sys/bus/smbus/ichsmb/ichsmb_pci.c:233",
    "sys/bus/smbus/ichsmb/ichsmb_pci.c:236",
    "sys/bus/pci/pci.c:2551",
    "sys/bus/pci/pci.c:2598",
    "sys/bus/pci/pci.c:4058",
    "sys/kern/subr_bus.c:2697"
  ],
  "poc_changes": "Measurement-only pack derived from the same rig boot; no seed PoC existed. The initially drafted under-claim always happens framing was corrected after live measurement showed the subr_bus.c:2699 ulmax upgrade rescues the programmed-BAR case -- the finding was narrowed to the pci_alloc_map path, which is the honest residual.",
  "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": 120,
  "guest_dirty": 0,
  "build_cmd": "(none - measurement only)",
  "run_cmd": "sh run.sh",
  "code_hash": "",
  "notes": "Checklist item (d) of the family sweep. The 16-first order is inherited from ancient FreeBSD; requesting the largest documented decode first (32) with 16 as fallback closes the pci_alloc_map under-claim for all ICH5+ IDs while preserving pre-ICH5 16-byte BARs. No security impact demonstrated; filed as Info hardening.",
  "recommended_fix": "In ichsmb_pci_attach(), request 32 I/O bytes first and fall back to 16, so the firmware-unprogrammed path (pci_alloc_map) reserves the full ICH5+ decode window instead of leaving half of it decoded-but-unowned.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "No reproducible bad behavior on the standard rig (the programmed-BAR path is auto-upgraded and the unprogrammed path needs firmware changes to reach); fix.diff is a two-line order swap supplied for review.",
  "fix_evidence": "fix.diff; run.log shows the measured upgrade that motivates keeping the request aligned with the rl count"
}