To be able to test vminitd/vmexec/linux specific packages on ci it'd be
a heck of a lot easier if `make` just worked. This should be the last
bit needed. The default goal currently compiles just fine after the
linux specific `make deps` is ran. Next in line would be adding decent
unit tests/actually getting ci setup for the linux bits.
- Add a `list` function that is needed for the `container registry list`
command
- Updates to `KeychainHelper` and `KeychainQuery` variable/parameter
names
- Updates to test cases
* Admit only valid OCI layout files when loading image.
- Adds `AdmissionMapper` protocol for validating archive
member paths and normalizing them to relative paths
under the extraction root directory.
- Renames `Reader.swift` to `ArchiveReader.swift` to
match type name.
- Rework `TempDir` to address `NSString.utf8String`
deprecation warning in Swift 6.2.3.
- Rework `ArchiveReader.extractContent()` to use an
`AdmissionMapper` to validate and remap archive
members before extracting.
- Adds `IdentityAdmissionWrapper` for naive extraction.
- Adds `NoSymlinkAdmissionWrapper` that only extracts
regular files and directories under the extraction root.
- Adds `OCIImageAdmissionWrapper` that only extracts
valid OCI image layout paths.
- Use `OCIImageAdmissionWrapper` for `cctl image load`
and print rejected paths.
* PR feedback.
* Adds public init() for TrustedAdmissionMapper.
* Replace AdmissionMapper with more secure extraction.
- Adds FileDescriptor.mkdirSecure() to prevent
root escapes on member pathnames, and to prevent
symlink traversal.
- Adds FileDescriptor.unlinkRecursive() to
facilitate overwrites when there are multiple
archive entries with the same member path.
- Adds FileDescriptor.validateSymlinkTargetInRoot()
to validate that extracted symlink targets do
not escape the root.
- Rewrite ArchiveReader.extractContents() to use
secure path functions.
* Remove unneeded symlink check, rename files.
* Simplify the lexical normalizer workaround.
* Reject member paths containing parent traversal components.
* Remove unused lexical normalization workaround.
* Fix leaking fds, extract absolute members as relative.
Optimize unpack a little by trying to reduce allocations in the hot
path. Today for every file we read the entire file into memory and then
pass the data blob to the ext4 writer to eventually be written to the
sparse file. Before being written to the sparse file the data is copied
*again* to a temp buffer before finally hitting write(2) in FileHandle.
This change moves things around such that we can pass an optional buffer
to the ext4 create() (so we can reuse a buffer for file writes), as well
as stops reading entire files into memory by passing the archive entry
itself (wrapped in a ReaderStream object albeit) down to the writer.
Testing with unpacking every platform for
`docker.io/jenkins/jenkins:lts` on an M1 Max:
Old Avg (5 runs): 7.43s
New Avg (5 runs): 5.31s
Creates a new Unpacker protocol that defines a single method
```
func unpack(_ image: Image, for platform: Platform, at path: URL, progress: ProgressHandler?) async throws -> Mount
```
This change also removes the `unpack(...)` method from the Image type.
Before
```
let mount = try await image.unpack(for: platform, at: path)
```
After
```
let unpacker = EXT4Unpacker(blockSizeInBytes: 2.gib())
let mount = try await unpacker.unpack(image, for: platform, at: path)
```
---------
Signed-off-by: Aditya Ramani <a_ramani@apple.com>