{
  "finding_id": "DF-4540",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Both tuner-table walks in cxm_tuner.c have no terminator element and no array-extent bound: the band-code walk at cxm_tuner.c:725-727 iterates struct cxm_tuner.band_codes[3] (cxm.h:619) whose three slots are fully initialized in all 21 cxm_tuners[] entries (no terminator slot exists), and the channel-assignment walk at cxm_tuner.c:789-791 iterates assignments[17] (cxm.h:594) which bg_air_channels fully populates (cxm_tuner.c:112-128). They stay in bounds only because unenforced data invariants hold in the current tables: freq >= min_freq (cxm_tuner.c:706-708) combined with band_codes[2].freq == min_freq for all 21 entries, and channel >= min_channel (cxm_tuner.c:784-787) combined with the last assignment channel == min_channel for all 9 channel tables -- both verified entry-by-entry in this tree. A future table edit breaking either invariant turns an unprivileged TVTUNER_SETCHNL/TVTUNER_SETFREQ ioctl (cxm.c:2824/2864) into a .rodata OOB read whose bytes are then written to the I2C bus (cxm_tuner.c:750). No input can cross the bounds with the current tables, so Info/hardening, same latent class as DF-1681. Untested: cxm needs a Conexant CX2381x PCI function absent from the audit guest (run.log); the invariant verification was static.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-4540/VERDICT.md (entry-by-entry invariant verification); cxm_tuner.c:725-727 and cxm_tuner.c:789-791 walks; cxm.h:619 band_codes[3]; cxm.h:594 assignments[17]; guards cxm_tuner.c:706-708 / cxm_tuner.c:784-787; run.log/env.txt (no vendor-14f1 function, no /dev/cxm*)",
  "kernel_refs": [
    "sys/dev/video/cxm/cxm_tuner.c:725",
    "sys/dev/video/cxm/cxm_tuner.c:789",
    "sys/dev/video/cxm/cxm_tuner.c:706",
    "sys/dev/video/cxm/cxm_tuner.c:784",
    "sys/dev/video/cxm/cxm.h:619",
    "sys/dev/video/cxm/cxm.h:594",
    "sys/dev/video/cxm/cxm.c:2824",
    "sys/dev/video/cxm/cxm.c:2864"
  ],
  "poc_changes": "authored fresh shell probe (no seed); documents trigger-hardware absence",
  "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": 4,
  "guest_dirty": 0,
  "build_cmd": "sh cxm_env_probe.sh (no compile step)",
  "run_cmd": "sh /root/cxm_env_probe.sh",
  "code_hash": "e96c7aeae7ad65be596c4dcd05455a721b54ec17d04c7825b0757058ccf5371a",
  "notes": "Pass-2 terminator/count-arithmetic leg of the cxm checklist. Everything else in the file checked and killed: msg[5] writes in-bounds with tuner_msg_len in {4,5}; N scaling checked N>32767 (cxm_tuner.c:747); afcmap[16] index masked 4 bits (cxm_tuner.c:965); system-code lookup bounded NUM_ELEMENTS(codes[6]) with post-check (cxm_tuner.c:638-643); tuner_type bounds-checked (cxm_tuner.c:557); cxm.c u32 kHz conversions wrap but are range-checked afterwards; apply_afc walk clamped by max_offset/step_size and select_frequency range checks.",
  "recommended_fix": "Bound both walks by array extent (NUM_ELEMENTS) and return -1 on exhaustion instead of relying on the min_freq/min_channel data invariants",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff adds explicit NUM_ELEMENTS bounds plus exhaustion checks to both walks in cxm_tuner.c; git apply --check clean. Runtime behaviour identical for the current tables (invariant holds), so baseline vs patched cannot differ observably even with hardware; fix_status not_testable on this guest.",
  "fix_evidence": "findings/poc/DF-4540/fix.diff"
}