D299 - Finding which answer the guest dereferenced, rather than reasoning about it
decided · 2026-08-26 · PPSA21564 dies
writing to 0x7fff0001
Turning the loop on all five commercial titles produced one clean
result and four refusals, and the refusals are more useful than the
success. PPSA21564 faults at
write to 0x7fff0001 - which is
GuestError::Unimplemented, one of our own placeholder
codes, being used as an address. The guest asked something, got "not
handled", and dereferenced it.
D125 already states what the fix is: "for anything the caller dereferences, an error code is a wild pointer - so those answer zero, which is what a caller already tests for." And the inference is measured rather than assumed: a guest treating an answer as an address is the evidence that the function returns something dereferenceable. Nothing has to be recalled about what the function is for.
What is missing is which function. The report
produces two ErrorUsedAsPointer findings and neither names
the producer: one names the call that received the placeholder,
the other names the import the fault happened inside. The action says so
out loud - "find what answered with that code just before" -
which is an instruction to a person to go looking.
Looking is a sweep. Every import the run called that nothing implements is a candidate; force each to answer zero in turn and see which one stops the fault being a placeholder dereference. The oracle is crisp and needs no judgement: the faulting address stops being one of our own codes, or it does not.
Two things make this cheaper than it sounds. The candidates are already in the trace, so the list costs nothing to build. And a boot is about a tenth of a second, so a title with a dozen unimplemented imports is under two seconds - the same measurement that made every other sweep here exhaustive rather than ranked (D231).
And its patch is auto-keepable, which none of the others
are. It changes what a function answers and writes no
memory, so Evidence::Further is sufficient by the rule set
in D296 - a wrong answer that buys progress shows up as a wall that
moved, where a wrong write does not show up until something unrelated
breaks.