Commit Graph
40 Commits
Author SHA1 Message Date
Alex Goodman 1d25dfe4da fix(golang): bound allocations from UPX-packed binary headers (#5195)
* fix(golang): bound UPX decompression by what the input can justify

A UPX block's `sz_unc` was passed straight to `make([]byte, n)`, so four bytes of
attacker input spanned the full uint32 range. A ~300KB file could drive multi-GB
resident memory, which Go reports as a fatal runtime OOM that no `recover` on this
path can contain. Syft parses binaries out of arbitrary images, so that is reachable
from any scan.

Two bounds do the work, and UPX's own invariants make them exact:

- all blocks together reconstruct `p_filesize`, so a running remainder caps the sum.
  Bounding only per-block would leave the total at (block count x original size), so
  the remainder is the part that actually closes it
- `p_filesize` sizes the output buffer, so it is capped both absolutely and against
  the size of the file on disk. The absolute cap alone left a ~60 byte header able to
  claim 500MB; the ratio alone cannot work either, since LZMA encodes a run of N
  equal bytes in O(log N) and a `go:embed` of 120MB of zeros legitimately packs 209x

The output buffer is also allocated on the first block that survives validation
rather than up front, so a header claiming a large size with nothing decodable behind
it costs nothing.

Alongside that, several ways the block loop could be steered off its own buffer:

- `parseELFPTLoadOffsets` bounds-checked program headers with `phStart+phentsize >
  len(buf)`, which overflows for a `p_offset` near 2^64 and lets an out-of-range entry
  through into a slice index. Switched to the subtraction form, and a `phentsize`
  shorter than an ELF64 program header is rejected since the reads use fixed offsets
- block placement had the same overflow shape, and on failure it skipped the copy and
  fell through. `outputOffset` derives from the rejected offset, so a `p_offset` at the
  uint64 ceiling wrapped it to 0 and the next block landed on the reconstructed ELF
  header, still returning success. Out-of-range placement now ends the block chain,
  keeping the blocks already placed since those often carry `.go.buildinfo`
- the UPX 2-byte LZMA header carries `lc`/`lp` as nibbles and `pb` as three bits, so
  they can hold values LZMA does not permit. Folded into the props byte they wrap
  (`lc=15, lp=15, pb=7` gives 465, which truncates to 209) and the stream mis-decodes
  instead of failing
- blocks decode directly into a slice of the output buffer instead of a per-block
  buffer that is then copied, so one block no longer doubles peak memory
- the block count is capped: the size budget alone still allows millions of 12-byte
  blocks, each spinning up an LZMA reader

Verified against the `image-small-upx` fixture, a real `upx --best --lzma` binary:
four blocks, max `sz_unc` equal to `p_blocksize` exactly, blocks summing to 0.68 of
`p_filesize`, and a 1.96x expansion against the packed file, so every bound holds with
headroom on genuine output.

Note `p_blocksize` is deliberately not used as a ceiling on `sz_unc`. It adds nothing
the remainder does not already cover, and real output sits at exactly `p_blocksize`,
so it would run with zero headroom against a value the format does not promise.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix(golang): report UPX binaries we cannot unpack as unknowns

A packed Go binary we fail to unpack means its packages are silently missing from the
SBOM. `getBuildInfo` checked the decompression error for nil and discarded it, so a
rejected file surfaced only the original `buildinfo.Read` error, and that one is
deliberately silenced because it is usually just "not a Go binary".

`decompressUPX` now marks the cases worth reporting with `errUPXDecompress`: it got
past the header and the method dispatch and still could not unpack the file. Everything
else stays quiet, which matters more than it sounds. `upx` defaults to NRV2B unless
`--lzma` is passed and only LZMA is implemented here, so treating any decompression
failure as reportable would attach a golang-cataloger unknown to every packed non-Go
binary in an image. Making the reportable case opt in rather than the quiet case a
growing list also means a guard added later is silent by default.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor(golang): drop the vendored xcoff parser

The only thing the golang cataloger read from it was `TargetMachine`, which is the same
two magic bytes `getGOARCHFromBin` had already matched on to dispatch there. So a full
XCOFF walk (string table, symbol table, every relocation table) ran to recover a value
that was already in hand.

`getGOARCHFromBin` reads those two bytes directly now. That is also strictly more
correct: `xcoff.NewFile` bailed with "no symbol table" when `symptr == 0`, so a stripped
XCOFF binary reported no arch at all.

Fixtures move to `testdata/xcoff/`, since they are no longer a package's own testdata.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* feat(internal/file): report a reader's real size behind one helper

Bounds get written as "does this claim exceed what the reader actually holds", and the
subtlety is that a reader's own answer cannot be trusted: an `io.SectionReader` reports
the nominal length it was built with, so one constructed with `1<<63-1` will happily
claim to hold 8EB. Confirming the last byte is readable is what separates a real size
from a nominal one.

Returns `(int64, bool)` rather than a bare size, since there are five ways to not know
and collapsing them to 0 makes every caller reinvent "0 means stop bounding".

The doc also names the wrapper trap: a type embedding `io.ReaderAt` as an interface
promotes only `ReadAt`, so it answers no size at all however large the reader beneath it
is, and a bound written against it silently does nothing.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix(golang): bound every section a reader can expand, not just the name table

`CheckSectionNameTable` bounds the one section `elf.NewFile` expands while parsing, which
is enough for a caller that only parses. It is not enough for one that goes on to read
sections: those are expanded lazily, so a 260KB ELF declaring a compressed `.symtab`
drove 1.3GB of allocation through `goversion`, which opens the file with `debug/elf`
inside its own package and cannot be routed through `elfutil.NewFile`.

`CheckAllSections` is that gate, and is deliberately named as the superset so the
relationship to the narrow one is structural rather than documented.

Also exports `ErrDeclaredSizeExceeded`. A refusal here costs the SBOM a package, so
callers report it as an unknown, and matching on an error string to decide that is not
something to build a reporting policy on.

A ruleguard rule now flags `buildinfo.Read` and `version.ReadExeFromReader` outside
`scan_binary.go`. Both open `debug/elf` internally and are only bounded there by the
wrappers that gate the reader first, which the existing rule on `elf.NewFile` could not
see through.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* feat(internal/spillbuf): sparse offset-addressed buffer that spills to disk

For output that arrives out of order, at offsets the input itself declares: a
decompressor placing extents, an archive rebuilding a file from chunks. A plain `[]byte`
cannot do that without either pre-sizing to a length the input claims or growing to the
furthest offset it names, and both hand a hostile input an allocation knob.

The load-bearing property is that it reports only what it actually stored. `Size` is the
contiguous run written from offset zero and a read past it is `io.EOF`, never the zeros
an unwritten region would hand back for free. Sparse storage serving holes as real
content is what lets a write offset stand in for output nothing produced, so anything
sizing an allocation against this reader (`saferio` in `debug/elf` does exactly that)
stays bounded by work actually done.

`FirstGap` answers where the next write fits, so callers filling holes do not need the
extent bookkeeping and cannot re-derive that rule wrongly, and it only reports gaps
lying entirely inside `[0, within)`. The extent type is unexported for the same reason.

The rest of the contract worth stating: reads and writes after `Close` fail with
`os.ErrClosed` rather than looking like an empty buffer, and a write that fails leaves
the buffer unchanged.

Memory is bounded by the limit rather than by how much is written: filling 1MB and
filling 64MB cost about the same. What lands on disk past that limit is the caller's
bound to set, not this package's. Growth is geometric and capped, because sizing the
tier to exactly what each write needs is quadratic once a caller streams through it in
small chunks.

The golang cataloger is the only consumer today, and nothing else in the tree has this
shape.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix(golang): rebuild UPX binaries through spillbuf and read the reconstruction everywhere

Two amplification paths were still reachable. A 128 byte input allocated 16MB by
trusting `sz_cpr` before weighing it against the bytes the file actually holds, and the
reconstruction was assembled in a `[]byte` sized from the header's declared original
size, so a 301KB input allocated 300MB.

The reconstruction is a `spillbuf.Buffer` now, which is what makes the second one go
away: blocks are placed at the offsets the file declares, nothing is pre-sized from a
claim, and the reader's length is the contiguous run actually rebuilt. That last part is
the invariant everything downstream leans on. A reader reporting the declared size would
serve the holes between placed blocks as zeros it never stored, and a 64 byte block
parked at `p_filesize-64` then made a 300KB input hand out a 64MB reader: measured, that
drove 269MB through `getBuildInfo` and returned nothing, silently.

Placement and storage are separate concerns. `upx.go` places blocks at the offsets the
file declares and asks the buffer how much was rebuilt and where the next gap is; it
knows nothing about temp files or memory limits.

The remaining bounds are ratios against the input wherever they can be, since an
absolute ceiling only ever drops a large legitimate binary. The one absolute left is on
`p_filesize`, because padding an input is nearly free, and the LZMA dictionary is paid
for in its own block's `sz_cpr`.

Interface change: `scanFile` takes a context and hands back the reconstruction for each
binary that turned out to be packed, and the caller owns it. Everything after the build
info read (crypto settings, arch, symbols, the version scan) reads it, so a packed
binary no longer reports its packages with no symbols at all.

Also narrows what gets reported. This cataloger runs on every executable in an image, so
reporting every `getBuildInfo` error attached an unknown to every corrupt ELF, odd PE and
non-Go Mach-O slice in it. Now only four gaps, the ones that cost the SBOM something
syft could have had: a packed file we could not decode (`errUPXDecompress`), a header
the size bounds refused (`errUPXSizeRefused`), a reconstruction that came up short
(`errUPXPartial`), and an ELF expansion `elfutil` declined
(`ErrDeclaredSizeExceeded`). An unimplemented UPX method stays quiet on purpose: `upx`
defaults to NRV2B and only LZMA is implemented here, so reporting it would attach an
unknown to most packed non-Go binaries in an image.

That filtering is a new pattern. No other cataloger picks which of its errors become
unknowns, and the reason this one does is that it runs on every executable in an image
rather than on files a glob already selected.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* chore: ignore local spec/ planning notes

`/specs` was already ignored; `/spec` is the same thing under the singular name and was
not, so working notes landed in commits.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor(golang): name what the unpack hands back, not where it stores it

the scan's signatures said `*spillbuf.Buffer` all the way down, which told
every reader below the scan that it cares whether the reconstruction lives in
memory or on disk. it does not. two interfaces instead, each naming only what
its side actually uses:

- `unpackedContents` for the consumers: `ReaderAt`, `Closer`, and a `Size` that
  is the contiguous run rebuilt from zero
- `blockSink` for the decoder, which additionally needs `WriterAt` and
  `FirstGap` to place blocks

this costs one thing worth flagging. `Close` on a nil `*spillbuf.Buffer` was
nil-safe, so callers just deferred it; widened into an interface, a nil pointer
becomes a non-nil interface and the same call panics. `closeUnpacked` absorbs
that, and it is now the only way an owner releases contents. `readerFor`,
`seekerFor` and `closeUnpacked` are the three places that resolve the nil.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* docs(elfutil): say that CheckAllSections is the decompression-bomb gate

the doc led with "bounds every section syft can drive debug/elf into
decompressing", which describes the mechanism without ever naming what it is
defending against. a reader landing on the call site could not tell that this
is the decompression-bomb check.

state the attack instead: a compressed section header declares its own
decompressed size, debug/elf believes that number and allocates it on open, and
nothing forces it to match what the compressed bytes actually yield. the 260KB
ELF that drove 1.3GB of allocation now lives in the doc rather than only at the
one call site that happened to mention it.

comments only.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* docs(golang): move the overflow note onto the bounds test it describes

the "subtraction form" note sat above the phStart assignment with ten lines of
wrap analysis between it and the `if` it was talking about, so the subtraction
it names reads as missing. it is `hdrLen-phStart < phentsize`.

move it onto that test and name the form it is avoiding (`phStart+phentsize >
hdrLen`, which can overflow past the buffer end) so the referent is not several
paragraphs away.

comments only.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* chore(golang): drop the internal/ README left over from xcoff

that README existed to record where the vendored xcoff package came from and
that Go keeps it internal, which is a provenance note worth having while
third-party code sat there. dropping xcoff took the reason with it, and
repurposing it to point at gotestdata just made it redundant: gotestdata has
its own README covering why it is under internal/, why it is not testdata/, and
what belongs in each.

internal/ now holds one self-documenting directory.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-09-10 09:21:19 -04:00
Alex Goodman 58a033f924 Prevent unnecessary allocations when parsing compressed ELF sections (#5187)
* 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>
2026-08-14 20:08:58 +00:00
Alex Goodman da745b13e8 feat(golang): add extended-stdlib scope and module patterns for symbol capture (#5154)
* feat(golang): add extended-stdlib scope and include patterns for symbol capture

`golang.capture-symbols` decides how much symbol data lands in the SBOM for grype's reachability analysis. It's `none`, `stdlib`, or `all` today, and the useful middle is missing: `stdlib` stops at the standard library, `all` multiplies SBOM size.

A new `extended-stdlib` configurable covers stdlib plus everything under `golang.org/x/`:

```yaml
golang:
  capture-symbols: extended-stdlib
```

Also, a new `capture-symbols-include` configurable for modules that are noisy in your binaries but not everyone's. It's unioned with whatever the scope selects, so it only ever widens:

```yaml
golang:
  capture-symbols: extended-stdlib
  capture-symbols-include:
    - github.com/klauspost/**
```

Patterns are standard doublestar globs, which matters because module paths carry `/v2`-style suffixes:

```yaml
golang:
  capture-symbols-include:
    - github.com/klauspost/*     # compress, but not compress/v2
    - github.com/klauspost/**    # both
    - k8s.io/client-go           # exact match only
```

Ordering is `none` < `stdlib` < `extended-stdlib` < `all`. The existing three values
and the `none` default are unchanged, and the include list is inert under `none`.
Presets compile into glob lists internally, so a single matcher answers "does this
module get symbols" instead of a preset branch sitting next to a separate glob branch.

An unrecognized `capture-symbols` value still falls back to `none`, but warns now
instead of doing it silently. A malformed include pattern warns and gets skipped.

One thing worth a look beyond the feature: the `Symbols` field description in the JSON
schema was wrong after this (it claimed only `all` and `stdlib` populate anything), and
that description lives in the already-published `16.1.10`. Rather than bump a version for
a sentence, `16.1.10` is amended in place and `schema/json/README.md` grows an explicit
exception for description-only changes: descriptions only, no shape change of any kind,
`$id` unchanged. Anything else still needs a bump. Happy to split that into its own PR if
you'd rather review the policy separately.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor(golang): rename capture-symbols-include to capture-symbols-modules

The key's entries are go module paths, and `-include` sitting next to `capture-symbols` reads as plausibly taking symbol or package names instead. Those spellings parse and match nothing, which is quieter than the confusion `-include` was picked to avoid, so the name now says what the list holds.

`golang.CatalogerConfig.CaptureSymbolsModules` and `WithCaptureSymbolsModules` rename with it. Nothing behavioral changes; the key is new in this PR so there is no compatibility surface.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* feat(golang): match capture-symbols-modules across major version suffixes

`github.com/anchore/*` covered `github.com/anchore/syft` and silently stopped covering it the day it became `github.com/anchore/syft/v2`. The config keeps parsing, nothing warns, and symbols quietly go missing from the SBOM. Exact paths had the same hole: `github.com/klauspost/compress` did not cover `compress/v2` either, so no spelling short of `**` survived a major bump.

A major version suffix is part of a module's path but not part of its identity, so patterns are now matched against the module path both with and without it, using `module.SplitPathVersion` from `golang.org/x/mod` (already a direct dep, already used in this package for `PseudoVersion`).

```yaml
golang:
  capture-symbols-modules:
    - github.com/klauspost/*          # compress and compress/v2
    - github.com/klauspost/compress   # same module at every major version
    - github.com/klauspost/compress/v2  # v2 alone
```

Only a trailing suffix is a version, which is Go's own rule. In `github.com/anchore/syft/v2/thing` the `v2` is an ordinary path element naming a major subdirectory a nested module lives in, so it stays literal and `github.com/anchore/**/thing` is how you reach it. `/v0` and `/v1` are not valid suffixes and are left alone.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-08-07 12:44:42 +00:00
Christopher Angelo PhillipsandAlex Goodman f6b5d3e736 perf: group golang symbols by package path to reduce the sbom size (#5064)
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-07-13 16:40:16 -04:00
Christopher Angelo PhillipsandAlex Goodman 1dcac54b0e feat: optionally capture golang binary symbols (#4988)
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-07-13 10:30:23 -04:00
VictorHuu baca32f04a fix:after compliance applied,the relationship concerning the original one should be omitted (#4419)
---------
Signed-off-by: Yuntao Hu <victorhu493@gmail.com>
2025-12-04 15:30:16 -05:00
Christopher Angelo PhillipsandAlex Goodman f77d503892 detect license ID from full text when incidentally provided as a value (#3876)
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2025-05-13 16:37:18 -04:00
Alex Goodman a7816dc9e7 clear devel version for go packages (#3873)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2025-05-09 13:36:52 -04:00
anchore-actions-token-generator[bot]andspiffcs f11377fe30 chore(deps): update tools to latest versions (#3775)
---------
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2025-04-03 17:35:26 +00:00
Christopher Angelo Phillips e584c9f416 feat: 3626 add option enable license content; disable by default (#3631)
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
2025-02-05 20:41:03 +00:00
Keith Zantow a2a56dd3e9 fix: golang remote license search not executing when error reading local mod dir (#3549)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2025-01-06 11:47:55 -05:00
Alex Goodman cbce129bb9 Use reader when scanning for package versions over reading entire binary into memory (#3558)
* use streaming readers

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* replace redis search patterns

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* address PR feedback

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2025-01-02 22:12:37 +00:00
Alex Goodman e4e985b9b0 Create single license scanner for all catalogers (#3348)
* add single license scanner instance

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* rename testing license scanner

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-10-21 16:17:12 +00:00
Weston Steimel e962c10da7 fix: improve go binary semver extraction for traefik (#3325)
Improves the go cataloger semver extraction logic to include getting the
release version of traefik.  This is based off of the regex pattern that
already existed in the traefik binary classifier.

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-10-14 09:41:34 -04:00
Keith ZantowandAlex Goodman ccbee94b87 feat: report unknowns in sbom (#2998)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-10-07 16:11:37 -04:00
Christopher Angelo Phillips c84cb2cf84 fix: update mainModuleVersion function to always prefix v to findings (#3087)
* chore: basic fix
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
* test: make sure ldflags are prefixed with v
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
2024-08-01 11:29:07 -04:00
Laurent Goderre 4882d2e8ce Only match ldflag version if it matches the main module or targets main.version (#3062)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-07-25 13:56:55 -04:00
Alex Goodman 9573f557d1 better go mod detection from partial package builds (#3060)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-07-24 09:34:40 -04:00
Weston SteimelandAlex Goodman 749ccc59c1 fix(golang): improve version extraction from ldflags for pingcap TiDB (#2962)
* fix(golang): improve version extraction from ldflags for pingcap TiDB

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

* loosen ld flag parsing requirements

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-06-14 14:35:14 +01:00
Keith Zantow ca0cc52d47 fix: separate golang license caches from mod dir (#2852)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-06-12 19:12:35 -04:00
Alex Goodman f4a69e6d35 add relationships for go binary packages (#2912)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-30 11:37:17 -04:00
Jon JohnsonandWill Murphy c314e05aae Handle GOEXPERIMENTs in go version (#2893)
* Handle GOEXPERIMENTs in go version

Signed-off-by: Jon Johnson <jon.johnson@chainguard.dev>

* bump JSON schema

Signed-off-by: Will Murphy <will.murphy@anchore.com>

---------

Signed-off-by: Jon Johnson <jon.johnson@chainguard.dev>
Signed-off-by: Will Murphy <will.murphy@anchore.com>
Co-authored-by: Will Murphy <will.murphy@anchore.com>
2024-05-25 20:23:30 +00:00
Keith ZantowandWill Murphy dde5d349b1 fix: more robust go main version extraction (#2767)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Will Murphy <will.murphy@anchore.com>
Co-authored-by: Will Murphy <will.murphy@anchore.com>
2024-04-11 11:58:51 -04:00
Alex Goodman 84576b93e1 Guess go main module version based on binary contents (#2608)
* guess go main module version based on binary contents

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add configuration options for golang main module version heuristics

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix test setup for go bin cataloger

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix unit test

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix incorrect test assert ordering

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* handle error from seek

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-02-09 19:52:42 +00:00
Alex Goodman 3023a5a7bc Detect ELF security features (#2443)
* add detection of ELF security features

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix linting

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update json schema with file executable data

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update expected fixure when no tty present

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* more detailed differ

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* use json differ

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove json schema addition

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* regenerate json schema

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix mimtype set ref

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-02-02 16:51:18 +00:00
Alex Goodman 6107e5e2ad translate maps to sequences in pkg metadata (#2553)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-02-01 11:58:10 -05:00
Alex Goodman 11c0b1c234 Unexport types and functions cataloger packages (#2530)
* unexport as many types and functions from cataloger packages as possible

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* capture type and signature information in convention test

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* check that we return pkg.Cataloger from constructors

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-01-24 16:12:46 -05:00
Alex Goodman cdad5e767a plumb context through catalogers (#2528)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-01-22 15:54:51 -05:00
Alex Goodman 1aaa644007 Remove MetadataType from core package object and normalize JSON metadataType values (#1983)
* [wip]

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* distinct the package metadata functions

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove metadata type from package core model

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* incorporate review feedback for names

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add RPM archive metadata and split parser helpers

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* clarify the python package metadata type

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* rename the KB metadata type

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* break hackage and composer types by use case

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* linting fix

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix encoding and decoding for syft-json and cyclonedx

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* bump json schema to 11

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update cyclonedx-json snapshots

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update cyclonedx-xml snapshots

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update spdx-json snapshots

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update spdx-tv snapshots

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update syft-json snapshots

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* correct metadata type in stack yaml parser test

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix bom-ref redactor for cyclonedx-xml

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add tests for legacy package metadata names

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* regenerate json schema v11

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix legacy HackageMetadataType reflect type value check

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix linting

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* packagemetadata discovery should account for type shadowing

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix linting

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix cli tests

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* bump json schema version to v12

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update json schema to incorporate changes from main

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add syft-json legacy config option

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add tests around v11-v12 json decoding

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add docs for SYFT_JSON_LEGACY

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* rename structs to be compliant with new naming scheme

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2023-10-30 12:12:04 -04:00
Christopher Angelo Phillips f6c8057977 feat: add package for go compiler given binary detection (#2195)
adds a unique synthetic package to the SBOM output that represents the go compiler when it is detected as a part of a package discovered by the go binary cataloger.

When using an SBOM generated by syft - downstream vulnerability scanners now have the opportunity to detect/report on the PURL/CPEs attached to the new stdlib package.
---------

Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>
2023-10-06 13:15:50 -04:00
William Murphy cfebae27f5 fix: don't panic on universal go binaries (#2078)
If crypto settings or arch cannot be determined, still attempt to catalog packages from
the build info, rather than panicking.

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2023-08-30 08:37:50 -04:00
Sirish Bathina 62f689824c Detect golang boring crypto and fipsonly modules (#2021)
* Extending build info to include crypto settings

Signed-off-by: Sirish Bathina <sirish@kasten.io>

* Use kasten fork for goversion module

Signed-off-by: Sirish Bathina <sirish@kasten.io>

* go mod tidy

Signed-off-by: Sirish Bathina <sirish@kasten.io>

* change key to GoCryptoSettings and lint fix

Signed-off-by: Sirish Bathina <sirish@kasten.io>

* Addressing feedback

Signed-off-by: Sirish Bathina <sirish@kasten.io>

---------

Signed-off-by: Sirish Bathina <sirish@kasten.io>
2023-08-24 09:49:59 -04:00
Avi Deitcher 68f8df9594 accept main.version ldflags even without vcs (#1855)
Signed-off-by: Avi Deitcher <avi@deitcher.net>
2023-06-01 08:34:46 -04:00
Alex Goodman 07e76907f6 Migrate location-related structs to the file package (#1751)
* migrate location structs to file package

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* replace source.Location refs with file package call

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* fix linting

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* remove hardlink test for file based catalogers

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* remove hardlink test for all-regular-files testing

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* migrate file resolver implementations to separate package

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* fix linting

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* [wip] migrate resolvers to internal

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* migrate resolvers to syft/internal

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

---------

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
Signed-off-by: <>
2023-05-24 17:06:38 -04:00
Alex GoodmanandWeston Steimel 26c201f7f7 Extract go module versions from ldflags for binaries built by go (#1832)
* wip

Signed-off-by: Weston Steimel <weston.steimel@anchore.com>

* with golang bin ldflags refactor

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add test for golang binary cataloger for ldflag extraction

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* remove binary classfiers that overlap with new go ldflags detection

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

---------

Signed-off-by: Weston Steimel <weston.steimel@anchore.com>
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
Co-authored-by: Weston Steimel <weston.steimel@anchore.com>
2023-05-23 10:27:48 -04:00
Alex Goodman 5d156b8241 Add annotations for evidence on package locations (#1723)
* add location annotations + deb evidence annotations

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* rename LocationData struct and Annotation helper function

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add failing integration test for evidence coverage

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add evidence to aplm cataloger locations

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* change location annotation helper to return a location copy

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add evidence to binary cataloger locations

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* updated remaining catalogers with location annotations

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* fix unit tests

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* fix linting

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* bump json schema

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* partial addressing of review comments

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* rename location.WithAnnotation

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

---------

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
2023-04-13 17:02:29 -04:00
Avi DeitcherandKeith Zantow 9fd532246a feat: scan local go mod cache for licenses of golang packages (#1645)
Signed-off-by: Avi Deitcher <avi@deitcher.net>
Co-authored-by: Keith Zantow <kzantow@gmail.com>
2023-03-23 10:38:15 -04:00
Weston Steimel bcc0751a40 feat: retain go package info when no module declared (#1632)
Signed-off-by: Weston Steimel <weston.steimel@anchore.com>
2023-03-01 14:26:44 +00:00
Justin Chadwell 8d36b21237 fix: additional excessive go binary warnings (#1432)
The original fix b125ea83ba didn't catch
all the excessive warnings, it seems like getArches can also be called
on binaries that aren't neccessarily go binaries, so the messages from
this should also be Trace instead of Warn.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-03 09:54:08 -05:00
Alex Goodman 6826d7603b port golang cataloger to new generic cataloger pattern (#1289)
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
2022-10-25 16:42:50 +00:00