rustsec-2026-0429
debian_rustsec`ZipArchive::extract()` sizes the symlink-target buffer from the uncompressed size declared in the central directory record, before reading a single byte of entry data: ```rust let mut target = Vec::with_capacity(file.size() as usize); ``` Both inputs are attacker-controlled. `ZipFile::size()` returns `uncompressed_size` verbatim from the central directory, widened to a full `u64` by a ZIP64 extended-information extra field, and is never cross-checked against the compressed size, the remaining archive length, or any platform-appropriate bound for a symlink target. `ZipFile::is_symlink()` is decided entirely by the `S_IFLNK` bit of the external-attributes field. `Vec::with_capacity()` is infallible: when the reservation is refused it calls `handle_alloc_error()` and aborts the process. This is not a Rust panic. It is not caught by `catch_unwind()`, is unaffected by `panic = "unwind"`, and is not contained by running the call on a worker thread. A 112-byte archive is sufficient. One `Stored` entry flagged `S_IFLNK` with a ZIP64 field declaring `uncompressed_size = 2^62` and a zero-byte payload makes `extract()` fail with: ``` memory allocation of 4611686018427387904 bytes failed Aborted (core dumped) # exit 134 ``` The declared value only needs to exceed the host's address space, not its RAM: `Vec::with_capacity()` maps address space without touching pages, so resident memory stays flat and the abort happens on the refused reservation itself. Under a `ulimit -v` cap or a memory-constrained container the threshold drops far enough that a plain 32-bit `uncompressed_size` with no ZIP64 field suffices. Applications that extract archives from untrusted input are affected on Unix and Windows targets with default features and no special configuration: upload handling, mail-attachment processing, package and artefact ingestion, backup restore and container-image layer extraction. No confidentiality or integrity property is affected: there is no memory unsafety, no out-of-bounds access, no disclosure and no data corruption. The fix landed in [zip-rs/zip2#984](https://github.com/zip-rs/zip2/pull/984) and shipped in 9.0.0. For further details see: https://github.com/zip-rs/zip2/security/advisories/GHSA-q7v9-x93c-xqv3
- Published
- unknown
- Last Modified
- unknown
CVSS details not available.
No product information available.
No references available.
No linked vulnerabilities found.
{
"aliases": [
"CVE-2026-115909",
"GHSA-q7v9-x93c-xqv3"
],
"categories": [
"denial-of-service"
],
"crate": "zip",
"cves": [
"CVE-2026-115909"
],
"cvss": 0.0,
"database_specific": {
"severity": "high"
},
"date": "2026-10-22",
"deb_packages": [
{
"crate_name": "czkawka-cli",
"deb_name": "czkawka-cli",
"version": "12.0.2-2"
},
{
"crate_name": "czkawka-gui",
"deb_name": "czkawka-gui",
"version": "12.0.2-1"
},
{
"crate_name": "icu4x-datagen",
"deb_name": "icu4x-datagen",
"version": "2.2.0-1+b2"
},
{
"crate_name": "ognibuild",
"deb_name": "ognibuild",
"version": "0.2.21-1"
},
{
"crate_name": "xleak",
"deb_name": "xleak",
"version": "0.2.6+dfsg-1+b1"
}
],
"description": "`ZipArchive::extract()` sizes the symlink-target buffer from the uncompressed\nsize declared in the central directory record, before reading a single byte of\nentry data:\n\n```rust\nlet mut target = Vec::with_capacity(file.size() as usize);\n```\n\nBoth inputs are attacker-controlled. `ZipFile::size()` returns\n`uncompressed_size` verbatim from the central directory, widened to a full `u64`\nby a ZIP64 extended-information extra field, and is never cross-checked against\nthe compressed size, the remaining archive length, or any platform-appropriate\nbound for a symlink target. `ZipFile::is_symlink()` is decided entirely by the\n`S_IFLNK` bit of the external-attributes field.\n\n`Vec::with_capacity()` is infallible: when the reservation is refused it calls\n`handle_alloc_error()` and aborts the process. This is not a Rust panic. It is\nnot caught by `catch_unwind()`, is unaffected by `panic = \"unwind\"`, and is not\ncontained by running the call on a worker thread.\n\nA 112-byte archive is sufficient. One `Stored` entry flagged `S_IFLNK` with a\nZIP64 field declaring `uncompressed_size = 2^62` and a zero-byte payload makes\n`extract()` fail with:\n\n```\nmemory allocation of 4611686018427387904 bytes failed\nAborted (core dumped) # exit 134\n```\n\nThe declared value only needs to exceed the host's address space, not its RAM:\n`Vec::with_capacity()` maps address space without touching pages, so resident\nmemory stays flat and the abort happens on the refused reservation itself. Under\na `ulimit -v` cap or a memory-constrained container the threshold drops far\nenough that a plain 32-bit `uncompressed_size` with no ZIP64 field suffices.\n\nApplications that extract archives from untrusted input are affected on Unix and\nWindows targets with default features and no special configuration: upload\nhandling, mail-attachment processing, package and artefact ingestion, backup\nrestore and container-image layer extraction. No confidentiality or integrity\nproperty is affected: there is no memory unsafety, no out-of-bounds access, no\ndisclosure and no data corruption.\n\nThe fix landed in [zip-rs/zip2#984](https://github.com/zip-rs/zip2/pull/984) and\nshipped in 9.0.0.\n\nFor further details see: https://github.com/zip-rs/zip2/security/advisories/GHSA-q7v9-x93c-xqv3",
"id": "RUSTSEC-2026-0429",
"keywords": [
"dos",
"symlink",
"unbounded-allocation",
"extract"
],
"patched_versions": [
">=9.0.0"
],
"source": "debian_rustsec",
"title": "zip: `ZipArchive::extract` aborts the process on a symlink entry with a large declared size",
"url": "https://rustsec.debian.net/advisories/RUSTSEC-2026-0429.html"
}