Skip to content

fix(shader): avoid unsafe Windows cache directory traversal - #7945

Merged
oneandonlydean merged 4 commits into
boykopovar:mainfrom
veosett:codex/windows-cache-housekeeping-safety
Oct 21, 2026
Merged

oneandonlydean merged 4 commits into
boykopovar:mainfrom
veosett:codex/windows-cache-housekeeping-safety

Conversation

@veosett

@veosett veosett commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Prevent Windows shader-cache housekeeping from entering std::filesystem::directory_iterator / remove_all with an extended (\\?\) or device (\\.\) namespace root. On supported WinLibs GCC 15.2 r7, the real housekeeping worker hangs for a prefixed 270-character root containing stale version directories. This addresses the housekeeping safety request on #7462 using its suggested skip option.

Keep directory creation and the active version's last-used update before the guard. Skip both directory-enumeration loops for namespace roots; ordinary roots retain version eviction and temporary-file cleanup. Record the eviction limit and remaining long-device stamp limitation in shader debt.

The regression launches the real cache worker in a separate process with a five-second limit and a working directory inside its own temporary sandbox. It checks stale versions with/without stamps, recent versions, stale/fresh temporaries, cached data, an updated active stamp and an unchanged outside-root tree. Windows covers ordinary, short/long extended and short device roots; Linux covers ordinary short/long roots. Cleanup uses Python's filesystem implementation, avoiding the MinGW recursive-directory path under test.

Independent of #7462, #7731 and #7933: no borrowed commits or helper dependency. Merge-tree checks with all three heads are clean. The guard also covers #7731's additional root cleanup loop when composed.

Tested

Tested source head 8d45d5c446f24fca428ac47f5ea52845e5cc708a, based on main 00d7e611e. Baseline is unchanged main production code with the test-only overlay 91853d299b58f05a0fccfbd6c2465b3535745003. The documentation follow-up removes the prebuilt-discovery caveat resolved by #8580; executable and test sources match this tested head.

  • Release builds of the affected shader-recompiler/AGC library targets and selected tests pass on Windows 11 Pro 26100, supported WinLibs GCC 15.2.0 r7; and Ubuntu 24.04 WSL, GCC 13.3. Bundled dependencies, SPIRV-Tools ON.
  • Negative control: the long extended-root case hangs 3/3 on the baseline. Each isolated child is killed at five seconds, its outside-root snapshot remains identical and temporary data is removed. The fixed case passes 3/3. The extended-long fixture is unchanged by the later device-mode correction.
  • Final Windows housekeeping modes pass 3 processes each (12 passes). Linux short/long ordinary modes pass 3 processes each on both baseline and change (6 passes per revision). Normal-root tests verify real eviction still occurs.
  • agc_shader_disk_cache, shader_cache_file_read, shader_cache_native_paths: each passes 3 processes on both OSes and both revisions (9 passes per OS/revision).
  • Real graphics/compute agc_driver_pipeline_journal: 3 passes on each revision, on AMD Radeon RX 6900 XT / Windows driver 32.0.21030.2001 and Linux lavapipe/Mesa 25.2.8 / llvmpipe LLVM 20.1.2. These are the existing GPU record/replay checks; housekeeping permutations themselves are host filesystem tests.
  • Both GPU matrices use VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1 and verbose CTest. Loader output confirms validation insertion; no missing-layer warning, VUIDs or validation errors/warnings on baseline or change. Portable layers are from Khronos main CI, source aea761f4d54b86682be4099c428dba27b6609940, manifest API 1.4.365.
  • Final selected matrix: 24 Windows passes, 18 Linux passes, no skips or CTest timeouts. Maximum observed test: Windows 4.13 s, Linux 5.43 s.
  • Conventions, whitespace and test registration pass on both OSes. The required overlap check reports no confirmed conflict; 75 stale/shared-file PR diffs were inspected separately. No duplicate housekeeping namespace guard found. Stale branches are not claimed merge-clean.

Limits: namespace-root eviction is intentionally skipped, including short aliases. Long \\.\ aliases still fail to refresh the stamp with the supported toolchain; the device regression uses a short root. Prebuilt directory discovery is covered by merged #8580. No full CTest suite, title execution, SMB end-to-end test or performance claim.

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 (review follow-up for fix(shader): support long Windows cache file paths #7462)
  • Unblocks: none
  • GPUs tested: AMD Radeon RX 6900 XT, driver 32.0.21030.2001, Windows 11 Pro 26100; lavapipe/Mesa 25.2.8, llvmpipe LLVM 20.1.2, Ubuntu 24.04 WSL
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 19, 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 6604 docs/dev/debt/shader.md L27
PR 6879 docs/dev/debt/shader.md L27

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 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5609 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/ShaderDiskCache.cpp
PR 5941 docs/dev/debt/shader.md
PR 6009 docs/dev/debt/shader.md
PR 6011 docs/dev/debt/shader.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6235 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6488 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6539 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6924 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/ShaderDiskCache.cpp
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6970 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 6977 core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 7410 docs/dev/debt/shader.md
PR 7484 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 7505 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7550 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
PR 7677 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7684 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 7689 core/shader/recompiler/ShaderDiskCache.cpp
PR 7800 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7831 core/shader/recompiler/ShaderDiskCache.cpp
PR 8014 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8077 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 8246 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8489 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 8552 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8564 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt

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

Labels

agc libSceAgc* build docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants