Skip to content

Improve security across containerization - #898

Merged
katiewasnothere merged 8 commits into
apple:mainfrom
katiewasnothere:patches
Aug 28, 2026
Merged

Improve security across containerization #898
katiewasnothere merged 8 commits into
apple:mainfrom
katiewasnothere:patches

Conversation

@katiewasnothere

Copy link
Copy Markdown
Contributor

See commit details for more information about each individual change.

This PR fixes a number of issues:

  • validate descriptor digests before filesystem use
  • validate container and exec ids before building paths in ManagedContainer
  • Check for attribute length when consuming extended attributes in ContainerizationEXT4
  • Check directory name length when formatting an ext4 fs
  • Prevent OCI image layout load from reading host files through a symlink
  • Validate registry auth realm before exchanging credentials

jgloganand others added 8 commits August 28, 2026 10:55
- Validates every OCI descriptor digest as
`sha256:<64 lowercase hex characters>`, rejecting
path-traversal payloads like `sha256:../../etc/hosts`.
- Adds a `ParsedDigest` type (`Content/Digest.swift`)
as the one safe way to turn a digest into a path
component; `path(in:)` also enforces the result stays
under the intended root.
- Validates at two independent points:
`Descriptor.init(from:)` rejects a malformed digest
the moment a manifest/index is decoded,
and `LocalContentStore.get`/`delete` validate again
at the sink, so a bad digest can't reach the
filesystem through either route.
- Deprecates `String.trimmingDigestPrefix` since it
never validated despite its name; call sites migrate
to `validatedDigestEncoding()`.
- Bounds `LocalContent.data()`/`.decode()` to 4 MiB
(`maxDecodedSize`), matching `RegistryClient`'s
existing HTTP response cap, and closing a potential
unbounded-read memory-exhaustion path.
- Hardens the `ImageStore+Import.swift` cache-hit
`copyItem` destination path too, as defense in
depth
- Rejects negative `Descriptor.size` values at
decode time.
- Makes digest lookups spelling-agnostic
(`sha256:<hex>` or bare `<hex>`) so existing
keep-sets and comparisons aren't broken by the
new validation.
- `Image.referencedDigests()`/`getContent(digest:)`:
a malformed root digest now fails loudly (a broken
image record shouldn't silently look like "nothing
referenced" to a caller garbage-collecting against
this list). A malformed *child* entry is skipped
instead, so one invalid manifest entry doesn't
brick the whole image.
- `ImageStore` reference-manager `load()`: tolerates
one unreadable `state.json` record instead of
failing the entire store load — every other image
stays listable/pullable/deletable.
- Rejects a container/exec `id` that is empty, `.`, `..`,
or contains `/`, closing a path-traversal write/delete
primitive in `vminitd`.
- Validates at the two points where an id first
becomes a path — `ManagedContainer.init` (container id)
and `ManagedContainer.createExecSpec`/exec
creation (exec id) — so every downstream use
(bundle create/delete, exec spec create/delete)
inherits the check for free.
- Original author: Aditya Ramani <a_ramani@apple.com>
Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
Signed-off-by: Kathryn Baldauf <k_baldauf@apple.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@katiewasnothere@jglogan@realrajaryan