* fix(elf): bound compressed ELF section reads `debug/elf` takes a section's decompressed size from that section's own compression header, and a highly compressible stream really does deliver the bytes that header promises, so `internal/saferio` does not help: it faithfully allocates every one of them. A 2MB input file drives `elf.NewFile` to allocate over 10GB and return no error, which is a fatal OOM rather than a recoverable panic. Which sections get read is not up to the caller. `elf.NewFile` always reads the section-name string table, and `File.Symbols` reads `.symtab` plus whatever section its `Link` field points at, so being selective about sections is not enough to avoid it. New `elfutil.NewFile` is a drop-in for `elf.NewFile` that rejects a declared decompressed size over 128MB. Every production call site goes through it, and a ruleguard rule keeps the next one from going direct. The check runs in two parts, since `debug/elf` expands sections at two different times. The section-name string table is the only one `elf.NewFile` expands itself, so it is checked against the raw bytes before the call; everything else is expanded lazily by `(*Section).Open` and is checked after the parse, where names, types and decompressed sizes are already resolved. Only the sections syft can actually reach are bounded, which keeps the guard from costing real binaries. DWARF is excluded since nothing calls `File.DWARF`, so a large compressed `.debug_info` no longer skips the whole file, and sections `debug/elf` will not decompress anyway (`SHF_ALLOC`, `SHT_NOBITS`) are left alone. The legacy `.zdebug` form is matched on the section name the way `debug/elf` gates it rather than on the `ZLIB` magic, so an ordinary section starting with those four bytes is not mistaken for a compressed one. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix(elf): gate debug/buildinfo behind the compressed-section check `debug/buildinfo.Read` opens ELF files with `debug/elf` itself, and `elf.NewFile` expands the section-name string table as it parses, so the golang cataloger was still reachable by the same bomb `elfutil` exists to stop. A 261KB fixture drove 1.4GB of allocation through `buildinfo.Read` and returned no error. `elfutil.CheckSectionNameTable` is now exported for that case: callers that cannot use `NewFile` because the `debug/elf` call is made for them inside another package. Both `buildinfo.Read` call sites go through it, including the UPX-decompressed one. Also corrects claims that did not hold up: - the package doc's 2MB-to-10GB figure is not reachable with zlib (~1000:1), so it now carries the measured 510KB-to-2.6GB, and names zstd's 32767:1 since that is what makes the small inputs possible - `.go.buildinfo` was listed as a hot-path section elfutil covers, but it is read through `debug/buildinfo` and never touches `Section.Data` - the graalvm comment claimed routing size rejections away from `*elf.FormatError` improved reporting; both branches are skipped by the caller and only the FormatError branch logs, so it did the opposite - `sharedLibraries` logged short and truncated files as real ELF failures, since `debug/elf` returns a bare `io.EOF` rather than an `*elf.FormatError` for those Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * added test comments around the negative cases Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * additional tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * better decomposition and comments Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * use a less brittle constant for error detection Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Syft
A CLI tool and Go library for generating a Software Bill of Materials (SBOM) from container images and filesystems. Exceptional for vulnerability detection when used with a scanner like Grype.
Features
- Generates SBOMs for container images, filesystems, archives (see the docs for a full list of supported scan targets)
- Supports dozens of packaging ecosystems (e.g. Alpine (apk), Debian (dpkg), RPM, Go, Python, Java, JavaScript, Ruby, Rust, PHP, .NET, and many more)
- Supports OCI, Docker, Singularity, and more image formats
- Works seamlessly with Grype for vulnerability scanning
- Multiple output formats (CycloneDX, SPDX, Syft JSON, and more) including the ability to convert between SBOM formats
- Create signed SBOM attestations using the in-toto specification
Tip
New to Syft? Check out the Getting Started guide for a walkthrough!
Installation
The quickest way to get up and going:
curl -sSfL https://get.anchore.io/syft | sudo sh -s -- -b /usr/local/bin
Tip
See Installation docs for more ways to get Syft, including Homebrew, Docker, Scoop, Chocolatey, Nix, and more!
The basics
See the packages within a container image or directory:
# container image
syft alpine:latest
# directory
syft ./my-project
To get an SBOM, specify one or more output formats:
# SBOM to stdout
syft <image> -o cyclonedx-json
# Multiple SBOMs to files
syft <image> -o spdx-json=./spdx.json -o cyclonedx-json=./cdx.json
Tip
Check out the Getting Started guide to explore all of the capabilities and features.
Want to know all of the ins-and-outs of Syft? Check out the CLI docs, configuration docs, and JSON schema.
Contributing
We encourage users to help make these tools better by submitting issues when you find a bug or want a new feature. Check out our contributing overview and developer-specific documentation if you are interested in providing code contributions.
Syft development is sponsored by Anchore, and is released under the Apache-2.0 License.
The Syft logo by Anchore is licensed under CC BY 4.0
For commercial support options with Syft or Grype, please contact Anchore.
Come talk to us!
The Syft Team holds regular community meetings online. All are welcome to join to bring topics for discussion.
- Check the calendar for the next meeting date.
- Add items to the agenda (join this group for write access to the agenda)
- See you there!
