diff options
| -rw-r--r-- | meta/classes/cve-check.bbclass | 24 | ||||
| -rw-r--r-- | meta/lib/oe/cve_check.py | 39 | ||||
| -rw-r--r-- | meta/lib/oe/spdx30_tasks.py | 11 |
3 files changed, 48 insertions, 26 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass index c946de29a4..bc35a1c53c 100644 --- a/meta/classes/cve-check.bbclass +++ b/meta/classes/cve-check.bbclass | |||
| @@ -324,8 +324,8 @@ def check_cves(d, patched_cves): | |||
| 324 | # Convert CVE_STATUS into ignored CVEs and check validity | 324 | # Convert CVE_STATUS into ignored CVEs and check validity |
| 325 | cve_ignore = [] | 325 | cve_ignore = [] |
| 326 | for cve in (d.getVarFlags("CVE_STATUS") or {}): | 326 | for cve in (d.getVarFlags("CVE_STATUS") or {}): |
| 327 | decoded_status, _, _ = decode_cve_status(d, cve) | 327 | decoded_status = decode_cve_status(d, cve) |
| 328 | if decoded_status == "Ignored": | 328 | if 'mapping' in decoded_status and decoded_status['mapping'] == "Ignored": |
| 329 | cve_ignore.append(cve) | 329 | cve_ignore.append(cve) |
| 330 | 330 | ||
| 331 | import sqlite3 | 331 | import sqlite3 |
| @@ -507,11 +507,11 @@ def cve_write_data_text(d, patched, unpatched, ignored, cve_data): | |||
| 507 | write_string += "PACKAGE VERSION: %s%s\n" % (d.getVar("EXTENDPE"), d.getVar("PV")) | 507 | write_string += "PACKAGE VERSION: %s%s\n" % (d.getVar("EXTENDPE"), d.getVar("PV")) |
| 508 | write_string += "CVE: %s\n" % cve | 508 | write_string += "CVE: %s\n" % cve |
| 509 | write_string += "CVE STATUS: %s\n" % status | 509 | write_string += "CVE STATUS: %s\n" % status |
| 510 | _, detail, description = decode_cve_status(d, cve) | 510 | status_details = decode_cve_status(d, cve) |
| 511 | if detail: | 511 | if 'detail' in status_details: |
| 512 | write_string += "CVE DETAIL: %s\n" % detail | 512 | write_string += "CVE DETAIL: %s\n" % status_details['detail'] |
| 513 | if description: | 513 | if 'description' in status_details: |
| 514 | write_string += "CVE DESCRIPTION: %s\n" % description | 514 | write_string += "CVE DESCRIPTION: %s\n" % status_details['description'] |
| 515 | write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"] | 515 | write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"] |
| 516 | write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["scorev2"] | 516 | write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["scorev2"] |
| 517 | write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["scorev3"] | 517 | write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["scorev3"] |
| @@ -637,11 +637,11 @@ def cve_write_data_json(d, patched, unpatched, ignored, cve_data, cve_status): | |||
| 637 | "status" : status, | 637 | "status" : status, |
| 638 | "link": issue_link | 638 | "link": issue_link |
| 639 | } | 639 | } |
| 640 | _, detail, description = decode_cve_status(d, cve) | 640 | status_details = decode_cve_status(d, cve) |
| 641 | if detail: | 641 | if 'detail' in status_details: |
| 642 | cve_item["detail"] = detail | 642 | cve_item["detail"] = status_details['detail'] |
| 643 | if description: | 643 | if 'description' in status_details: |
| 644 | cve_item["description"] = description | 644 | cve_item["description"] = status_details['description'] |
| 645 | cve_list.append(cve_item) | 645 | cve_list.append(cve_item) |
| 646 | 646 | ||
| 647 | package_data["issue"] = cve_list | 647 | package_data["issue"] = cve_list |
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py index ed5c714cb8..5edd34a2d9 100644 --- a/meta/lib/oe/cve_check.py +++ b/meta/lib/oe/cve_check.py | |||
| @@ -132,8 +132,8 @@ def get_patched_cves(d): | |||
| 132 | 132 | ||
| 133 | # Search for additional patched CVEs | 133 | # Search for additional patched CVEs |
| 134 | for cve in (d.getVarFlags("CVE_STATUS") or {}): | 134 | for cve in (d.getVarFlags("CVE_STATUS") or {}): |
| 135 | decoded_status, _, _ = decode_cve_status(d, cve) | 135 | decoded_status = decode_cve_status(d, cve) |
| 136 | if decoded_status == "Patched": | 136 | if 'mapping' in decoded_status and decoded_status['mapping'] == "Patched": |
| 137 | bb.debug(2, "CVE %s is additionally patched" % cve) | 137 | bb.debug(2, "CVE %s is additionally patched" % cve) |
| 138 | patched_cves.add(cve) | 138 | patched_cves.add(cve) |
| 139 | 139 | ||
| @@ -227,19 +227,40 @@ def convert_cve_version(version): | |||
| 227 | 227 | ||
| 228 | def decode_cve_status(d, cve): | 228 | def decode_cve_status(d, cve): |
| 229 | """ | 229 | """ |
| 230 | Convert CVE_STATUS into status, detail and description. | 230 | Convert CVE_STATUS into status, vendor, product, detail and description. |
| 231 | """ | 231 | """ |
| 232 | status = d.getVarFlag("CVE_STATUS", cve) | 232 | status = d.getVarFlag("CVE_STATUS", cve) |
| 233 | if not status: | 233 | if not status: |
| 234 | return ("", "", "") | 234 | return {} |
| 235 | |||
| 236 | status_split = status.split(':', 5) | ||
| 237 | status_out = {} | ||
| 238 | status_out["detail"] = status_split[0] | ||
| 239 | product = "*" | ||
| 240 | vendor = "*" | ||
| 241 | description = "" | ||
| 242 | if len(status_split) >= 4 and status_split[1].strip() == "cpe": | ||
| 243 | # Both vendor and product are mandatory if cpe: present, the syntax is then: | ||
| 244 | # detail: cpe:vendor:product:description | ||
| 245 | vendor = status_split[2].strip() | ||
| 246 | product = status_split[3].strip() | ||
| 247 | description = status_split[4].strip() | ||
| 248 | elif len(status_split) >= 2 and status_split[1].strip() == "cpe": | ||
| 249 | # Malformed CPE | ||
| 250 | bb.warn('Invalid CPE information for CVE_STATUS[%s] = "%s", not setting CPE' % (detail, cve, status)) | ||
| 251 | else: | ||
| 252 | # Other case: no CPE, the syntax is then: | ||
| 253 | # detail: description | ||
| 254 | description = status_split[len(status_split)-1].strip() if (len(status_split) > 1) else "" | ||
| 235 | 255 | ||
| 236 | status_split = status.split(':', 1) | 256 | status_out["vendor"] = vendor |
| 237 | detail = status_split[0] | 257 | status_out["product"] = product |
| 238 | description = status_split[1].strip() if (len(status_split) > 1) else "" | 258 | status_out["description"] = description |
| 239 | 259 | ||
| 240 | status_mapping = d.getVarFlag("CVE_CHECK_STATUSMAP", detail) | 260 | status_mapping = d.getVarFlag("CVE_CHECK_STATUSMAP", status_out['detail']) |
| 241 | if status_mapping is None: | 261 | if status_mapping is None: |
| 242 | bb.warn('Invalid detail "%s" for CVE_STATUS[%s] = "%s", fallback to Unpatched' % (detail, cve, status)) | 262 | bb.warn('Invalid detail "%s" for CVE_STATUS[%s] = "%s", fallback to Unpatched' % (detail, cve, status)) |
| 243 | status_mapping = "Unpatched" | 263 | status_mapping = "Unpatched" |
| 264 | status_out["mapping"] = status_mapping | ||
| 244 | 265 | ||
| 245 | return (status_mapping, detail, description) | 266 | return status_out |
diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py index 03dc47db02..4864d6252a 100644 --- a/meta/lib/oe/spdx30_tasks.py +++ b/meta/lib/oe/spdx30_tasks.py | |||
| @@ -488,21 +488,22 @@ def create_spdx(d): | |||
| 488 | cve_by_status = {} | 488 | cve_by_status = {} |
| 489 | if include_vex != "none": | 489 | if include_vex != "none": |
| 490 | for cve in d.getVarFlags("CVE_STATUS") or {}: | 490 | for cve in d.getVarFlags("CVE_STATUS") or {}: |
| 491 | status, detail, description = oe.cve_check.decode_cve_status(d, cve) | 491 | decoded_status = oe.cve_check.decode_cve_status(d, cve) |
| 492 | 492 | ||
| 493 | # If this CVE is fixed upstream, skip it unless all CVEs are | 493 | # If this CVE is fixed upstream, skip it unless all CVEs are |
| 494 | # specified. | 494 | # specified. |
| 495 | if include_vex != "all" and detail in ( | 495 | if include_vex != "all" and 'detail' in decoded_status and \ |
| 496 | decoded_status['detail'] in ( | ||
| 496 | "fixed-version", | 497 | "fixed-version", |
| 497 | "cpe-stable-backport", | 498 | "cpe-stable-backport", |
| 498 | ): | 499 | ): |
| 499 | bb.debug(1, "Skipping %s since it is already fixed upstream" % cve) | 500 | bb.debug(1, "Skipping %s since it is already fixed upstream" % cve) |
| 500 | continue | 501 | continue |
| 501 | 502 | ||
| 502 | cve_by_status.setdefault(status, {})[cve] = ( | 503 | cve_by_status.setdefault(decoded_status['mapping'], {})[cve] = ( |
| 503 | build_objset.new_cve_vuln(cve), | 504 | build_objset.new_cve_vuln(cve), |
| 504 | detail, | 505 | decoded_status['detail'], |
| 505 | description, | 506 | decoded_status['description'], |
| 506 | ) | 507 | ) |
| 507 | 508 | ||
| 508 | cpe_ids = oe.cve_check.get_cpe_ids(d.getVar("CVE_PRODUCT"), d.getVar("CVE_VERSION")) | 509 | cpe_ids = oe.cve_check.get_cpe_ids(d.getVar("CVE_PRODUCT"), d.getVar("CVE_VERSION")) |
