diff options
-rw-r--r-- | meta/classes/cve-check.bbclass | 116 |
1 files changed, 1 insertions, 115 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass index 0d7c8a5835..a5104f210b 100644 --- a/meta/classes/cve-check.bbclass +++ b/meta/classes/cve-check.bbclass | |||
@@ -36,20 +36,15 @@ CVE_CHECK_DB_DIR ?= "${STAGING_DIR}/CVE_CHECK" | |||
36 | CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/${CVE_CHECK_DB_FILENAME}" | 36 | CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/${CVE_CHECK_DB_FILENAME}" |
37 | CVE_CHECK_DB_FILE_LOCK ?= "${CVE_CHECK_DB_FILE}.lock" | 37 | CVE_CHECK_DB_FILE_LOCK ?= "${CVE_CHECK_DB_FILE}.lock" |
38 | 38 | ||
39 | CVE_CHECK_LOG ?= "${T}/cve.log" | ||
40 | CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check" | ||
41 | CVE_CHECK_SUMMARY_DIR ?= "${LOG_DIR}/cve" | 39 | CVE_CHECK_SUMMARY_DIR ?= "${LOG_DIR}/cve" |
42 | CVE_CHECK_SUMMARY_FILE_NAME ?= "cve-summary" | 40 | CVE_CHECK_SUMMARY_FILE_NAME ?= "cve-summary" |
43 | CVE_CHECK_SUMMARY_FILE ?= "${CVE_CHECK_SUMMARY_DIR}/${CVE_CHECK_SUMMARY_FILE_NAME}" | ||
44 | CVE_CHECK_SUMMARY_FILE_NAME_JSON = "cve-summary.json" | 41 | CVE_CHECK_SUMMARY_FILE_NAME_JSON = "cve-summary.json" |
45 | CVE_CHECK_SUMMARY_INDEX_PATH = "${CVE_CHECK_SUMMARY_DIR}/cve-summary-index.txt" | 42 | CVE_CHECK_SUMMARY_INDEX_PATH = "${CVE_CHECK_SUMMARY_DIR}/cve-summary-index.txt" |
46 | 43 | ||
47 | CVE_CHECK_LOG_JSON ?= "${T}/cve.json" | 44 | CVE_CHECK_LOG_JSON ?= "${T}/cve.json" |
48 | 45 | ||
49 | CVE_CHECK_DIR ??= "${DEPLOY_DIR}/cve" | 46 | CVE_CHECK_DIR ??= "${DEPLOY_DIR}/cve" |
50 | CVE_CHECK_RECIPE_FILE ?= "${CVE_CHECK_DIR}/${PN}" | ||
51 | CVE_CHECK_RECIPE_FILE_JSON ?= "${CVE_CHECK_DIR}/${PN}_cve.json" | 47 | CVE_CHECK_RECIPE_FILE_JSON ?= "${CVE_CHECK_DIR}/${PN}_cve.json" |
52 | CVE_CHECK_MANIFEST ?= "${IMGDEPLOYDIR}/${IMAGE_NAME}.cve" | ||
53 | CVE_CHECK_MANIFEST_JSON_SUFFIX ?= "json" | 48 | CVE_CHECK_MANIFEST_JSON_SUFFIX ?= "json" |
54 | CVE_CHECK_MANIFEST_JSON ?= "${IMGDEPLOYDIR}/${IMAGE_NAME}.${CVE_CHECK_MANIFEST_JSON_SUFFIX}" | 49 | CVE_CHECK_MANIFEST_JSON ?= "${IMGDEPLOYDIR}/${IMAGE_NAME}.${CVE_CHECK_MANIFEST_JSON_SUFFIX}" |
55 | CVE_CHECK_COPY_FILES ??= "1" | 50 | CVE_CHECK_COPY_FILES ??= "1" |
@@ -60,9 +55,6 @@ CVE_CHECK_REPORT_PATCHED ??= "1" | |||
60 | 55 | ||
61 | CVE_CHECK_SHOW_WARNINGS ??= "1" | 56 | CVE_CHECK_SHOW_WARNINGS ??= "1" |
62 | 57 | ||
63 | # Provide text output | ||
64 | CVE_CHECK_FORMAT_TEXT ??= "1" | ||
65 | |||
66 | # Provide JSON output | 58 | # Provide JSON output |
67 | CVE_CHECK_FORMAT_JSON ??= "1" | 59 | CVE_CHECK_FORMAT_JSON ??= "1" |
68 | 60 | ||
@@ -152,20 +144,11 @@ python cve_save_summary_handler () { | |||
152 | import datetime | 144 | import datetime |
153 | from oe.cve_check import update_symlinks | 145 | from oe.cve_check import update_symlinks |
154 | 146 | ||
155 | cve_tmp_file = d.getVar("CVE_CHECK_TMP_FILE") | ||
156 | |||
157 | cve_summary_name = d.getVar("CVE_CHECK_SUMMARY_FILE_NAME") | 147 | cve_summary_name = d.getVar("CVE_CHECK_SUMMARY_FILE_NAME") |
158 | cvelogpath = d.getVar("CVE_CHECK_SUMMARY_DIR") | 148 | cvelogpath = d.getVar("CVE_CHECK_SUMMARY_DIR") |
159 | bb.utils.mkdirhier(cvelogpath) | 149 | bb.utils.mkdirhier(cvelogpath) |
160 | 150 | ||
161 | timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S') | 151 | timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S') |
162 | cve_summary_file = os.path.join(cvelogpath, "%s-%s.txt" % (cve_summary_name, timestamp)) | ||
163 | |||
164 | if os.path.exists(cve_tmp_file): | ||
165 | shutil.copyfile(cve_tmp_file, cve_summary_file) | ||
166 | cvefile_link = os.path.join(cvelogpath, cve_summary_name) | ||
167 | update_symlinks(cve_summary_file, cvefile_link) | ||
168 | bb.plain("Complete CVE report summary created at: %s" % cvefile_link) | ||
169 | 152 | ||
170 | if d.getVar("CVE_CHECK_FORMAT_JSON") == "1": | 153 | if d.getVar("CVE_CHECK_FORMAT_JSON") == "1": |
171 | json_summary_link_name = os.path.join(cvelogpath, d.getVar("CVE_CHECK_SUMMARY_FILE_NAME_JSON")) | 154 | json_summary_link_name = os.path.join(cvelogpath, d.getVar("CVE_CHECK_SUMMARY_FILE_NAME_JSON")) |
@@ -206,7 +189,6 @@ python cve_check_cleanup () { | |||
206 | """ | 189 | """ |
207 | Delete the file used to gather all the CVE information. | 190 | Delete the file used to gather all the CVE information. |
208 | """ | 191 | """ |
209 | bb.utils.remove(e.data.getVar("CVE_CHECK_TMP_FILE")) | ||
210 | bb.utils.remove(e.data.getVar("CVE_CHECK_SUMMARY_INDEX_PATH")) | 192 | bb.utils.remove(e.data.getVar("CVE_CHECK_SUMMARY_INDEX_PATH")) |
211 | } | 193 | } |
212 | 194 | ||
@@ -224,9 +206,6 @@ python cve_check_write_rootfs_manifest () { | |||
224 | from oe.cve_check import cve_check_merge_jsons, update_symlinks | 206 | from oe.cve_check import cve_check_merge_jsons, update_symlinks |
225 | 207 | ||
226 | if d.getVar("CVE_CHECK_COPY_FILES") == "1": | 208 | if d.getVar("CVE_CHECK_COPY_FILES") == "1": |
227 | deploy_file = d.getVar("CVE_CHECK_RECIPE_FILE") | ||
228 | if os.path.exists(deploy_file): | ||
229 | bb.utils.remove(deploy_file) | ||
230 | deploy_file_json = d.getVar("CVE_CHECK_RECIPE_FILE_JSON") | 209 | deploy_file_json = d.getVar("CVE_CHECK_RECIPE_FILE_JSON") |
231 | if os.path.exists(deploy_file_json): | 210 | if os.path.exists(deploy_file_json): |
232 | bb.utils.remove(deploy_file_json) | 211 | bb.utils.remove(deploy_file_json) |
@@ -246,19 +225,13 @@ python cve_check_write_rootfs_manifest () { | |||
246 | json_data = {"version":"1", "package": []} | 225 | json_data = {"version":"1", "package": []} |
247 | text_data = "" | 226 | text_data = "" |
248 | enable_json = d.getVar("CVE_CHECK_FORMAT_JSON") == "1" | 227 | enable_json = d.getVar("CVE_CHECK_FORMAT_JSON") == "1" |
249 | enable_text = d.getVar("CVE_CHECK_FORMAT_TEXT") == "1" | ||
250 | 228 | ||
251 | save_pn = d.getVar("PN") | 229 | save_pn = d.getVar("PN") |
252 | 230 | ||
253 | for pkg in recipies: | 231 | for pkg in recipies: |
254 | # To be able to use the CVE_CHECK_RECIPE_FILE variable we have to evaluate | 232 | # To be able to use the CVE_CHECK_RECIPE_FILE_JSON variable we have to evaluate |
255 | # it with the different PN names set each time. | 233 | # it with the different PN names set each time. |
256 | d.setVar("PN", pkg) | 234 | d.setVar("PN", pkg) |
257 | if enable_text: | ||
258 | pkgfilepath = d.getVar("CVE_CHECK_RECIPE_FILE") | ||
259 | if os.path.exists(pkgfilepath): | ||
260 | with open(pkgfilepath) as pfile: | ||
261 | text_data += pfile.read() | ||
262 | 235 | ||
263 | if enable_json: | 236 | if enable_json: |
264 | pkgfilepath = d.getVar("CVE_CHECK_RECIPE_FILE_JSON") | 237 | pkgfilepath = d.getVar("CVE_CHECK_RECIPE_FILE_JSON") |
@@ -269,16 +242,6 @@ python cve_check_write_rootfs_manifest () { | |||
269 | 242 | ||
270 | d.setVar("PN", save_pn) | 243 | d.setVar("PN", save_pn) |
271 | 244 | ||
272 | if enable_text: | ||
273 | link_path = os.path.join(deploy_dir, "%s.cve" % link_name) | ||
274 | manifest_name = d.getVar("CVE_CHECK_MANIFEST") | ||
275 | |||
276 | with open(manifest_name, "w") as f: | ||
277 | f.write(text_data) | ||
278 | |||
279 | update_symlinks(manifest_name, link_path) | ||
280 | bb.plain("Image CVE report stored in: %s" % manifest_name) | ||
281 | |||
282 | if enable_json: | 245 | if enable_json: |
283 | manifest_name_suffix = d.getVar("CVE_CHECK_MANIFEST_JSON_SUFFIX") | 246 | manifest_name_suffix = d.getVar("CVE_CHECK_MANIFEST_JSON_SUFFIX") |
284 | link_path = os.path.join(deploy_dir, "%s.%s" % (link_name, manifest_name_suffix)) | 247 | link_path = os.path.join(deploy_dir, "%s.%s" % (link_name, manifest_name_suffix)) |
@@ -488,81 +451,6 @@ def get_cve_info(d, cve_data): | |||
488 | cursor.close() | 451 | cursor.close() |
489 | conn.close() | 452 | conn.close() |
490 | 453 | ||
491 | def cve_write_data_text(d, cve_data): | ||
492 | """ | ||
493 | Write CVE information in WORKDIR; and to CVE_CHECK_DIR, and | ||
494 | CVE manifest if enabled. | ||
495 | """ | ||
496 | |||
497 | cve_file = d.getVar("CVE_CHECK_LOG") | ||
498 | fdir_name = d.getVar("FILE_DIRNAME") | ||
499 | layer = fdir_name.split("/")[-3] | ||
500 | |||
501 | include_layers = d.getVar("CVE_CHECK_LAYER_INCLUDELIST").split() | ||
502 | exclude_layers = d.getVar("CVE_CHECK_LAYER_EXCLUDELIST").split() | ||
503 | |||
504 | report_all = d.getVar("CVE_CHECK_REPORT_PATCHED") == "1" | ||
505 | |||
506 | if exclude_layers and layer in exclude_layers: | ||
507 | return | ||
508 | |||
509 | if include_layers and layer not in include_layers: | ||
510 | return | ||
511 | |||
512 | # Early exit, the text format does not report packages without CVEs | ||
513 | if not len(cve_data): | ||
514 | return | ||
515 | |||
516 | nvd_link = "https://nvd.nist.gov/vuln/detail/" | ||
517 | write_string = "" | ||
518 | unpatched_cves = [] | ||
519 | bb.utils.mkdirhier(os.path.dirname(cve_file)) | ||
520 | |||
521 | for cve in sorted(cve_data): | ||
522 | if not report_all and (cve_data[cve]["abbrev-status"] == "Patched" or cve_data[cve]["abbrev-status"] == "Ignored"): | ||
523 | continue | ||
524 | write_string += "LAYER: %s\n" % layer | ||
525 | write_string += "PACKAGE NAME: %s\n" % d.getVar("PN") | ||
526 | write_string += "PACKAGE VERSION: %s%s\n" % (d.getVar("EXTENDPE"), d.getVar("PV")) | ||
527 | write_string += "CVE: %s\n" % cve | ||
528 | write_string += "CVE STATUS: %s\n" % cve_data[cve]["abbrev-status"] | ||
529 | |||
530 | if 'status' in cve_data[cve]: | ||
531 | write_string += "CVE DETAIL: %s\n" % cve_data[cve]["status"] | ||
532 | if 'justification' in cve_data[cve]: | ||
533 | write_string += "CVE DESCRIPTION: %s\n" % cve_data[cve]["justification"] | ||
534 | |||
535 | if "NVD-summary" in cve_data[cve]: | ||
536 | write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["NVD-summary"] | ||
537 | write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["NVD-scorev2"] | ||
538 | write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["NVD-scorev3"] | ||
539 | write_string += "VECTOR: %s\n" % cve_data[cve]["NVD-vector"] | ||
540 | write_string += "VECTORSTRING: %s\n" % cve_data[cve]["NVD-vectorString"] | ||
541 | |||
542 | write_string += "MORE INFORMATION: %s%s\n\n" % (nvd_link, cve) | ||
543 | if cve_data[cve]["abbrev-status"] == "Unpatched": | ||
544 | unpatched_cves.append(cve) | ||
545 | |||
546 | if unpatched_cves and d.getVar("CVE_CHECK_SHOW_WARNINGS") == "1": | ||
547 | bb.warn("Found unpatched CVE (%s), for more information check %s" % (" ".join(unpatched_cves),cve_file)) | ||
548 | |||
549 | with open(cve_file, "w") as f: | ||
550 | bb.note("Writing file %s with CVE information" % cve_file) | ||
551 | f.write(write_string) | ||
552 | |||
553 | if d.getVar("CVE_CHECK_COPY_FILES") == "1": | ||
554 | deploy_file = d.getVar("CVE_CHECK_RECIPE_FILE") | ||
555 | bb.utils.mkdirhier(os.path.dirname(deploy_file)) | ||
556 | with open(deploy_file, "w") as f: | ||
557 | f.write(write_string) | ||
558 | |||
559 | if d.getVar("CVE_CHECK_CREATE_MANIFEST") == "1": | ||
560 | cvelogpath = d.getVar("CVE_CHECK_SUMMARY_DIR") | ||
561 | bb.utils.mkdirhier(cvelogpath) | ||
562 | |||
563 | with open(d.getVar("CVE_CHECK_TMP_FILE"), "a") as f: | ||
564 | f.write("%s" % write_string) | ||
565 | |||
566 | def cve_check_write_json_output(d, output, direct_file, deploy_file, manifest_file): | 454 | def cve_check_write_json_output(d, output, direct_file, deploy_file, manifest_file): |
567 | """ | 455 | """ |
568 | Write CVE information in the JSON format: to WORKDIR; and to | 456 | Write CVE information in the JSON format: to WORKDIR; and to |
@@ -670,7 +558,5 @@ def cve_write_data(d, cve_data, status): | |||
670 | Write CVE data in each enabled format. | 558 | Write CVE data in each enabled format. |
671 | """ | 559 | """ |
672 | 560 | ||
673 | if d.getVar("CVE_CHECK_FORMAT_TEXT") == "1": | ||
674 | cve_write_data_text(d, cve_data) | ||
675 | if d.getVar("CVE_CHECK_FORMAT_JSON") == "1": | 561 | if d.getVar("CVE_CHECK_FORMAT_JSON") == "1": |
676 | cve_write_data_json(d, cve_data, status) | 562 | cve_write_data_json(d, cve_data, status) |