summaryrefslogtreecommitdiffstats
path: root/meta/classes/cve-check.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes/cve-check.bbclass')
-rw-r--r--meta/classes/cve-check.bbclass62
1 files changed, 2 insertions, 60 deletions
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index 1688fe2dfe..9eb9a95574 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -136,10 +136,11 @@ python do_cve_check () {
136 """ 136 """
137 Check recipe for patched and unpatched CVEs 137 Check recipe for patched and unpatched CVEs
138 """ 138 """
139 from oe.cve_check import get_patched_cves
139 140
140 if os.path.exists(d.getVar("CVE_CHECK_DB_FILE")): 141 if os.path.exists(d.getVar("CVE_CHECK_DB_FILE")):
141 try: 142 try:
142 patched_cves = get_patches_cves(d) 143 patched_cves = get_patched_cves(d)
143 except FileNotFoundError: 144 except FileNotFoundError:
144 bb.fatal("Failure in searching patches") 145 bb.fatal("Failure in searching patches")
145 whitelisted, patched, unpatched, status = check_cves(d, patched_cves) 146 whitelisted, patched, unpatched, status = check_cves(d, patched_cves)
@@ -247,65 +248,6 @@ ROOTFS_POSTPROCESS_COMMAND_prepend = "${@'cve_check_write_rootfs_manifest; ' if
247do_rootfs[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}" 248do_rootfs[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"
248do_populate_sdk[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}" 249do_populate_sdk[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"
249 250
250def get_patches_cves(d):
251 """
252 Get patches that solve CVEs using the "CVE: " tag.
253 """
254
255 import re
256
257 pn = d.getVar("PN")
258 cve_match = re.compile("CVE:( CVE\-\d{4}\-\d+)+")
259
260 # Matches the last "CVE-YYYY-ID" in the file name, also if written
261 # in lowercase. Possible to have multiple CVE IDs in a single
262 # file name, but only the last one will be detected from the file name.
263 # However, patch files contents addressing multiple CVE IDs are supported
264 # (cve_match regular expression)
265
266 cve_file_name_match = re.compile(".*([Cc][Vv][Ee]\-\d{4}\-\d+)")
267
268 patched_cves = set()
269 bb.debug(2, "Looking for patches that solves CVEs for %s" % pn)
270 for url in src_patches(d):
271 patch_file = bb.fetch.decodeurl(url)[2]
272
273 if not os.path.isfile(patch_file):
274 bb.error("File Not found: %s" % patch_file)
275 raise FileNotFoundError
276
277 # Check patch file name for CVE ID
278 fname_match = cve_file_name_match.search(patch_file)
279 if fname_match:
280 cve = fname_match.group(1).upper()
281 patched_cves.add(cve)
282 bb.debug(2, "Found CVE %s from patch file name %s" % (cve, patch_file))
283
284 with open(patch_file, "r", encoding="utf-8") as f:
285 try:
286 patch_text = f.read()
287 except UnicodeDecodeError:
288 bb.debug(1, "Failed to read patch %s using UTF-8 encoding"
289 " trying with iso8859-1" % patch_file)
290 f.close()
291 with open(patch_file, "r", encoding="iso8859-1") as f:
292 patch_text = f.read()
293
294 # Search for one or more "CVE: " lines
295 text_match = False
296 for match in cve_match.finditer(patch_text):
297 # Get only the CVEs without the "CVE: " tag
298 cves = patch_text[match.start()+5:match.end()]
299 for cve in cves.split():
300 bb.debug(2, "Patch %s solves %s" % (patch_file, cve))
301 patched_cves.add(cve)
302 text_match = True
303
304 if not fname_match and not text_match:
305 bb.debug(2, "Patch %s doesn't solve CVEs" % patch_file)
306
307 return patched_cves
308
309def check_cves(d, patched_cves): 251def check_cves(d, patched_cves):
310 """ 252 """
311 Connect to the NVD database and find unpatched cves. 253 Connect to the NVD database and find unpatched cves.