summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarta Rybczynska <rybczynska@gmail.com>2022-06-23 19:42:29 +0200
committerSteve Sakoman <steve@sakoman.com>2022-06-28 04:35:47 -1000
commit14b3c0ca46a0aa97565a24b7a5116306237d7cfe (patch)
tree59bcee849f81e27143e2dce3719a5bdad50ebc96
parent097469513f6dea7c678438e71a152f4e77fe670d (diff)
downloadopenembedded-core-contrib-14b3c0ca46a0aa97565a24b7a5116306237d7cfe.tar.gz
cve-check: add support for Ignored CVEs
Ignored CVEs aren't patched, but do not apply in our configuration for some reason. Up till now they were only partially supported and reported as "Patched". This patch adds separate reporting of Ignored CVEs. The variable CVE_CHECK_REPORT_PATCHED now manages reporting of both patched and ignored CVEs. Signed-off-by: Marta Rybczynska <marta.rybczynska@huawei.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> (cherry-picked from c773102d4828fc4ddd1024f6115d577e23f1afe4) Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/classes/cve-check.bbclass41
1 files changed, 29 insertions, 12 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index 894cebaaa4..d0f6970db8 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -47,7 +47,9 @@ CVE_CHECK_MANIFEST_JSON ?= "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX
CVE_CHECK_COPY_FILES ??= "1"
CVE_CHECK_CREATE_MANIFEST ??= "1"
+# Report Patched or Ignored/Whitelisted CVEs
CVE_CHECK_REPORT_PATCHED ??= "1"
+
CVE_CHECK_SHOW_WARNINGS ??= "1"
# Provide text output
@@ -142,7 +144,7 @@ python do_cve_check () {
bb.fatal("Failure in searching patches")
whitelisted, patched, unpatched, status = check_cves(d, patched_cves)
if patched or unpatched or (d.getVar("CVE_CHECK_COVERAGE") == "1" and status):
- cve_data = get_cve_info(d, patched + unpatched)
+ cve_data = get_cve_info(d, patched + unpatched + whitelisted)
cve_write_data(d, patched, unpatched, whitelisted, cve_data, status)
else:
bb.note("No CVE database found, skipping CVE check")
@@ -315,6 +317,7 @@ def check_cves(d, patched_cves):
suffix = d.getVar("CVE_VERSION_SUFFIX")
cves_unpatched = []
+ cves_ignored = []
cves_status = []
cves_in_recipe = False
# CVE_PRODUCT can contain more than one product (eg. curl/libcurl)
@@ -349,8 +352,7 @@ def check_cves(d, patched_cves):
if cve in cve_whitelist:
bb.note("%s-%s has been whitelisted for %s" % (product, pv, cve))
- # TODO: this should be in the report as 'whitelisted'
- patched_cves.add(cve)
+ cves_ignored.append(cve)
continue
elif cve in patched_cves:
bb.note("%s has been patched" % (cve))
@@ -362,9 +364,13 @@ def check_cves(d, patched_cves):
cves_in_recipe = True
vulnerable = False
+ ignored = False
+
for row in conn.execute("SELECT * FROM PRODUCTS WHERE ID IS ? AND PRODUCT IS ? AND VENDOR LIKE ?", (cve, product, vendor)):
(_, _, _, version_start, operator_start, version_end, operator_end) = row
#bb.debug(2, "Evaluating row " + str(row))
+ if cve in cve_whitelist:
+ ignored = True
if (operator_start == '=' and pv == version_start) or version_start == '-':
vulnerable = True
@@ -397,13 +403,16 @@ def check_cves(d, patched_cves):
vulnerable = vulnerable_start or vulnerable_end
if vulnerable:
- bb.note("%s-%s is vulnerable to %s" % (pn, real_pv, cve))
- cves_unpatched.append(cve)
+ if ignored:
+ bb.note("%s is ignored in %s-%s" % (cve, pn, real_pv))
+ cves_ignored.append(cve)
+ else:
+ bb.note("%s-%s is vulnerable to %s" % (pn, real_pv, cve))
+ cves_unpatched.append(cve)
break
if not vulnerable:
bb.note("%s-%s is not vulnerable to %s" % (pn, real_pv, cve))
- # TODO: not patched but not vulnerable
patched_cves.add(cve)
if not cves_in_product:
@@ -412,7 +421,7 @@ def check_cves(d, patched_cves):
conn.close()
- return (list(cve_whitelist), list(patched_cves), cves_unpatched, cves_status)
+ return (list(cves_ignored), list(patched_cves), cves_unpatched, cves_status)
def get_cve_info(d, cves):
"""
@@ -450,6 +459,8 @@ def cve_write_data_text(d, patched, unpatched, whitelisted, cve_data):
include_layers = d.getVar("CVE_CHECK_LAYER_INCLUDELIST").split()
exclude_layers = d.getVar("CVE_CHECK_LAYER_EXCLUDELIST").split()
+ report_all = d.getVar("CVE_CHECK_REPORT_PATCHED") == "1"
+
if exclude_layers and layer in exclude_layers:
return
@@ -457,7 +468,7 @@ def cve_write_data_text(d, patched, unpatched, whitelisted, cve_data):
return
# Early exit, the text format does not report packages without CVEs
- if not patched+unpatched:
+ if not patched+unpatched+whitelisted:
return
nvd_link = "https://nvd.nist.gov/vuln/detail/"
@@ -467,13 +478,16 @@ def cve_write_data_text(d, patched, unpatched, whitelisted, cve_data):
for cve in sorted(cve_data):
is_patched = cve in patched
- if is_patched and (d.getVar("CVE_CHECK_REPORT_PATCHED") != "1"):
+ is_ignored = cve in whitelisted
+
+ if (is_patched or is_ignored) and not report_all:
continue
+
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 cve in whitelisted:
+ if is_ignored:
write_string += "CVE STATUS: Whitelisted\n"
elif is_patched:
write_string += "CVE STATUS: Patched\n"
@@ -550,6 +564,8 @@ def cve_write_data_json(d, patched, unpatched, ignored, cve_data, cve_status):
include_layers = d.getVar("CVE_CHECK_LAYER_INCLUDELIST").split()
exclude_layers = d.getVar("CVE_CHECK_LAYER_EXCLUDELIST").split()
+ report_all = d.getVar("CVE_CHECK_REPORT_PATCHED") == "1"
+
if exclude_layers and layer in exclude_layers:
return
@@ -576,10 +592,11 @@ def cve_write_data_json(d, patched, unpatched, ignored, cve_data, cve_status):
for cve in sorted(cve_data):
is_patched = cve in patched
+ is_ignored = cve in ignored
status = "Unpatched"
- if is_patched and (d.getVar("CVE_CHECK_REPORT_PATCHED") != "1"):
+ if (is_patched or is_ignored) and not report_all:
continue
- if cve in ignored:
+ if is_ignored:
status = "Ignored"
elif is_patched:
status = "Patched"