Skip to content

Image-layer extraction restores setuid/setgid and arbitrary ownership on the host (fchmod/fchown after the create-time 0o777 mask)

Moderate
jglogan published GHSA-5h49-6pr7-9mv4 Aug 11, 2026

Package

swift github.com/apple/container (Swift)

Affected versions

< 1.2.0

Patched versions

1.2.0
swift github.com/apple/containerization (Swift)
< 0.40.0
0.40.0

Description

Impact

The author or publisher of any container image, or any process running inside a container, can plant a file whose mode carries the setuid, setgid, or sticky bit. When a host user copies a directory out of that container with container cp <id>:/dir /host/path, the file is written to the host filesystem with those bits intact and owned by the host user running the apiserver, not root. A second, less-privileged local actor that can read and execute that file — another user on a shared Mac, or a sandboxed app granted access to the path — inherits the first user's effective UID.

The extractor masked high mode bits when creating each file, but a subsequent fchmod re-applied the unmasked mode. Because the extractor is unprivileged, its attempt to set ownership to root fails and the bit lands on a file owned by the operator.

Privilege escalation is not self-completing: it requires a second actor to execute the file.

Not affected: single-file copies out (a separate code path creates the file 0644 and never chmods); copies into a container; and container image layer unpacking, where content is written into a disk image rather than the host filesystem.

Mitigations

Upgrade to container 1.2.0 or containerization 0.40.0 or later. If you cannot upgrade immediately, any of the following reduce or eliminate exposure:

  1. Copy individual files instead of directories from untrusted containers. Single-file copies are not affected.
  2. Clear the bits after every directory copy out: chmod -R a-s <destination>. Wrap it so it isn't forgotten:
    ccp() { command container cp "$@" && chmod -R a-s "${@[-1]}"; }
  3. Copy onto a filesystem that won't honor the bits — mount the destination nosuid, or use a scratch disk image attached with hdiutil attach -owners off.
  4. Deny other actors access. The bit is only exploitable if someone else can read and execute the file. Copy into a 0700 directory under your own home rather than /tmp or any shared or world-readable location.
  5. Sanitize at host boundaries. Before moving copied-out trees to Linux hosts, build runners, or NFS exports, run chmod -R a-s, or extract with tar --no-same-permissions.
  6. Only run and copy from images you trust — the attacker-controlled input is container content.

A restrictive umask does not mitigate this. fchmod(2) is not filtered by umask, so the bits are applied regardless.

Verifying whether you are affected

Check for artifacts already on disk. Upgrading does not clean up files created by earlier versions. The signature is a setuid or setgid file owned by an ordinary user rather than root:

find ~/Downloads ~/Desktop /tmp -user "$(id -u)" \( -perm -4000 -o -perm -2000 \) -type f -ls 2>/dev/null

Clear anything you did not deliberately create with chmod a-s. Extend the same sweep to any build runner or NFS export that received copied-out directories — that is where the bits are fully honored and residual risk is highest.

References

Severity

Moderate

CVE ID

No known CVE

Weaknesses

No CWEs

Credits