Skip to content

fix(libc): reject null secure scan destinations - #7211

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
simonbronk:codex/secure-scan-null-20261017
Oct 17, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
simonbronk:codex/secure-scan-null-20261017

Conversation

@simonbronk

Copy link
Copy Markdown
Contributor

What

sscanf_s("7", "%d", nullptr) writes through address zero and crashes inside the Windows shared libc.prx. The shared scanner also dereferences a null %n destination directly. Both paths affect sscanf_s and vsscanf_s.

Check a reached destination before writing or passing it to the host scanner. Return EOF, retain earlier successful assignments and stop before later conversions. C11 N1570, K.3.5.3.7 and K.3.5.3.14, specify the null-destination constraint and EOF result. Existing constraint-handler invocation remains unimplemented; console behavior is unverified, as recorded in libc debt.

The regression adds 20 calls across both guest ABI entry points: integer, real, string, character, scanset and count destinations; a null after an earlier assignment; no later writes; matching failure before an unreachable null; and assignment suppression. This is a synthetic crash correction: no known title is claimed to reach this path, and no implementation-percentage or performance gain is claimed.

Tested

Windows, WinLibs MinGW-w64 GCC 15.2.0r7 UCRT, Release, actual shared libc and CMake test targets, based on 66702f1cffd3646f2d674ed093fde0a85a70761f:

  • Base production with the new regression: guest_scan_count crashes with 0xc0000005, writing address zero; the other three tests pass.
  • Fixed tree 2a2e9e9357e8636fbf90ffe748d2d277445a7fcc: guest_scan_count, guest_formatting, guest_wide_formatting, guest_strings pass (4/4, 0.69 s).
  • tools/check_conventions.py --base 66702f1cffd3646f2d674ed093fde0a85a70761f and git diff --check pass.
  • The full all-target build was attempted and deliberately stopped after 83.23 s when Ninja scheduled 3,691 targets. It did not complete; this is not a full-build or full-CTest success. No Linux/macOS, game or console run.
  • tools/pr_overlap.py cannot run here because gh is unavailable; live connector searches found no open null-destination fix. feat(libc): scan 16-bit wide conversions in sscanf and vsscanf on Linux #6731 and feat(libc): scan 16-bit wide conversions in fscanf on Linux #6732 change the same scanner for wide conversions and may require reconciliation if merged first; this fix does not depend on their functionality.

AI assistance: OpenAI Codex. Evidence logs are attached below.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes
    secure-scan-null-evidence-20261017.zip

Prevent reached null conversion destinations from crashing sscanf_s and vsscanf_s. Return EOF before writes and retain earlier assignments. Add regression coverage through both guest ABI entry points.

AI-assisted: yes (OpenAI Codex). Windows WinLibs GCC 15.2 Release: production baseline crashes with the new regression; fixed shared libc passes guest_scan_count, guest_formatting, guest_wide_formatting and guest_strings (4/4). Conventions pass. Full all-target build was deliberately stopped after 83s with 3691 pending targets, not completed. No title or console run; constraint-handler invocation remains unimplemented as documented. No performance or coverage-percentage claim.
@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6916 docs/dev/debt/libc.md L41

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6044 core/libs/tests/GuestScanCount.cpp
PR 6222 docs/dev/debt/libc.md
PR 6334 docs/dev/debt/libc.md
PR 6447 core/libs/prx/libc/src/Formatting.cpp
PR 6483 core/libs/prx/libc/src/Formatting.cpp
docs/dev/debt/libc.md
PR 6731 core/libs/prx/libc/src/Formatting.cpp
docs/dev/debt/libc.md
PR 6732 core/libs/prx/libc/src/Formatting.cpp
docs/dev/debt/libc.md
PR 7081 docs/dev/debt/libc.md

@oneandonlydean
oneandonlydean merged commit cf217c5 into boykopovar:main Oct 17, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants