1
0
mirror of https://git.yoctoproject.org/poky synced 2026-06-02 13:29:49 +00:00

cve-check: Remove dependency to cve-check-tool-native

Use the new update-cve-db recipe to update database.

(From OE-Core rev: bc144b028f6f51252f4359248f6921028bcb6780)

Signed-off-by: Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Pierre Le Magourou
2019-06-19 15:59:38 +02:00
committed by Richard Purdie
parent 1704028878
commit 05fb9db633
+25 -44
View File
@@ -26,7 +26,7 @@ CVE_PRODUCT ??= "${BPN}"
CVE_VERSION ??= "${PV}" CVE_VERSION ??= "${PV}"
CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK" CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK"
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvd.db" CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvd-json.db"
CVE_CHECK_LOG ?= "${T}/cve.log" CVE_CHECK_LOG ?= "${T}/cve.log"
CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check" CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check"
@@ -62,7 +62,7 @@ python do_cve_check () {
} }
addtask cve_check after do_unpack before do_build addtask cve_check after do_unpack before do_build
do_cve_check[depends] = "cve-check-tool-native:do_populate_sysroot cve-check-tool-native:do_populate_cve_db" do_cve_check[depends] = "cve-update-db:do_populate_cve_db"
do_cve_check[nostamp] = "1" do_cve_check[nostamp] = "1"
python cve_check_cleanup () { python cve_check_cleanup () {
@@ -163,61 +163,40 @@ def get_patches_cves(d):
def check_cves(d, patched_cves): def check_cves(d, patched_cves):
""" """
Run cve-check-tool looking for patched and unpatched CVEs. Connect to the NVD database and find unpatched cves.
""" """
import ast, csv, tempfile, subprocess, io import ast, csv, tempfile, subprocess, io
cves_patched = []
cves_unpatched = [] cves_unpatched = []
bpn = d.getVar("CVE_PRODUCT") bpn = d.getVar("CVE_PRODUCT")
# If this has been unset then we're not scanning for CVEs here (for example, image recipes) # If this has been unset then we're not scanning for CVEs here (for example, image recipes)
if not bpn: if not bpn:
return ([], []) return ([], [])
pv = d.getVar("CVE_VERSION").split("+git")[0] pv = d.getVar("CVE_VERSION").split("+git")[0]
cves = " ".join(patched_cves)
cve_db_dir = d.getVar("CVE_CHECK_DB_DIR")
cve_whitelist = ast.literal_eval(d.getVar("CVE_CHECK_CVE_WHITELIST")) cve_whitelist = ast.literal_eval(d.getVar("CVE_CHECK_CVE_WHITELIST"))
cve_cmd = "cve-check-tool"
cmd = [cve_cmd, "--no-html", "--skip-update", "--csv", "--not-affected", "-t", "faux", "-d", cve_db_dir]
# If the recipe has been whitlisted we return empty lists # If the recipe has been whitlisted we return empty lists
if d.getVar("PN") in d.getVar("CVE_CHECK_PN_WHITELIST").split(): if d.getVar("PN") in d.getVar("CVE_CHECK_PN_WHITELIST").split():
bb.note("Recipe has been whitelisted, skipping check") bb.note("Recipe has been whitelisted, skipping check")
return ([], []) return ([], [])
try: import sqlite3
# Write the faux CSV file to be used with cve-check-tool db_file = d.getVar("CVE_CHECK_DB_FILE")
fd, faux = tempfile.mkstemp(prefix="cve-faux-") conn = sqlite3.connect(db_file)
with os.fdopen(fd, "w") as f: c = conn.cursor()
for pn in bpn.split(): query = "SELECT * FROM PRODUCTS WHERE PRODUCT IS '%s' AND VERSION IS '%s';"
f.write("%s,%s,%s,\n" % (pn, pv, cves)) for row in c.execute(query % (bpn,pv)):
cmd.append(faux) cve = row[1]
if pv in cve_whitelist.get(cve,[]):
bb.note("%s-%s has been whitelisted for %s" % (bpn, pv, cve))
elif cve in patched_cves:
bb.note("%s has been patched" % (cve))
else:
cves_unpatched.append(cve)
bb.debug(2, "%s-%s is not patched for %s" % (bpn, pv, cve))
conn.close()
output = subprocess.check_output(cmd).decode("utf-8") return (list(patched_cves), cves_unpatched)
bb.debug(2, "Output of command %s:\n%s" % ("\n".join(cmd), output))
except subprocess.CalledProcessError as e:
bb.warn("Couldn't check for CVEs: %s (output %s)" % (e, e.output))
finally:
os.remove(faux)
for row in csv.reader(io.StringIO(output)):
# Third row has the unpatched CVEs
if row[2]:
for cve in row[2].split():
# Skip if the CVE has been whitlisted for the current version
if pv in cve_whitelist.get(cve,[]):
bb.note("%s-%s has been whitelisted for %s" % (bpn, pv, cve))
else:
cves_unpatched.append(cve)
bb.debug(2, "%s-%s is not patched for %s" % (bpn, pv, cve))
# Fourth row has patched CVEs
if row[3]:
for cve in row[3].split():
cves_patched.append(cve)
bb.debug(2, "%s-%s is patched for %s" % (bpn, pv, cve))
return (cves_patched, cves_unpatched)
def get_cve_info(d, cves): def get_cve_info(d, cves):
""" """
@@ -241,9 +220,10 @@ def get_cve_info(d, cves):
for row in cur.execute(query, tuple(cves)): for row in cur.execute(query, tuple(cves)):
cve_data[row[0]] = {} cve_data[row[0]] = {}
cve_data[row[0]]["summary"] = row[1] cve_data[row[0]]["summary"] = row[1]
cve_data[row[0]]["score"] = row[2] cve_data[row[0]]["scorev2"] = row[2]
cve_data[row[0]]["modified"] = row[3] cve_data[row[0]]["scorev3"] = row[3]
cve_data[row[0]]["vector"] = row[4] cve_data[row[0]]["modified"] = row[4]
cve_data[row[0]]["vector"] = row[5]
conn.close() conn.close()
return cve_data return cve_data
@@ -270,7 +250,8 @@ def cve_write_data(d, patched, unpatched, cve_data):
unpatched_cves.append(cve) unpatched_cves.append(cve)
write_string += "CVE STATUS: Unpatched\n" write_string += "CVE STATUS: Unpatched\n"
write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"] write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"]
write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["score"] write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["scorev2"]
write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["scorev3"]
write_string += "VECTOR: %s\n" % cve_data[cve]["vector"] write_string += "VECTOR: %s\n" % cve_data[cve]["vector"]
write_string += "MORE INFORMATION: %s%s\n\n" % (nvd_link, cve) write_string += "MORE INFORMATION: %s%s\n\n" % (nvd_link, cve)