Skip to content
AppleGHSA-g3rx-2m58-rr63

Unpacking a crafted image layer with an invalid length extended-attribute 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 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 names...

GitHub advisory

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

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.