feat(executable): capture GNU ELF build IDs (#5426)

* feat(executable): capture GNU ELF build IDs

Capture GNU ELF build IDs in Syft JSON so consumers can correlate
otherwise unidentified binaries with known artifacts or build records.

Read GNU build-ID notes from .note.gnu.build-id, with a 64 KiB read limit.
Validate the note owner and type before recording the identifier.

Add focused extraction and JSON round-trip tests and update the schema.

Signed-off-by: Mario Corchero <mcorcherojim@bloomberg.net>

* chore: bump JSON schema to 16.1.13 for executable identifiers

16.1.12 landed on main for coordinate fullPath, so the identifiers
addition moves to the next version.

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

* feat(executable): capture go build IDs from .note.go.buildid

The go linker only writes a GNU build ID with -B or when linking
externally, so most pure-Go binaries had no identifier. Every go ELF
carries .note.go.buildid, captured as kind `go-build-id` in the form
`go tool buildid` prints.

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

* docs(executable): describe identifiers generically

Identifier field docs (and the published schema) now give GNU hex and
Go build IDs as examples instead of stating every value is a GNU build
ID in lowercase hex, so the contract holds as more kinds are added.

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

* fix(executable): keep identifier notes inside elfutil bounds

Register `.note.gnu.build-id` and `.note.go.buildid` in elfutil's
sectionsReadByName as that list asks, and never open a compressed
identifier note. Real ones are SHF_ALLOC and cannot be compressed, so
this drops the only decompression path into these reads.

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

* test(executable): check identifiers from real linker output

Cross-compiles a tiny go program with `-B` so the test sees a GNU
build ID and a go build ID written by an actual linker and read through
the cataloger entrypoint.

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

---------

Signed-off-by: Mario Corchero <mcorcherojim@bloomberg.net>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Mario Corchero <mcorcherojim@bloomberg.net>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Aditya Sirish A Yelgundhalli
2026-11-04 22:42:03 +00:00
committed by GitHub
co-authored by Mario Corchero Alex Goodman
parent fd712ee71a
commit fa02ff2d26
8 changed files with 5081 additions and 5 deletions
File diff suppressed because it is too large Load Diff
+26 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "anchore.io/schema/syft/json/16.1.12/document",
"$id": "anchore.io/schema/syft/json/16.1.13/document",
"$ref": "#/$defs/Document",
"$defs": {
"AlpmDbEntry": {
@@ -1468,6 +1468,13 @@
"elfSecurityFeatures": {
"$ref": "#/$defs/ELFSecurityFeatures",
"description": "ELFSecurityFeatures contains ELF-specific security hardening information when Format is ELF."
},
"identifiers": {
"items": {
"$ref": "#/$defs/ExecutableIdentifier"
},
"type": "array",
"description": "Identifiers lists self-declared build identifiers found in the binary (e.g. ELF GNU build IDs or Go build IDs)."
}
},
"type": "object",
@@ -1479,6 +1486,24 @@
],
"description": "Executable contains metadata about binary files and their security features."
},
"ExecutableIdentifier": {
"properties": {
"kind": {
"type": "string",
"description": "Kind identifies the type and source of the identifier."
},
"value": {
"type": "string",
"description": "Value is the identifier in the conventional text form for its Kind (e.g. lowercase hex for an ELF GNU build ID)."
}
},
"type": "object",
"required": [
"kind",
"value"
],
"description": "ExecutableIdentifier is a self-declared build identifier used to correlate a binary with its build or debug information."
},
"File": {
"properties": {
"id": {