From 74b562e1cedc484cf417b98d67a5ee37a340dc3b Mon Sep 17 00:00:00 2001 From: Pierre Le Magourou Date: Wed, 6 Nov 2019 17:37:27 +0200 Subject: cve-check: Update unpatched CVE matching Now that cve-update-db added CPE information to NVD database. We can check for unpatched versions with operators '<', '<=', '>', and '>='. (From OE-Core rev: bc0195be1b15bcffe60127bc5e8b7011a853c2ed) (From OE-Core rev: 48793a3b74bfaa5ffe6191d21f64aef3720433db) Signed-off-by: Pierre Le Magourou Signed-off-by: Richard Purdie --- meta/classes/cve-check.bbclass | 54 +++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 14 deletions(-) (limited to 'meta/classes') diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass index 6ffa0c4688..ffd624333f 100644 --- a/meta/classes/cve-check.bbclass +++ b/meta/classes/cve-check.bbclass @@ -26,7 +26,7 @@ CVE_PRODUCT ??= "${BPN}" CVE_VERSION ??= "${PV}" CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK" -CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvd-json.db" +CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve.db" CVE_CHECK_LOG ?= "${T}/cve.log" CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check" @@ -189,27 +189,53 @@ def check_cves(d, patched_cves): conn = sqlite3.connect(db_file) c = conn.cursor() - query = """SELECT * FROM PRODUCTS WHERE - (PRODUCT IS '{0}' AND VERSION = '{1}' AND OPERATOR IS '=') OR - (PRODUCT IS '{0}' AND OPERATOR IS '<=');""" + query = "SELECT * FROM PRODUCTS WHERE PRODUCT IS '{0}';" + for product in products: for row in c.execute(query.format(product, pv)): cve = row[1] - version = row[4] - - try: - discardVersion = LooseVersion(version) < LooseVersion(pv) - except: - discardVersion = True + version_start = row[4] + operator_start = row[5] + version_end = row[6] + operator_end = row[7] if pv in cve_whitelist.get(cve, []): bb.note("%s-%s has been whitelisted for %s" % (product, pv, cve)) elif cve in patched_cves: bb.note("%s has been patched" % (cve)) - elif discardVersion: - bb.debug(2, "Do not consider version %s " % (version)) else: - cves_unpatched.append(cve) + if (operator_start == '=' and pv == version_start): + cves_unpatched.append(cve) + else: + if operator_start: + try: + to_append_start = (operator_start == '>=' and LooseVersion(pv) >= LooseVersion(version_start)) + to_append_start |= (operator_start == '>' and LooseVersion(pv) > LooseVersion(version_start)) + except: + bb.note("%s: Failed to compare %s %s %s for %s" % + (product, pv, operator_start, version_start, cve)) + to_append_start = False + else: + to_append_start = False + + if operator_end: + try: + to_append_end = (operator_end == '<=' and LooseVersion(pv) <= LooseVersion(version_end)) + to_append_end |= (operator_end == '<' and LooseVersion(pv) < LooseVersion(version_end)) + except: + bb.note("%s: Failed to compare %s %s %s for %s" % + (product, pv, operator_end, version_end, cve)) + to_append_end = False + else: + to_append_end = False + + if operator_start and operator_end: + to_append = to_append_start and to_append_end + else: + to_append = to_append_start or to_append_end + + if to_append: + cves_unpatched.append(cve) bb.debug(2, "%s-%s is not patched for %s" % (product, pv, cve)) conn.close() @@ -217,7 +243,7 @@ def check_cves(d, patched_cves): def get_cve_info(d, cves): """ - Get CVE information from the database used by cve-check-tool. + Get CVE information from the database. Unfortunately the only way to get CVE info is set the output to html (hard to parse) or query directly the database. -- cgit v1.2.3-54-g00ecf