The CycloneDX specification for vulnerabilities defines four analysis
states ([1]) for cases where a vulnerability does not affect a component:
* resolved
* resolved_with_pedigree
* not_affected
* false_positive
Currently, the metadatas present in Buildroot does not allow an accurate
mapping of ignored CVEs to the appropriate CycloneDX vulnerability
categories. As a result, all ignored CVEs are currently marked as
'in_triage' by default.
This default analysis was established during the introduction of the
'generate-cyclonedx' script. The reasoning at the time was that SBOM
consumers might want to re-evaluate ignored vulnerabilities, as the
Buildroot infrastructure could not reliably determine their actual
state.
This patch adds support for automatically marking vulnerabilities as
'resolved_with_pedigree' when a Buildroot patch includes a 'CVE:''
tag in its header referencing the CVE identifier.
The 'CVE:' tag appears alongside the already required 'Upstream:', if
the patch address a security vulnerability and may be repeated if a
patch addresses multiple vulnerabilities.
If a vulnerability is addressed by multiple patches, each patch will need to
reference the vulnerability identifier.
For details on how CycloneDX handles 'resolved_with_pedigree', see
[1][2].
As an example, the CVE-2025-3198 from the binutils package will result
in the following pedigree for the binutils component:
```
{
"type": "unofficial",
"diff": {
"text": {
"content": "..."
}
},
"resolves": [
{
"type": "security",
"name": "CVE-2025-3198"
}
]
},
```
The `resolves` property is an array of issue the pedigree resolves. If
multiple are addressed by the same patch, then multiple identifier will be
present in this array.
In the listed vulnerabilities the entry for the CVE-2025-3198 looks like
this:
```
{
"id": "CVE-2025-3198",
"analysis": {
"state": "resolved_with_pedigree",
"detail": "The CVE 'CVE-2025-3198' has been marked as ignored by Buildroot"
},
"affects": [
{
"ref": "binutils"
}
]
}
```
[1] https://cyclonedx.org/docs/1.6/json/#vulnerabilities_items_analysis_state
[2] https://cyclonedx.org/docs/1.6/json/#components_items_pedigree_patches_items_resolves
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
(cherry picked from commit 9415529923c9f7eaeec44c8fd3eecca79bf6b8d2)
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Add options to customize the project name and version in the generated SBOM
metadata and set buildroot generate-cyclonedx as a tool in the metadata
section.
Signed-off-by: Fabien Lehoussel <fabien.lehoussel@smile.fr>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
(cherry picked from commit 9cbbc47762)
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
By default, use an indent of 2, which is the same as what 'jq' uses.
This omits the need for 'jq' in the example usage. Also, add a new
line to the output while at it.
Signed-off-by: Thomas Devoogdt <thomas.devoogdt@barco.com>
Signed-off-by: Julien Olivain <ju.o@free.fr>
The real file is utils/generate-cyclonedx,
not utils/generate-cyclonedx.py.
Signed-off-by: Thomas Devoogdt <thomas.devoogdt@barco.com>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
Check if the script shall read from stdin if data is piped into.
Otherwise read from the input file or if not specified print usage and
exit.
Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
There is a growing need to generate software bill of materials (SBOM) from
buildroot configurations. Right now there are different solutions available
for buildroot users `show-info`, `legal-info` and `pkg-stats`.
They all generate similar information but in a format that is specific
to buildroot.
CycloneDX is a SBOM specification that can be consumed by different services.
This patch introduces a Python script, that converts the JSON output of the
show-info Makefile target to a CycloneDX-style SBOM.
The script output contains the following information.
- A list of all packages, or "components" with information about
version, cpe (if available), applied patches.
- By default virtual packages are not listed in the SBOM.
- Additional information is added to the component 'properties' to
specify wheter the component is present on the target or the host
under the `BR_TYPE` property name.
- An overview of the licenses applicable to each package. If possible,
the names of these licenses have been matched to known SPDX license
identifiers.
- Per package, a list of (recursive) dependencies on other packages.
- A list of ignored CVE and their associated component.
More information on CycloneDX at https://cyclonedx.org/.
Usage:
make show-info | utils/generate-cyclonedx.py | jq '.'
Example output:
```
{
"bomFormat": "CycloneDX",
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
"specVersion": "1.6",
"components": [
{
"bom-ref": "busybox",
"type": "library",
"name": "busybox",
"version": "1.36.1",
"licenses": [
{
"license": {
"id": "GPL-2.0"
}
},
...
],
"cpe": "cpe:2.3🅰️busybox:busybox:1.36.1:*:*:*:*:*:*:*",
"pedigree": {
"patches": [
{
"type": "unofficial",
"diff": {
"text": {
"content": "..."
}
}
}
]
}
"properties": [
{
"name": "BR_TYPE",
"value": "target"
}
]
},
...
],
"dependencies": [
{
"ref": "busybox",
"dependsOn": [
"host-skeleton",
"skeleton",
"skeleton-init-sysv",
"skeleton-init-common",
...
}
...
],
"vulnerabilities": [
{
"id": "CVE-2022-28391",
"analysis": {
"state": "in_triage",
"detail": "The CVE 'CVE-2022-28391' has been marked as ignored by Buildroot"
},
"affects": [
{
"ref": "busybox"
}
]
},
...
],
"metadata": {
"component": {
"bom-ref": "buildroot",
"name": "buildroot",
"type": "firmware",
"version": "2024.02-4744-gafea667f00-dirty"
}
}
}
```
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Co-authored-by: Matthias Swiggers <matthias.swiggers@mind.be>
Reviewed-by: Vincent Jardin <vjardin@free.fr>
[Arnout:
- alphabetically order imports;
- use endswith instead if 'in' to check suffix;
- add usage to help text;
- remove .py suffix.
]
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>