From: Andrej Valek <andrej.valek@siemens.com>
To: <openembedded-core@lists.openembedded.org>
Cc: Andrej Valek <andrej.valek@siemens.com>,
Peter Marko <peter.marko@siemens.com>
Subject: [OE-core][PATCH v8 1/3] cve-check: add option to add additional patched CVEs
Date: Thu, 22 Jun 2023 14:00:01 +0200 [thread overview]
Message-ID: <20230622120009.28939-2-andrej.valek@siemens.com> (raw)
In-Reply-To: <20230519081850.82586-1-andrej.valek@siemens.com>
From: Andrej Valek <andrej.valek@siemens.com>
- Replace CVE_CHECK_IGNORE with CVE_STATUS to be more flexible.
The CVE_STATUS should contain an information about status wich
is decoded in 3 items:
- generic status: "Ignored", "Patched" or "Unpatched"
- more detailed status enum
- description: free text describing reason for status
Examples of usage:
CVE_STATUS[CVE-1234-0001] = "not-applicable-platform: Issue only applies on Windows"
CVE_STATUS[CVE-1234-0002] = "fixed-version: Fixed externally"
CVE_CHECK_STATUSMAP[not-applicable-platform] = "Ignored"
CVE_CHECK_STATUSMAP[fixed-version] = "Patched"
Signed-off-by: Andrej Valek <andrej.valek@siemens.com>
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
meta/classes/cve-check.bbclass | 99 +++++++++++++++++++++++++++++-----
meta/lib/oe/cve_check.py | 25 +++++++++
2 files changed, 111 insertions(+), 13 deletions(-)
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index bd9e7e7445..4eb6dff7de 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -70,14 +70,48 @@ CVE_CHECK_COVERAGE ??= "1"
# Skip CVE Check for packages (PN)
CVE_CHECK_SKIP_RECIPE ?= ""
-# Ingore the check for a given list of CVEs. If a CVE is found,
-# then it is considered patched. The value is a string containing
-# space separated CVE values:
+# Replace NVD DB check status for a given CVE. Each of CVE has to be mentioned
+# separately with optional detail and description for this status.
#
-# CVE_CHECK_IGNORE = 'CVE-2014-2524 CVE-2018-1234'
+# CVE_STATUS[CVE-1234-0001] = "not-applicable-platform: Issue only applies on Windows"
+# CVE_STATUS[CVE-1234-0002] = "fixed-version: Fixed externally"
#
+# CVE_CHECK_STATUSMAP[not-applicable-platform] = "Ignored"
+# CVE_CHECK_STATUSMAP[fixed-version] = "Patched"
+#
+# CVE_CHECK_IGNORE is deprecated and CVE_STATUS has to be used instead.
+# Keep CVE_CHECK_IGNORE until other layers migrate to new variables
CVE_CHECK_IGNORE ?= ""
+# Possible options for CVE statuses
+
+# used by this class internally when fix is detected (NVD DB version check or CVE patch file)
+CVE_CHECK_STATUSMAP[patched] = "Patched"
+# use when this class does not detect backported patch (e.g. vendor kernel repo with cherry-picked CVE patch)
+CVE_CHECK_STATUSMAP[backported-patch] = "Patched"
+# use when NVD DB does not mention patched versions of stable/LTS branches which have upstream CVE backports
+CVE_CHECK_STATUSMAP[cpe-stable-backport] = "Patched"
+# use when NVD DB does not mention correct version or does not mention any verion at all
+CVE_CHECK_STATUSMAP[fixed-version] = "Patched"
+
+# used internally by this class if CVE vulnerability is detected which is not marked as fixed or ignored
+CVE_CHECK_STATUSMAP[unpatched] = "Unpatched"
+# use when CVE is confirmed by upstream but fix is still not available
+CVE_CHECK_STATUSMAP[vulnerable-investigating] = "Unpatched"
+
+# used for migration from old concept, do not use for new vulnerabilities
+CVE_CHECK_STATUSMAP[ignored] = "Ignored"
+# use when NVD DB wrongly indicates vulnerability which is actually for a different component
+CVE_CHECK_STATUSMAP[cpe-incorrect] = "Ignored"
+# use when upstream does not accept the report as a vulnerability (e.g. works as designed)
+CVE_CHECK_STATUSMAP[disputed] = "Ignored"
+# use when vulnerability depends on build or runtime configuration which is not used
+CVE_CHECK_STATUSMAP[not-applicable-config] = "Ignored"
+# use when vulnerability affects other platform (e.g. Windows or Debian)
+CVE_CHECK_STATUSMAP[not-applicable-platform] = "Ignored"
+# use when upstream acknowledged the vulnerability but does not plan to fix it
+CVE_CHECK_STATUSMAP[upstream-wontfix] = "Ignored"
+
# Layers to be excluded
CVE_CHECK_LAYER_EXCLUDELIST ??= ""
@@ -88,6 +122,24 @@ CVE_CHECK_LAYER_INCLUDELIST ??= ""
# set to "alphabetical" for version using single alphabetical character as increment release
CVE_VERSION_SUFFIX ??= ""
+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)
+}
+
def generate_json_report(d, out_path, link_path):
if os.path.exists(d.getVar("CVE_CHECK_SUMMARY_INDEX_PATH")):
import json
@@ -260,7 +312,7 @@ def check_cves(d, patched_cves):
"""
Connect to the NVD database and find unpatched cves.
"""
- from oe.cve_check import Version, convert_cve_version
+ from oe.cve_check import Version, convert_cve_version, decode_cve_status
pn = d.getVar("PN")
real_pv = d.getVar("PV")
@@ -282,7 +334,12 @@ def check_cves(d, patched_cves):
bb.note("Recipe has been skipped by cve-check")
return ([], [], [], [])
- cve_ignore = d.getVar("CVE_CHECK_IGNORE").split()
+ # Convert CVE_STATUS into ignored CVEs and check validity
+ cve_ignore = []
+ for cve in (d.getVarFlags("CVE_STATUS") or {}):
+ decoded_status, _, _ = decode_cve_status(d, cve)
+ if decoded_status == "Ignored":
+ cve_ignore.append(cve)
import sqlite3
db_file = d.expand("file:${CVE_CHECK_DB_FILE}?mode=ro")
@@ -413,6 +470,8 @@ def cve_write_data_text(d, patched, unpatched, ignored, cve_data):
CVE manifest if enabled.
"""
+ from oe.cve_check import decode_cve_status
+
cve_file = d.getVar("CVE_CHECK_LOG")
fdir_name = d.getVar("FILE_DIRNAME")
layer = fdir_name.split("/")[-3]
@@ -441,20 +500,27 @@ def cve_write_data_text(d, patched, unpatched, ignored, cve_data):
is_patched = cve in patched
is_ignored = cve in ignored
+ status = "Unpatched"
if (is_patched or is_ignored) and not report_all:
continue
+ if is_ignored:
+ status = "Ignored"
+ elif is_patched:
+ status = "Patched"
+ else:
+ # default value of status is Unpatched
+ unpatched_cves.append(cve)
write_string += "LAYER: %s\n" % layer
write_string += "PACKAGE NAME: %s\n" % d.getVar("PN")
write_string += "PACKAGE VERSION: %s%s\n" % (d.getVar("EXTENDPE"), d.getVar("PV"))
write_string += "CVE: %s\n" % cve
- if is_ignored:
- write_string += "CVE STATUS: Ignored\n"
- elif is_patched:
- write_string += "CVE STATUS: Patched\n"
- else:
- unpatched_cves.append(cve)
- write_string += "CVE STATUS: Unpatched\n"
+ write_string += "CVE STATUS: %s\n" % status
+ _, detail, description = decode_cve_status(d, cve)
+ if detail:
+ write_string += "CVE DETAIL: %s\n" % detail
+ if description:
+ write_string += "CVE DESCRIPTION: %s\n" % description
write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"]
write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["scorev2"]
write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["scorev3"]
@@ -516,6 +582,8 @@ def cve_write_data_json(d, patched, unpatched, ignored, cve_data, cve_status):
Prepare CVE data for the JSON format, then write it.
"""
+ from oe.cve_check import decode_cve_status
+
output = {"version":"1", "package": []}
nvd_link = "https://nvd.nist.gov/vuln/detail/"
@@ -576,6 +644,11 @@ def cve_write_data_json(d, patched, unpatched, ignored, cve_data, cve_status):
"status" : status,
"link": issue_link
}
+ _, detail, description = decode_cve_status(d, cve)
+ if detail:
+ cve_item["detail"] = detail
+ if description:
+ cve_item["description"] = description
cve_list.append(cve_item)
package_data["issue"] = cve_list
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
index dbaa0b373a..5bf3caac47 100644
--- a/meta/lib/oe/cve_check.py
+++ b/meta/lib/oe/cve_check.py
@@ -130,6 +130,13 @@ def get_patched_cves(d):
if not fname_match and not text_match:
bb.debug(2, "Patch %s doesn't solve CVEs" % patch_file)
+ # Search for additional patched CVEs
+ for cve in (d.getVarFlags("CVE_STATUS") or {}):
+ decoded_status, _, _ = decode_cve_status(d, cve)
+ if decoded_status == "Patched":
+ bb.debug(2, "CVE %s is additionally patched" % cve)
+ patched_cves.add(cve)
+
return patched_cves
@@ -218,3 +225,21 @@ def convert_cve_version(version):
return version + update
+def decode_cve_status(d, cve):
+ """
+ Convert CVE_STATUS into status, detail and description.
+ """
+ status = d.getVarFlag("CVE_STATUS", cve)
+ if status is None:
+ return ("", "", "")
+
+ status_split = status.split(':', 1)
+ detail = status_split[0]
+ description = status_split[1].strip() if (len(status_split) > 1) else ""
+
+ status_mapping = d.getVarFlag("CVE_CHECK_STATUSMAP", detail)
+ if status_mapping is None:
+ bb.warn('Invalid detail %s for CVE_STATUS[%s] = "%s", fallback to Unpatched' % (detail, cve, status))
+ status_mapping = "Unpatched"
+
+ return (status_mapping, detail, description)
--
2.41.0
next prev parent reply other threads:[~2023-06-22 12:00 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-05 11:18 [OE-core][PATCH] cve-check: add option to add additional patched CVEs Andrej Valek
2023-05-05 11:30 ` Richard Purdie
2023-05-05 11:36 ` Valek, Andrej
2023-05-05 11:59 ` Richard Purdie
2023-05-08 8:57 ` adrian.freihofer
2023-05-09 9:02 ` Ross Burton
2023-05-09 9:16 ` Richard Purdie
2023-05-09 9:32 ` Mikko Rapeli
2023-05-09 21:37 ` Douglas Royds
2023-05-10 6:56 ` Mikko Rapeli
2023-05-09 8:19 ` Michael Opdenacker
2023-05-17 5:41 ` [OE-core][PATCH v2] " Andrej Valek
2023-05-17 11:08 ` Mikko Rapeli
2023-05-19 6:24 ` [OE-core][PATCH v3 1/3] " Andrej Valek
2023-05-19 6:56 ` Mikko Rapeli
2023-05-19 7:44 ` Michael Opdenacker
2023-05-19 13:11 ` Marta Rybczynska
2023-05-20 7:43 ` Valek, Andrej
2023-05-22 7:57 ` Mikko Rapeli
2023-05-23 8:41 ` Valek, Andrej
2023-05-29 7:32 ` Valek, Andrej
2023-05-30 10:12 ` Richard Purdie
2023-06-02 21:10 ` adrian.freihofer
2023-06-02 21:27 ` Richard Purdie
2023-06-04 9:59 ` Sanjaykumar kantibhai Chitroda -X (schitrod - E-INFO CHIPS INC at Cisco)
2023-06-21 7:52 ` Richard Purdie
2023-05-19 6:24 ` [OE-core][PATCH v3 2/3] oeqa/selftest/cve_check: add check for optional "reason" value Andrej Valek
2023-05-19 6:24 ` [OE-core][PATCH v3 3/3] cve_check: convert CVE_CHECK_IGNORE to CVE_STATUS and CVE_STATUS_REASONING Andrej Valek
2023-05-19 8:18 ` [OE-core][PATCH v4 1/3] cve-check: add option to add additional patched CVEs Andrej Valek
2023-05-19 9:17 ` Mikko Rapeli
2023-05-19 13:09 ` Michael Opdenacker
2023-05-19 13:19 ` Valek, Andrej
2023-05-23 11:39 ` Sanjaykumar kantibhai Chitroda -X (schitrod - E-INFO CHIPS INC at Cisco)
2023-06-12 11:57 ` [OE-core][PATCH v5 0/2] CVE-check handling Andrej Valek
2023-06-12 11:57 ` [OE-core][PATCH v5 1/2] cve-check: add option to add additional patched CVEs Andrej Valek
2023-06-15 12:47 ` Richard Purdie
2023-06-12 11:57 ` [OE-core][dunfell][PATCH 2/2] curl: whitelists CVE-2022-42915, CVE-2022-42916 and CVE-2022-43551 Andrej Valek
2023-06-12 12:01 ` Valek, Andrej
2023-06-12 11:59 ` [OE-core][PATCH v5 2/2] oeqa/selftest/cve_check: add check for opt "detail" and "description" values Andrej Valek
2023-06-20 14:15 ` [OE-core][PATCH v6 0/2] RFC: CVE-check handling Andrej Valek
2023-06-20 14:15 ` [OE-core][PATCH v6 1/2] RFC: cve-check: add option to add additional patched CVEs Andrej Valek
2023-06-21 5:07 ` Sanjaykumar kantibhai Chitroda -X (schitrod - E-INFO CHIPS INC at Cisco)
2023-06-21 6:48 ` [PATCH " Siddharth
2023-06-21 7:55 ` [OE-core][PATCH " Luca Ceresoli
2023-06-20 14:15 ` [OE-core][PATCH v6 2/2] RFC: oeqa/selftest/cve_check: rework test to new cve status handling Andrej Valek
2023-06-22 6:59 ` [OE-core][PATCH v7 0/3] CVE-check handling Andrej Valek
2023-06-22 12:42 ` Luca Ceresoli
2023-06-22 13:50 ` Valek, Andrej
2023-06-22 13:55 ` Luca Ceresoli
2023-06-22 13:59 ` Valek, Andrej
2023-06-22 14:07 ` Valek, Andrej
2023-06-22 16:24 ` Luca Ceresoli
2023-06-22 6:59 ` [OE-core][PATCH v7 1/3] cve-check: add option to add additional patched CVEs Andrej Valek
2023-06-22 6:59 ` [OE-core][PATCH v7 2/3] oeqa/selftest/cve_check: rework test to new cve status handling Andrej Valek
2023-06-22 6:59 ` [OE-core][PATCH v7 3/3] cve_check: convert CVE_CHECK_IGNORE to CVE_STATUS Andrej Valek
2023-06-22 12:00 ` [OE-core][PATCH v8 0/3] CVE-check handling Andrej Valek
2023-06-22 12:00 ` Andrej Valek [this message]
2023-06-23 10:02 ` [OE-core][PATCH v8 1/3] cve-check: add option to add additional patched CVEs Ross Burton
2023-06-23 11:22 ` Valek, Andrej
2023-06-22 12:00 ` [OE-core][PATCH v8 2/3] oeqa/selftest/cve_check: rework test to new cve status handling Andrej Valek
2023-06-22 12:00 ` [OE-core][PATCH v8 3/3] cve_check: convert CVE_CHECK_IGNORE to CVE_STATUS Andrej Valek
2023-06-23 11:14 ` [OE-core][PATCH v9 0/3] CVE-check handling Andrej Valek
2023-07-19 10:26 ` Valek, Andrej
2023-07-19 10:54 ` Richard Purdie
2023-07-19 11:16 ` Ross Burton
2023-07-19 12:03 ` Valek, Andrej
2023-07-20 16:41 ` Marta Rybczynska
2023-06-23 11:14 ` [OE-core][PATCH v9 1/3] cve-check: add option to add additional patched CVEs Andrej Valek
2023-06-23 11:14 ` [OE-core][PATCH v9 2/3] oeqa/selftest/cve_check: rework test to new cve status handling Andrej Valek
2023-06-23 11:14 ` [OE-core][PATCH v9 3/3] cve_check: convert CVE_CHECK_IGNORE to CVE_STATUS Andrej Valek
2023-07-20 7:19 ` [OE-core][PATCH] " Andrej Valek
2023-05-19 8:18 ` [OE-core][PATCH v4 2/3] oeqa/selftest/cve_check: add check for optional "reason" value Andrej Valek
2023-05-19 8:18 ` [OE-core][PATCH v4 3/3] cve_check: convert CVE_CHECK_IGNORE to CVE_STATUS and CVE_STATUS_REASONING Andrej Valek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230622120009.28939-2-andrej.valek@siemens.com \
--to=andrej.valek@siemens.com \
--cc=openembedded-core@lists.openembedded.org \
--cc=peter.marko@siemens.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox