@@ -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"