AI and data stack advisories

Severe, 6 weeks1496Projects326

1496 severe, 6 weeks · 326 projects

AppleGHSA-g3rx-2m58-rr63

Unpacking a crafted image layer with an invalid length extended-attribute name crashes the unpacking process

Apple

Published Aug 30, 2026

Medium
Fix: upgrade to 0.41.0 or later (2 fixed versions below)
GitHub advisory

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 carrying an extended-attribute (xattr) name longer than 255 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.FileXattrsState.write() writes each xattr entry's name length into a single on-disk byte via an unchecked UInt8 conversion:

```swift

// Sources/ContainerizationEXT4/EXT4+Xattrs.swift

out.append(UInt8(attribute.name.count)) // traps if attribute.name.count > 255

`

Swift's plain UInt8.init(_:) traps at runtime (aborting the process) when the source value does not fit in 8 bits.

attribute.name is the xattr name taken from a tar entry's PAX extended header (SCHILY.xattr.*) with no length limit, after ExtendedAttribute.compressName() strips a known namespace prefix, it flows into EXT4.Formatter.create(...), which calls state.writeInlineAttributes(...) / state.writeBlockAttributes(...), both reaching the conversion above with no length...

Affected versions

PackageAffectedFixed in
apple/container
Product
< 1.3.01.3.0
apple/containerization
Product
< 0.41.00.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 carrying an extended-attribute (xattr) name longer than 255 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.FileXattrsState.write()` writes each xattr entry's name length into a single on-disk byte via an unchecked `UInt8` conversion: ```swift // Sources/ContainerizationEXT4/EXT4+Xattrs.swift out.append(UInt8(attribute.name.count)) // traps if attribute.name.count > 255 ``` Swift's plain `UInt8.init(_:)` traps at runtime (aborting the process) when the source value does not fit in 8 bits. `attribute.name` is the xattr name taken from a tar entry's PAX extended header (`SCHILY.xattr.*`) with no length limit, after `ExtendedAttribute.compressName()` strips a known namespace prefix, it flows into `EXT4.Formatter.create(...)`, which calls `state.writeInlineAttributes(...)` / `state.writeBlockAttributes(...)`, both reaching the conversion above with no length validation along the path. 255 bytes is the maximum length of a single xattr name 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 contain one. ## Affected code - `EXT4.FileXattrsState.write()` in `Sources/ContainerizationEXT4/EXT4+Xattrs.swift` — fixed to reject a name whose length is `0` or exceeds `UInt8.max` (255), throwing `EXT4.FileXattrsState.Error.invalidXAttr` instead of trapping. - The reachable callers `writeInlineAttributes(...)` / `writeBlockAttributes(...)`, invoked from `EXT4.Formatter.create(...)`. 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 xattr name that would overflow the single length byte before unpacking it. The only reliable check enumerates xattrs through the same library the unpacker uses (`ContainerizationArchive`, a libarchive wrapper) and applies the same prefix compression (`EXT4.ExtendedAttribute.compressName`) that feeds the conversion. This catches both PAX xattr encodings libarchive recognizes (`SCHILY.xattr.` and `LIBARCHIVE.xattr.`, the latter with URL-encoded names) and measures the exact post-compression length that the vulnerable `UInt8(...)` sees. A plain `tarfile`/`tar` scan for long `SCHILY.xattr.` keys is only an approximation — it misses `LIBARCHIVE.xattr.`-encoded names and measures the raw, pre-compression length. Create a Swift project directory and populate it with the following files: ```swift // Sources/main.swift import Foundation import ContainerizationArchive import ContainerizationEXT4 for path in CommandLine.arguments.dropFirst() { let reader = try ArchiveReader(file: URL(fileURLWithPath: path)) // auto-detects gzip/zstd/etc. for (entry, _) in reader { for (rawName, _) in

Severity from
GitHub (reviewed advisory)

More Apple advisories

All Apple