Commit Graph
1 Commits
Author SHA1 Message Date
Vamshidher Reddy Jannapu Reddy 14a0beb93c Fix unbounded memory use decoding AI model metadata from CycloneDX (#5404)
* fix: stop unbounded recursion decoding self-referencing CycloneDX metadata

SafeTensorsModelInfo and GGUFFileHeader both carry a Parts field that is a
slice of their own type. When a CycloneDX component with that metadata is
decoded from properties, the slice decoder tries element 0, which decodes a
struct whose Parts slice tries element 0 one level deeper, and so on. The
recursion never finds a base case, building longer property-name prefixes
on every level, so memory grows until the process is killed (seen in
grype on any machine-learning-model component written by syft).

Return early from struct decoding when no property is named by the prefix
or nested below it: none of the fields could be decoded anyway, and the
recursion is now bounded by the depth of the properties that exist.

Refs anchore/grype#3767

Signed-off-by: Vamshidher Reddy Jannapu Reddy <v.jannapu@gmail.com>

* perf: look up nested CycloneDX property names in a sorted index

The struct check added in the previous commit scanned every property of a
component for every struct it decoded. Decoding a slice of structs, such as
a package's locations, does that once per element, so a component with n
properties took O(n^2): 20,000 location properties took 5.3s to decode
instead of 18ms, a cost that an untrusted SBOM can choose.

Sort the property names once per Decode/DecodeInto call and binary-search
them instead. The result of each check is unchanged; decoding is back to
O(n log n) (27ms for the same 20,000 properties).

Refs anchore/grype#3767

Signed-off-by: Vamshidher Reddy Jannapu Reddy <v.jannapu@gmail.com>

---------

Signed-off-by: Vamshidher Reddy Jannapu Reddy <v.jannapu@gmail.com>
2026-10-29 15:02:36 -04:00