java-topology/whitepaper/outreach/openmsx-0001.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.5 KiB
Raw Permalink Blame History

openMSX — CWE-407 Disclosure Brief (openmsx-0001)

2026-04-13 · Patch available — awaiting upstream merge

Finding

One O(B) defect in openMSX's breakpoint checking. Patched. checkBreakPoints() linearly scans all breakpoints on every Z80 instruction to find matches for the current PC. The fix adds an address index for O(k) lookup where k = breakpoints at the current address.

The Defect

openmsx-0001 (PATCHED — MEDIUM): src/cpu/MSXCPUInterface.cc:892

// In checkBreakPoints() — fires on every Z80 CPU instruction:
std::vector<BreakPoint> bpCopy;
for (const auto& bp : breakPoints) {
    if (bp.isEnabled() && bp.getAddress() == pc) bpCopy.push_back(bp);
}

breakPoints is an unsorted std::vector<BreakPoint>. Every emulated Z80 instruction scans all B breakpoints to find matches for the current PC. The Z80 runs at 3.58 MHz. With B=20 breakpoints, this wastes ~71 million comparisons per second.

Complexity Proof

At B=20 breakpoints:

  • Defective: 20 comparisons × 3.58M instructions/sec = 71.6M comparisons/sec
  • Fixed: O(1) hash lookup per instruction (usually 0 breakpoints at any given PC)
  • ~20× op reduction per instruction. Near-zero cost on miss.

Impact

openMSX is a cycle-accurate MSX emulator. The breakpoint check fires on every emulated Z80 instruction during debugging. With multiple breakpoints set, the linear scan adds per-instruction overhead that compounds at ~3.58 million instructions per second.

The Fix

Add BreakIndex (unordered_map<uint16_t, vector<unsigned>>) for O(1) address lookup:

// Before: O(B) full scan per instruction
for (const auto& bp : breakPoints) {
    if (bp.isEnabled() && bp.getAddress() == pc) ...
}

// After: O(k) via address index, where k = breakpoints at this PC (usually 0)
if (auto it = breakIndex.find(uint16_t(pc)); it != breakIndex.end()) {
    for (unsigned bpId : it->second) { ... }
}

Patch

Fix available: defects/openmsx-0001/patch/openmsx-0001.patch

Touches MSXCPUInterface.hh and MSXCPUInterface.cc. Maintains address index on insert/remove. ~20× speedup at 20 breakpoints.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (openMSX/openMSX).
  2. Assess severity — fires on every emulated Z80 instruction during debugging.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the openMSX team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.