Skip to content

Commit

Permalink
Repl deprecated CVE_CHECK_IGNORE with CVE_STATUS
Browse files Browse the repository at this point in the history
Yocto releases after Kirkstone have deprecated CVE_CHECK_IGNORE in favour of
CVE_STATUS. Updating VEX handling of patched and ignored CVEs accordingly.

CVE_STATUS will also provide additional details about a specific CVE's
status, using the detail and description fields.

Co-authored-by: Aoife Power <aoife.power@iris-sensing.com>
Signed-off-by: Jasper Orschulko <jasper@fancydomain.eu>
  • Loading branch information
Jasper-Ben and aoifepow committed Aug 29, 2024
1 parent 413d3d9 commit 8eb6a1e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
2 changes: 2 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Copyright (C) 2024 iris-GmbH infrared & intelligent sensors
Based on previous work from `github.com/bgnetworks/meta-dependencytrack`:
Copyright 2022 BG Networks, Inc.

Includes code snippet which is Copyright (C) 2023 Andrej Valek <andrej.valek@siemens.com>

---

Permission is hereby granted, free of charge, to any person obtaining a copy of
Expand Down
90 changes: 59 additions & 31 deletions classes/cyclonedx-export.bbclass
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,29 @@ CYCLONEDX_EXPORT_VEX ??= "${CYCLONEDX_EXPORT_DIR}/vex.json"
CYCLONEDX_EXPORT_TMP ??= "${TMPDIR}/cyclonedx-export"
CYCLONEDX_EXPORT_LOCK ??= "${CYCLONEDX_EXPORT_TMP}/bom.lock"

# resolve CVE_CHECK_IGNORE and CVE_STATUS_GROUPS,
# taken from https://git.yoctoproject.org/poky/commit/meta/classes/cve-check.bbclass?id=be9883a92bad0fe4c1e9c7302c93dea4ac680f8c
# SPDX-License-Identifier: MIT
# Copyright (C) 2023 Andrej Valek <andrej.valek@siemens.com>

python () {
# Fallback all CVEs from CVE_CHECK_IGNORE to CVE_STATUS
cve_check_ignore = d.getVar("CVE_CHECK_IGNORE")
if cve_check_ignore:
bb.warn("CVE_CHECK_IGNORE is deprecated in favor of CVE_STATUS")
for cve in (d.getVar("CVE_CHECK_IGNORE") or "").split():
d.setVarFlag("CVE_STATUS", cve, "ignored")

# Process CVE_STATUS_GROUPS to set multiple statuses and optional detail or description at once
for cve_status_group in (d.getVar("CVE_STATUS_GROUPS") or "").split():
cve_group = d.getVar(cve_status_group)
if cve_group is not None:
for cve in cve_group.split():
d.setVarFlag("CVE_STATUS", cve, d.getVarFlag(cve_status_group, "status"))
else:
bb.warn("CVE_STATUS_GROUPS contains undefined variable %s" % cve_status_group)
}

python do_cyclonedx_init() {
import uuid
from datetime import datetime, timezone
Expand Down Expand Up @@ -56,7 +79,7 @@ addhandler do_cyclonedx_init
do_cyclonedx_init[eventmask] = "bb.event.BuildStarted"

python do_cyclonedx_package_collect() {
import oe.cve_check
from oe.cve_check import decode_cve_status

# ignore non-target packages
for ignored_suffix in (d.getVar("SPECIAL_PKGSUFFIX") or "").split():
Expand All @@ -77,36 +100,8 @@ python do_cyclonedx_package_collect() {
sbom["components"].append(pkg)
bom_ref = pkg["bom-ref"]

# populate vex file with patched CVEs
for _, patched_cve in enumerate(oe.cve_check.get_patched_cves(d)):
bb.debug(2, f"Found patch for CVE {patched_cve} in {name}@{version}")
vex["vulnerabilities"].append({
"id": patched_cve,
# vex documents require a valid source, see https://github.com/DependencyTrack/dependency-track/issues/2977
# this should always be NVD for yocto CVEs.
"source": {"name": "NVD", "url": f"https://nvd.nist.gov/vuln/detail/{patched_cve}"},
"analysis": {"state": "resolved"},
# Hint: Component specific resolving seems not to work at the moment when using DependencyTrack
# resolution will of CVE will be applied to all components within the project that contain the CVE
"affects": [{"ref": f"urn:cdx:{sbom_serial_number}/1#{bom_ref}"}]
})

# populate vex file with ignored CVEs defined in CVE_CHECK_IGNORE
cve_check_ignore = d.getVar("CVE_CHECK_IGNORE")
if cve_check_ignore is not None:
for ignored_cve in cve_check_ignore.split():
bb.debug(2, f"Found ignore statement for CVE {ignored_cve} in {name}@{version}")
vex["vulnerabilities"].append({
"id": ignored_cve,
# vex documents require a valid source, see https://github.com/DependencyTrack/dependency-track/issues/2977
# this should always be NVD for yocto CVEs.
"source": {"name": "NVD", "url": f"https://nvd.nist.gov/vuln/detail/{ignored_cve}"},
# setting not-affected state for ignored CVEs
"analysis": {"state": "not_affected"},
# Hint: Component specific resolving seems not to work at the moment when using DependencyTrack
# resolution will of CVE will be applied to all components within the project that contain the CVE
"affects": [{"ref": f"urn:cdx:{sbom_serial_number}/1#{bom_ref}"}]
})
for cve in (d.getVarFlags("CVE_STATUS") or {}):
append_to_vex_vulnerabilities(d, vex, cve, sbom_serial_number, bom_ref)

# write it back to the deploy directory
write_json(d.getVar("CYCLONEDX_EXPORT_SBOM"), sbom)
Expand Down Expand Up @@ -162,3 +157,36 @@ def generate_packages_list(products_names, version):
pkg["group"] = vendor
packages.append(pkg)
return packages

def append_to_vex_vulnerabilities(d, vex, cve, sbom_serial_number, bom_ref):
from oe.cve_check import decode_cve_status

decoded_status, state, justification = decode_cve_status(d, cve)
# Currently, only "Patched" and "Ignored" status are relevant to us.
# See https://docs.yoctoproject.org/singleindex.html#term-CVE_CHECK_STATUSMAP for possible statuses.
if decoded_status == "Patched":
bb.debug(2, f"Found patch for {cve} in {d.getVar('BPN')}")
vex_state = "resolved"
elif decoded_status == "Ignored":
bb.debug(2, f"Found ignore statement for {cve} in {d.getVar('BPN')}")
vex_state = "not_affected"
else:
bb.debug(2, f"Found unknown or irrelevant CVE status {decoded_status} for {cve} in {d.getVer('BPN')}. Skipping...")
return

detail_string = ""
if state:
detail_string += f"STATE: {state}\n"
if justification:
detail_string += f"JUSTIFICATION: {justification}\n"
vex["vulnerabilities"].append({
"id": cve,
# vex documents require a valid source, see https://github.com/DependencyTrack/dependency-track/issues/2977
# this should always be NVD for yocto CVEs.
"source": {"name": "NVD", "url": f"https://nvd.nist.gov/vuln/detail/{cve}"},
"analysis": {
"state": vex_state,
"detail": detail_string
},
"affects": [{"ref": f"urn:cdx:{sbom_serial_number}/1#{bom_ref}"}]
})

0 comments on commit 8eb6a1e

Please sign in to comment.