diff options
| author | Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com> | 2019-06-19 15:59:38 +0200 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-06-20 13:14:21 +0100 |
| commit | 05fb9db63372d32e6ab3cb56186d7bcb09e26b43 (patch) | |
| tree | 90e6899d35e4097fc9003f03baf1c90ac109b4af /meta/classes/cve-check.bbclass | |
| parent | 1704028878e6e6dbd806c2822b8794047b0f031a (diff) | |
| download | poky-05fb9db63372d32e6ab3cb56186d7bcb09e26b43.tar.gz | |
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>
Diffstat (limited to 'meta/classes/cve-check.bbclass')
| -rw-r--r-- | meta/classes/cve-check.bbclass | 71 |
1 files changed, 26 insertions, 45 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass index 743bc08a4f..28619c7bd4 100644 --- a/meta/classes/cve-check.bbclass +++ b/meta/classes/cve-check.bbclass | |||
| @@ -26,7 +26,7 @@ CVE_PRODUCT ??= "${BPN}" | |||
| 26 | CVE_VERSION ??= "${PV}" | 26 | CVE_VERSION ??= "${PV}" |
| 27 | 27 | ||
| 28 | CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK" | 28 | CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK" |
| 29 | CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvd.db" | 29 | CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvd-json.db" |
| 30 | 30 | ||
| 31 | CVE_CHECK_LOG ?= "${T}/cve.log" | 31 | CVE_CHECK_LOG ?= "${T}/cve.log" |
| 32 | CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check" | 32 | CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check" |
| @@ -62,7 +62,7 @@ python do_cve_check () { | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | addtask cve_check after do_unpack before do_build | 64 | addtask cve_check after do_unpack before do_build |
| 65 | do_cve_check[depends] = "cve-check-tool-native:do_populate_sysroot cve-check-tool-native:do_populate_cve_db" | 65 | do_cve_check[depends] = "cve-update-db:do_populate_cve_db" |
| 66 | do_cve_check[nostamp] = "1" | 66 | do_cve_check[nostamp] = "1" |
| 67 | 67 | ||
| 68 | python cve_check_cleanup () { | 68 | python cve_check_cleanup () { |
| @@ -163,61 +163,40 @@ def get_patches_cves(d): | |||
| 163 | 163 | ||
| 164 | def check_cves(d, patched_cves): | 164 | def check_cves(d, patched_cves): |
| 165 | """ | 165 | """ |
| 166 | Run cve-check-tool looking for patched and unpatched CVEs. | 166 | Connect to the NVD database and find unpatched cves. |
| 167 | """ | 167 | """ |
| 168 | |||
| 169 | import ast, csv, tempfile, subprocess, io | 168 | import ast, csv, tempfile, subprocess, io |
| 170 | 169 | ||
| 171 | cves_patched = [] | ||
| 172 | cves_unpatched = [] | 170 | cves_unpatched = [] |
| 173 | bpn = d.getVar("CVE_PRODUCT") | 171 | bpn = d.getVar("CVE_PRODUCT") |
| 174 | # If this has been unset then we're not scanning for CVEs here (for example, image recipes) | 172 | # If this has been unset then we're not scanning for CVEs here (for example, image recipes) |
| 175 | if not bpn: | 173 | if not bpn: |
| 176 | return ([], []) | 174 | return ([], []) |
| 177 | pv = d.getVar("CVE_VERSION").split("+git")[0] | 175 | pv = d.getVar("CVE_VERSION").split("+git")[0] |
| 178 | cves = " ".join(patched_cves) | ||
| 179 | cve_db_dir = d.getVar("CVE_CHECK_DB_DIR") | ||
| 180 | cve_whitelist = ast.literal_eval(d.getVar("CVE_CHECK_CVE_WHITELIST")) | 176 | cve_whitelist = ast.literal_eval(d.getVar("CVE_CHECK_CVE_WHITELIST")) |
| 181 | cve_cmd = "cve-check-tool" | ||
| 182 | cmd = [cve_cmd, "--no-html", "--skip-update", "--csv", "--not-affected", "-t", "faux", "-d", cve_db_dir] | ||
| 183 | 177 | ||
| 184 | # If the recipe has been whitlisted we return empty lists | 178 | # If the recipe has been whitlisted we return empty lists |
| 185 | if d.getVar("PN") in d.getVar("CVE_CHECK_PN_WHITELIST").split(): | 179 | if d.getVar("PN") in d.getVar("CVE_CHECK_PN_WHITELIST").split(): |
| 186 | bb.note("Recipe has been whitelisted, skipping check") | 180 | bb.note("Recipe has been whitelisted, skipping check") |
| 187 | return ([], []) | 181 | return ([], []) |
| 188 | 182 | ||
| 189 | try: | 183 | import sqlite3 |
| 190 | # Write the faux CSV file to be used with cve-check-tool | 184 | db_file = d.getVar("CVE_CHECK_DB_FILE") |
| 191 | fd, faux = tempfile.mkstemp(prefix="cve-faux-") | 185 | conn = sqlite3.connect(db_file) |
| 192 | with os.fdopen(fd, "w") as f: | 186 | c = conn.cursor() |
| 193 | for pn in bpn.split(): | 187 | query = "SELECT * FROM PRODUCTS WHERE PRODUCT IS '%s' AND VERSION IS '%s';" |
| 194 | f.write("%s,%s,%s,\n" % (pn, pv, cves)) | 188 | for row in c.execute(query % (bpn,pv)): |
| 195 | cmd.append(faux) | 189 | cve = row[1] |
| 196 | 190 | if pv in cve_whitelist.get(cve,[]): | |
| 197 | output = subprocess.check_output(cmd).decode("utf-8") | 191 | bb.note("%s-%s has been whitelisted for %s" % (bpn, pv, cve)) |
| 198 | bb.debug(2, "Output of command %s:\n%s" % ("\n".join(cmd), output)) | 192 | elif cve in patched_cves: |
| 199 | except subprocess.CalledProcessError as e: | 193 | bb.note("%s has been patched" % (cve)) |
| 200 | bb.warn("Couldn't check for CVEs: %s (output %s)" % (e, e.output)) | 194 | else: |
| 201 | finally: | 195 | cves_unpatched.append(cve) |
| 202 | os.remove(faux) | 196 | bb.debug(2, "%s-%s is not patched for %s" % (bpn, pv, cve)) |
| 203 | 197 | conn.close() | |
| 204 | for row in csv.reader(io.StringIO(output)): | 198 | |
| 205 | # Third row has the unpatched CVEs | 199 | return (list(patched_cves), cves_unpatched) |
| 206 | if row[2]: | ||
| 207 | for cve in row[2].split(): | ||
| 208 | # Skip if the CVE has been whitlisted for the current version | ||
| 209 | if pv in cve_whitelist.get(cve,[]): | ||
| 210 | bb.note("%s-%s has been whitelisted for %s" % (bpn, pv, cve)) | ||
| 211 | else: | ||
| 212 | cves_unpatched.append(cve) | ||
| 213 | bb.debug(2, "%s-%s is not patched for %s" % (bpn, pv, cve)) | ||
| 214 | # Fourth row has patched CVEs | ||
| 215 | if row[3]: | ||
| 216 | for cve in row[3].split(): | ||
| 217 | cves_patched.append(cve) | ||
| 218 | bb.debug(2, "%s-%s is patched for %s" % (bpn, pv, cve)) | ||
| 219 | |||
| 220 | return (cves_patched, cves_unpatched) | ||
| 221 | 200 | ||
| 222 | def get_cve_info(d, cves): | 201 | def get_cve_info(d, cves): |
| 223 | """ | 202 | """ |
| @@ -241,9 +220,10 @@ def get_cve_info(d, cves): | |||
| 241 | for row in cur.execute(query, tuple(cves)): | 220 | for row in cur.execute(query, tuple(cves)): |
| 242 | cve_data[row[0]] = {} | 221 | cve_data[row[0]] = {} |
| 243 | cve_data[row[0]]["summary"] = row[1] | 222 | cve_data[row[0]]["summary"] = row[1] |
| 244 | cve_data[row[0]]["score"] = row[2] | 223 | cve_data[row[0]]["scorev2"] = row[2] |
| 245 | cve_data[row[0]]["modified"] = row[3] | 224 | cve_data[row[0]]["scorev3"] = row[3] |
| 246 | cve_data[row[0]]["vector"] = row[4] | 225 | cve_data[row[0]]["modified"] = row[4] |
| 226 | cve_data[row[0]]["vector"] = row[5] | ||
| 247 | conn.close() | 227 | conn.close() |
| 248 | 228 | ||
| 249 | return cve_data | 229 | return cve_data |
| @@ -270,7 +250,8 @@ def cve_write_data(d, patched, unpatched, cve_data): | |||
| 270 | unpatched_cves.append(cve) | 250 | unpatched_cves.append(cve) |
| 271 | write_string += "CVE STATUS: Unpatched\n" | 251 | write_string += "CVE STATUS: Unpatched\n" |
| 272 | write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"] | 252 | write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"] |
| 273 | write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["score"] | 253 | write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["scorev2"] |
| 254 | write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["scorev3"] | ||
| 274 | write_string += "VECTOR: %s\n" % cve_data[cve]["vector"] | 255 | write_string += "VECTOR: %s\n" % cve_data[cve]["vector"] |
| 275 | write_string += "MORE INFORMATION: %s%s\n\n" % (nvd_link, cve) | 256 | write_string += "MORE INFORMATION: %s%s\n\n" % (nvd_link, cve) |
| 276 | 257 | ||
