You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
apt uploads: a 40 KB .deb makes the control parser hold about 0.5 GiB, so a few concurrent uploads OOM-kill the instance #815
Reading a .deb's control member (crates/formats/apt/src/deb.rs) bounds the CPU time but not the memory:
MAX_CONTROL_TAR_BYTES (deb.rs:15) lets the control member inflate to 256 MiB. Real control members are a few KB.
control_in_tar (deb.rs:156-157) reads the inflated tar with tar::Archive. The tar crate reads a GNU long-name or long-link entry, and a PAX header entry, whole into memory before it returns the next entry. So one long-name entry of up to 256 MiB is buffered.
The xz decoder (lzma_rust2::XzReader::new, deb.rs:130) has no memory limit, so a large dictionary adds its window on top.
This runs on every upload and every apt import, in publish_staged (crates/core/src/repo/hosted.rs:843), before anything is refused. Nothing limits how many publishes parse at once.
npm had the same hole: #487 fixed it for npm tarballs in 2.0.0.
Scenario
A writer of any apt repository uploads a .deb whose control.tar.xz holds one GNU L (long-name) entry of about 256 MiB of a, compressed with a large dictionary. The file is 39 KB.
The upload is refused with 400, but only after the process has held about 515 MiB.
Two or three such uploads at once go past the Helm chart's and the kustomize base's default limits.memory: 1Gi, and the pod is OOM-killed, taking every other repository on it down. The writer can repeat this at will.
Measured with forge_format_apt::deb::control_file on crafted files:
Refuse a long-name, long-link or PAX entry larger than a few KiB before it is buffered. Or walk the tar headers without the tar crate's extension handling, as the npm reader does.
Give the xz and zstd decoders a memory limit (XzReader::new_mem_limit, a bounded zstd window).
Test: the crafted xz and gzip packages are refused while holding no more than a few MiB.
New with #176 (#725). #797 covers the memory of an index generation, not of the upload parser. Found in the 2.2.0 release review.
Activity