Unpacking a crafted image layer with a long(invalid) file name crashes the unpacking process
MediumPublished Aug 30, 2026
## Impact An attacker who can supply a container image layer for a victim to unpack — via a malicious or compromised registry, a poisoned base image, or a pull request that changes which image gets fetched — can crash the process performing the unpack with no privileges beyond getting the victim to pull or run the crafted image reference. The trigger is a single tar entry whose file, directory, or symlink name exceeds 255 UTF-8 bytes. When `ContainerizationEXT4` writes that entry into the ext4 rootfs it is building, an unchecked `UInt8` conversion of the name length traps and aborts the process. ## Details `EXT4.Formatter.writeDirEntry()` writes each directory entry's name length into the ext4 on-disk `DirectoryEntry.nameLength` field, which is a `UInt8`: ```swift // Sources/ContainerizationEXT4/EXT4+Formatter.swift nameLength: UInt8(nameData.count), // traps if nameData.count > 255 ``` Swift's `UInt8.init(_:)` traps at runtime (aborting the process) when the source value does not fit in 8 bits. The name is fully attacker-controlled and reaches this conversion with no length validation anywhere along the path. 255 bytes is the maximum length of a single path component on a rea...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| apple/container Product | < 1.3.0 | 1.3.0 |
| apple/containerization Product | < 0.41.0 | 0.41.0 |
Details and references
## Impact An attacker who can supply a container image layer for a victim to unpack — via a malicious or compromised registry, a poisoned base image, or a pull request that changes which image gets fetched — can crash the process performing the unpack with no privileges beyond getting the victim to pull or run the crafted image reference. The trigger is a single tar entry whose file, directory, or symlink name exceeds 255 UTF-8 bytes. When `ContainerizationEXT4` writes that entry into the ext4 rootfs it is building, an unchecked `UInt8` conversion of the name length traps and aborts the process. ## Details `EXT4.Formatter.writeDirEntry()` writes each directory entry's name length into the ext4 on-disk `DirectoryEntry.nameLength` field, which is a `UInt8`: ```swift // Sources/ContainerizationEXT4/EXT4+Formatter.swift nameLength: UInt8(nameData.count), // traps if nameData.count > 255 ``` Swift's `UInt8.init(_:)` traps at runtime (aborting the process) when the source value does not fit in 8 bits. The name is fully attacker-controlled and reaches this conversion with no length validation anywhere along the path. 255 bytes is the maximum length of a single path component on a real Linux filesystem, so a layer produced by tarring an actual directory tree can never contain a name this long. The tar format itself imposes no such limit, so a deliberately crafted archive (one that was never the tar of a real filesystem) can trivially contain one. ## Affected code - `EXT4.Formatter.writeDirEntry()` in `Sources/ContainerizationEXT4/EXT4+Formatter.swift` — fixed to reject a name whose UTF-8 length exceeds `UInt8.max` (255) before the conversion, throwing `EXT4.Formatter.Error.invalidName` instead of trapping. The same guard also protects the entry's `recordLength` (`UInt16`), which is derived from the name length and would only overflow with a far longer name. - Any consumer of `ContainerizationEXT4` that formats an ext4 filesystem from untrusted tar/OCI layer input reaches the same conversion. ## Mitigations 1. Upgrade to the version of `apple/containerization` containing the fix. 2. Do not unpack, pull, or run container images from untrusted sources — the registry, base image, or CI step that supplies a layer is part of the trust boundary, not just the resulting container's contents. 3. In CI/CD, avoid pulling or running an image reference that a pull request or other external input can influence on a runner shared with other jobs, since the crash disrupts every concurrent image operation on that host. ## Verifying whether you are affected Inspect a layer tar for any path component longer than 255 bytes before unpacking it: ```bash cd <content-store-path> for f in *; do tar -tf "$f" 2>/dev/null | awk -F/ -v file="$f" \ '{ for (i=1;i<=NF;i++) if (length($i) > 255) print file": "$0 }' done ``` Any output indicates an entry that would trigger the trap on an affected version. ## References Fix: apple/containerization#898, commit [cd29b8a734abd972d73d4b3eaba12af946f55f9b](https://github.com/apple/containerization/pull/898/commits/cd29b8a734abd972d73d4b3eaba12af946f55f9b)
- Severity from
- GitHub (reviewed advisory)
More Apple advisories
All Apple| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Aug 30 | Unpacking a crafted image layer with an invalid length extended-attribute name crashes the unpacking process | Medium | 0.41.0+1 more |
| Aug 30 | Loading an OCI image layout can read host files through a symlink | Medium | 0.41.0+1 more |
| Aug 30 | `RegistryClient` follows the `WWW-Authenticate` realm without validating its host or scheme | Medium | 0.41.0 |
| Aug 30 | Apple: path traversal | High | 0.41.0+1 more |
| Aug 30 | ## Impact An attacker who can choose a container or exec id may be able to... | High | 0.41.0 |
| Aug 25 | Apple iOS and iPadOS: buffer overflow | Medium5.5 | 26.6+2 more |