Fix ACL inheritance: newly-created files reopenable by creator#10
Merged
Fix ACL inheritance: newly-created files reopenable by creator#10
Conversation
Root SDDL `(A;;FA;;;...)` lacked OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE flags, so WinFsp's kernel-side FspCreateSecurityDescriptor dropped every ACE when computing the SD for newly-created children. Children ended up with an empty DACL — interpreted as "deny everyone all access". Symptom captured via procmon while debugging the unrelated `--remote-debugging-pipe` chrome crash: chrome creates `Default\Shared Dictionary\cache` (SUCCESS) and immediately reopens the same dir (ACCESS_DENIED). Same pattern on disk_cache network temp files (`Default\Network\<guid>.tmp`). End-user symptom is Chromium's "Profile error occurred" dialog and SQLite-backed components (top_sites, login_database) failing to initialise. Fix: change SDDL to `(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;WD)` in both production adapter and integration test fixture so they stay in sync. Tests: - RootSddlTests (new): pin the canonical SDDL string and assert every ACE carries OI|CI; guards against future SDDL string typos that would silently re-introduce the bug. - AclInheritanceTests (new): mounted-FS regression test — create file/dir, reopen with Read and with raw Win32 DELETE access, assert effective ACL contains an inherited FullControl Allow ACE for Everyone. - All 33 integration tests pass (28 existing + 5 new). Documented in CLAUDE.md (WinFsp Notes) and cross-referenced from the existing leveldb postmortem §9.1. Diagnostic scripts (debug_batch.cmd/js, bisect_chrome.js, repro_chrome_min.js) gitignored — kept locally for the upcoming cache-mode crash investigation. OpenSpec change: openspec/changes/fix-acl-inheritance/ (capability default-security-descriptor). Independent of the unrelated cache-mode STATUS_BREAKPOINT bug, which remains open. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI on PR #10 timed out (15min) on TortureTests.CreateDeleteChurn (locally ~525ms, 5/5 stable). RootSddlTests had no [Collection], so xUnit ran it in parallel with the main RamDrive collection on the windows-latest runner — adding contention on a box that's already short on cores. Adding the collection attribute serializes it; test takes 30ms total so cost is nil. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hooyao
added a commit
that referenced
this pull request
May 3, 2026
… spec (#11) - Move openspec/changes/fix-acl-inheritance/ -> archive/2026-05-03-... - Sync delta spec into openspec/specs/default-security-descriptor/spec.md The implementation already shipped in PR #10 (e5bc2e1). This commit only touches openspec/ bookkeeping. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hooyao
added a commit
that referenced
this pull request
May 3, 2026
…POINT) (#12) Self-contained context dump so a fresh Claude Code session post-compaction can pick up the diagnosis without re-deriving anything. Captures: - Status of bugs #1 (shipped #9), #2 (shipped #10), and #3 (open, this doc) - Symptoms (STATUS_BREAKPOINT 0x80000003 + early death; degraded "Profile error" dialog variant) - Repro recipe (5-flag minimum, deterministic to ~80% on H:\) - 8 already-falsified hypotheses (don't redo) - Procmon evidence captured in F:\procmon_chrome2.csv (gitignored) - Four ranked working hypotheses with concrete next-test-steps - Cheat sheet of mount/repro/bisect commands - Pointers to all relevant code, specs, archived changes, and external refs (winfsp source paths) This file is meant to be read first by any session continuing this work. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OICIACE flags so newly-created files and directories inherit a usable DACLWhy
Procmon trace from H:\ during the unrelated
--remote-debugging-pipechrome crash investigation revealed: chrome createsDefault\Shared Dictionary\cache(SUCCESS) and immediately reopens the same dir →ACCESS_DENIED. Same pattern forDefault\Network\<guid>.tmpand many disk_cache temp files.Root cause:
O:BAG:BAD:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;WD)had empty ACE flags. WinFsp's kernel-sideFspCreateSecurityDescriptorwalks the parent's DACL when computing the SD for a newly-created child and copies only ACEs whose flags say "yes, inherit me". With empty flags, no ACE inherits → child gets an empty DACL → kernel interprets as "deny everyone all access".End-user symptom is Chromium's "Profile error occurred — Something went wrong when opening your profile" dialog and
top_sites_backend / login_database / disk_cachefailing to initialise.What changed
src/RamDrive.Cli/WinFspRamAdapter.csline 47: SDDL now(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;WD)with explanatory XML doctests/RamDrive.IntegrationTests/RamDriveFixture.cs: same constant updated, kept in synctests/RamDrive.IntegrationTests/RootSddlTests.cs(new): pins the SDDL string and asserts every ACE carriesOI|CI— guards against future typostests/RamDrive.IntegrationTests/AclInheritanceTests.cs(new): mounted-FS regression — create file/dir, reopen with Read and with raw Win32DELETEaccess, assert effective ACL contains inheritedFullControlfor EveryoneCLAUDE.mdWinFsp Notes section updated with new SDDL + explanationdocs/leveldb-cache-coherency-postmortem.md§9.1 cross-references this fixdebug_batch.*,bisect_chrome.js,repro_chrome_min.js) added to.gitignore— kept locally for the upcoming cache-mode crash investigationOpenSpec
openspec/changes/fix-acl-inheritance/— capabilitydefault-security-descriptor. Single requirement with 5 scenarios.Test plan
dotnet test tests/RamDrive.IntegrationTests— 33/33 pass (28 existing + 5 new), 56sGet-Aclon a freshly-created file returnsInherit=ContainerInherit, ObjectInherit FullControlfor SYSTEM/Administrators/EveryoneChange 'fix-acl-inheritance' is validKnown follow-up out of scope
The
chrome --remote-debugging-pipeSTATUS_BREAKPOINTbug surfaced during the same investigation is independent of this fix (different root cause, different procmon signature). Tracked separately; will be a future change.🤖 Generated with Claude Code