diff mbox series

[3/3] SPDX 3.0: add CVEs from cve-ckeck results

Message ID 20250108154718.3031653-3-hongxu.jia@windriver.com
State New
Headers show
Series [1/3] meta/lib/oe/cve_check.py: fix patched_cves not updated | expand

Commit Message

Hongxu Jia Jan. 8, 2025, 3:47 p.m. UTC
Originally, SPDX 3.0 added CVEs from CVE patch and CVE_STATUS
in recipe, this commit adds CVEs cve-ckeck results that is
generated from NVD CVE database

Enable it by inheriting cve_check and setting 'SPDX_INCLUDE_VEX = "all"'
otherwise still added CVEs from CVE patch and CVE_STATUS as usual

$ echo 'INHERIT += "cve-check"' >> conf/local.conf
$ echo 'SPDX_INCLUDE_VEX = "all"' >> conf/local.conf
$ bitbake glibc
WARNING: glibc-2.40+git-r0 do_cve_check: Found unpatched CVE (CVE-2010-4756)

$ bitbake core-image-minimal
$ vim tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.rootfs.spdx.json
...
    {
      "type": "security_VexAffectedVulnAssessmentRelationship",
      "spdxId": "http://spdx.org/spdxdocs/glibc-086907e2-5516-5638-9df3-b3863651f374/df3a653fe6624a017aa75a75ba8cff1c3d0c6093c4bf8b05d1473ae4da277398/vex-affected/1ae2a2b94bac9bf0894b46b0c3194416",
      "creationInfo": "_:CreationInfo161",
      "from": "http://spdx.org/spdxdocs/glibc-086907e2-5516-5638-9df3-b3863651f374/df3a653fe6624a017aa75a75ba8cff1c3d0c6093c4bf8b05d1473ae4da277398/vulnerability/CVE-2010-4756",
      "relationshipType": "affects",
      "to": [
        "http://spdx.org/spdxdocs/glibc-086907e2-5516-5638-9df3-b3863651f374/df3a653fe6624a017aa75a75ba8cff1c3d0c6093c4bf8b05d1473ae4da277398/package/libc6"
      ],
      "security_vexVersion": "1.0.0"
    },
...
    {
      "type": "security_Vulnerability",
      "spdxId": "http://spdx.org/spdxdocs/glibc-086907e2-5516-5638-9df3-b3863651f374/df3a653fe6624a017aa75a75ba8cff1c3d0c6093c4bf8b05d1473ae4da277398/vulnerability/CVE-2010-4756",
      "creationInfo": "_:CreationInfo263",
      "externalIdentifier": [
        {
          "type": "ExternalIdentifier",
          "externalIdentifierType": "cve",
          "identifier": "CVE-2010-4756",
          "identifierLocator": [
            "https://cveawg.mitre.org/api/cve/CVE-2010-4756",
            "https://www.cve.org/CVERecord?id=CVE-2010-4756"
          ]
        }
      ]
    },
...

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
 meta/classes/create-spdx-3.0.bbclass |  7 +++++--
 meta/classes/spdx-common.bbclass     | 11 +++++++++++
 meta/lib/oe/spdx30_tasks.py          | 29 ++++++++++++++++++++++++++--
 3 files changed, 43 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/meta/classes/create-spdx-3.0.bbclass b/meta/classes/create-spdx-3.0.bbclass
index 25f3aa5f43..e3d6f95e3d 100644
--- a/meta/classes/create-spdx-3.0.bbclass
+++ b/meta/classes/create-spdx-3.0.bbclass
@@ -42,8 +42,9 @@  SPDX_INCLUDE_VEX[doc] = "Controls what VEX information is in the output. Set to
     'none' to disable all VEX data. Set to 'current' to only include VEX data \
     for vulnerabilities not already fixed in the upstream source code \
     (recommended). Set  to 'all' to get all known historical vulnerabilities, \
-    including those already fixed upstream (warning: This can be large and \
-    slow)."
+    including those already fixed upstream, if cve_check is inherited, set to 'all' \
+    to get all known historical vulnerabilities from cve check result \
+    (warning: This can be large and slow)."
 
 SPDX_INCLUDE_TIMESTAMPS ?= "0"
 SPDX_INCLUDE_TIMESTAMPS[doc] = "Include time stamps in SPDX output. This is \
@@ -141,6 +142,7 @@  do_create_spdx[vardeps] += "\
     SPDX_PROFILES \
     SPDX_NAMESPACE_PREFIX \
     SPDX_UUID_NAMESPACE \
+    SPDX_INCLUDE_VEX \
     "
 
 addtask do_create_spdx after \
@@ -164,6 +166,7 @@  do_create_spdx[cleandirs] = "${SPDXDEPLOY} ${SPDXWORK}"
 do_create_spdx[depends] += " \
     ${PATCHDEPENDENCY} \
     ${@create_spdx_source_deps(d)} \
+    ${@create_spdx_cve_check_deps(d)} \
 "
 
 python do_create_package_spdx() {
diff --git a/meta/classes/spdx-common.bbclass b/meta/classes/spdx-common.bbclass
index 81ad4d3b7a..8918448c35 100644
--- a/meta/classes/spdx-common.bbclass
+++ b/meta/classes/spdx-common.bbclass
@@ -39,6 +39,17 @@  SPDX_CUSTOM_ANNOTATION_VARS ??= ""
 
 SPDX_MULTILIB_SSTATE_ARCHS ??= "${SSTATE_ARCHS}"
 
+def create_spdx_cve_check_deps(d):
+    if (
+        d.getVar("SPDX_INCLUDE_VEX") == "all"
+        and bb.data.inherits_class('cve-check', d)
+        and d.getVar("CVE_CHECK_FORMAT_JSON") == "1"
+    ):
+        pn = d.getVar('PN')
+        return pn + ":do_cve_check"
+
+    return ""
+
 def create_spdx_source_deps(d):
     import oe.spdx_common
 
diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py
index 9baa40887b..e8658e2c32 100644
--- a/meta/lib/oe/spdx30_tasks.py
+++ b/meta/lib/oe/spdx30_tasks.py
@@ -437,8 +437,33 @@  def set_purposes(d, element, *var_names, force_purposes=[]):
         getattr(oe.spdx30.software_SoftwarePurpose, p) for p in purposes[1:]
     ]
 
-def get_cves(d):
+def get_cves(d, include_vex):
     cve_status = {}
+
+    # Get CVEs from cve-check
+    if (
+        include_vex == "all"
+        and bb.data.inherits_class('cve-check', d)
+        and d.getVar("CVE_CHECK_FORMAT_JSON") == "1"
+    ):
+        pkgfilepath = d.getVar("CVE_CHECK_RECIPE_FILE_JSON")
+        if os.path.exists(pkgfilepath):
+            with open(pkgfilepath) as j:
+                data = json.load(j)
+                json_data = {"version":"1", "package": []}
+                oe.cve_check.cve_check_merge_jsons(json_data, data)
+                for issue in json_data["package"][0].get("issue", []):
+                    cve = issue["id"]
+                    cve_status[cve] = {
+                        "mapping": issue["status"],
+                        "detail": issue["detail"],
+                        "description": issue.get("description", None)
+                    }
+
+                if cve_status:
+                    return cve_status
+
+    # Get CVEs from recipe
     patched_cves = oe.cve_check.get_patched_cves(d)
     for cve, patched_cve in patched_cves.items():
         cve_status[cve] = {
@@ -498,7 +523,7 @@  def create_spdx(d):
     # Add CVEs
     cve_by_status = {}
     if include_vex != "none":
-        cve_data = get_cves(d)
+        cve_data = get_cves(d, include_vex)
         for cve, decoded_status in cve_data.items():
 
             # If this CVE is fixed upstream, skip it unless all CVEs are