Defer directory attributes without following symlinks - #823
Open
stephenlclarke wants to merge 4 commits into
Open
Defer directory attributes without following symlinks#823stephenlclarke wants to merge 4 commits into
stephenlclarke wants to merge 4 commits into
Conversation
Exercise deferred directory attributes through the archive reader and prove a replaced intermediate directory cannot redirect ownership or permission changes outside the extraction root.
Canonicalise successfully extracted directory paths before deferring metadata so archive aliases such as directory and ./directory retain last-entry-wins semantics.
Record the extracted directory identity and verify it before applying deferred metadata so a removed and recreated path cannot inherit attributes from an earlier archive entry.
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.
During testing of my Container Compose plugin, I found that archives containing read-only directories cannot be extracted by the current
mainbranch because directory attributes are applied before their children are written.This supersedes and credits @JaewonHur's work in #716. That PR correctly defers directory attributes, but its single
openatcall passes the full relative path withO_NOFOLLOW.O_NOFOLLOWprotects only the final path component, so a directory replaced by an intermediate symlink can redirect the deferredfchownandfchmodoperations outside the extraction root.Reproduction
On stock
apple/containerizationmainat50f77222964ed3d01dcb53f803ea2d511656a9dc:readonly/with mode0555andreadonly/file.txt.ArchiveReader.extractContents.readonly/file.txtbecause the parent directory was already made read-only.The regression test
archiveDirectoryPreservesReadonlySubdirectoryfails on stockmainwith:On the current #716 head at
77da467c16d8e406b38f3257188a7f1fbe078368:parent/child/.parentwith a symlink to an external directory.childdirectory's permissions are changed, demonstrating that metadata escaped the extraction root.The current #716 head also loses last-entry-wins semantics when the same directory is represented by aliases such as
directory/and./directory/.Change
O_NOFOLLOW | O_RDONLY | O_DIRECTORY.0777.Expected result
Read-only directory archives extract successfully and retain their final metadata. Deferred metadata operations remain anchored beneath the extraction root, and the last successful directory entry defines the final attributes.
Testing
make fmtmake checkswift test --filter ArchiveReaderTests: 26 tests passed in 43.917 secondsswift test --filter FileDescriptorOpsTests: 28 tests passed in 18.969 secondsmake test: 579 tests in 80 suites passed in 45.230 seconds after buildmake check: passed in 3.62 secondsmake test: passed in 121.14 seconds including the coverage rebuildmaincomparison: corrected read-only test fails as describedAll commits are signed and verified.