All of lore.kernel.org
 help / color / mirror / Atom feed
* [OE-core][PATCH] classes/cve-check: Move get_patches_cves to library
@ 2021-08-11 14:51 Joshua Watt
  2021-08-19 16:04 ` Marta Rybczynska
  0 siblings, 1 reply; 3+ messages in thread
From: Joshua Watt @ 2021-08-11 14:51 UTC (permalink / raw)
  To: openembedded-core; +Cc: saul.wold, Joshua Watt

Moving the function will allow other classes to capture which CVEs have
been patched, in particular SBoM generation.

Also add a function to capture the CPE ID from the CVE Product and
Version

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/classes/cve-check.bbclass | 62 +------------------------
 meta/lib/oe/cve_check.py       | 83 ++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 60 deletions(-)

diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index 6582f97151..3c4c9218e3 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -94,10 +94,11 @@ python do_cve_check () {
     """
     Check recipe for patched and unpatched CVEs
     """
+    from oe.cve_check import get_patched_cves
 
     if os.path.exists(d.getVar("CVE_CHECK_DB_FILE")):
         try:
-            patched_cves = get_patches_cves(d)
+            patched_cves = get_patched_cves(d)
         except FileNotFoundError:
             bb.fatal("Failure in searching patches")
         whitelisted, patched, unpatched = check_cves(d, patched_cves)
@@ -156,65 +157,6 @@ python cve_check_write_rootfs_manifest () {
 ROOTFS_POSTPROCESS_COMMAND:prepend = "${@'cve_check_write_rootfs_manifest; ' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"
 do_rootfs[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"
 
-def get_patches_cves(d):
-    """
-    Get patches that solve CVEs using the "CVE: " tag.
-    """
-
-    import re
-
-    pn = d.getVar("PN")
-    cve_match = re.compile("CVE:( CVE\-\d{4}\-\d+)+")
-
-    # Matches the last "CVE-YYYY-ID" in the file name, also if written
-    # in lowercase. Possible to have multiple CVE IDs in a single
-    # file name, but only the last one will be detected from the file name.
-    # However, patch files contents addressing multiple CVE IDs are supported
-    # (cve_match regular expression)
-
-    cve_file_name_match = re.compile(".*([Cc][Vv][Ee]\-\d{4}\-\d+)")
-
-    patched_cves = set()
-    bb.debug(2, "Looking for patches that solves CVEs for %s" % pn)
-    for url in src_patches(d):
-        patch_file = bb.fetch.decodeurl(url)[2]
-
-        if not os.path.isfile(patch_file):
-            bb.error("File Not found: %s" % patch_file)
-            raise FileNotFoundError
-
-        # Check patch file name for CVE ID
-        fname_match = cve_file_name_match.search(patch_file)
-        if fname_match:
-            cve = fname_match.group(1).upper()
-            patched_cves.add(cve)
-            bb.debug(2, "Found CVE %s from patch file name %s" % (cve, patch_file))
-
-        with open(patch_file, "r", encoding="utf-8") as f:
-            try:
-                patch_text = f.read()
-            except UnicodeDecodeError:
-                bb.debug(1, "Failed to read patch %s using UTF-8 encoding"
-                        " trying with iso8859-1" %  patch_file)
-                f.close()
-                with open(patch_file, "r", encoding="iso8859-1") as f:
-                    patch_text = f.read()
-
-        # Search for one or more "CVE: " lines
-        text_match = False
-        for match in cve_match.finditer(patch_text):
-            # Get only the CVEs without the "CVE: " tag
-            cves = patch_text[match.start()+5:match.end()]
-            for cve in cves.split():
-                bb.debug(2, "Patch %s solves %s" % (patch_file, cve))
-                patched_cves.add(cve)
-                text_match = True
-
-        if not fname_match and not text_match:
-            bb.debug(2, "Patch %s doesn't solve CVEs" % patch_file)
-
-    return patched_cves
-
 def check_cves(d, patched_cves):
     """
     Connect to the NVD database and find unpatched cves.
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
index a1d7c292af..0302beeb4a 100644
--- a/meta/lib/oe/cve_check.py
+++ b/meta/lib/oe/cve_check.py
@@ -63,3 +63,86 @@ def _cmpkey(release, patch_l, pre_l, pre_v):
     else:
         _pre = float(pre_v) if pre_v else float('-inf')
     return _release, _patch, _pre
+
+
+def get_patched_cves(d):
+    """
+    Get patches that solve CVEs using the "CVE: " tag.
+    """
+
+    import re
+    import oe.patch
+
+    pn = d.getVar("PN")
+    cve_match = re.compile("CVE:( CVE\-\d{4}\-\d+)+")
+
+    # Matches the last "CVE-YYYY-ID" in the file name, also if written
+    # in lowercase. Possible to have multiple CVE IDs in a single
+    # file name, but only the last one will be detected from the file name.
+    # However, patch files contents addressing multiple CVE IDs are supported
+    # (cve_match regular expression)
+
+    cve_file_name_match = re.compile(".*([Cc][Vv][Ee]\-\d{4}\-\d+)")
+
+    patched_cves = set()
+    bb.debug(2, "Looking for patches that solves CVEs for %s" % pn)
+    for url in oe.patch.src_patches(d):
+        patch_file = bb.fetch.decodeurl(url)[2]
+
+        if not os.path.isfile(patch_file):
+            bb.error("File Not found: %s" % patch_file)
+            raise FileNotFoundError
+
+        # Check patch file name for CVE ID
+        fname_match = cve_file_name_match.search(patch_file)
+        if fname_match:
+            cve = fname_match.group(1).upper()
+            patched_cves.add(cve)
+            bb.debug(2, "Found CVE %s from patch file name %s" % (cve, patch_file))
+
+        with open(patch_file, "r", encoding="utf-8") as f:
+            try:
+                patch_text = f.read()
+            except UnicodeDecodeError:
+                bb.debug(1, "Failed to read patch %s using UTF-8 encoding"
+                        " trying with iso8859-1" %  patch_file)
+                f.close()
+                with open(patch_file, "r", encoding="iso8859-1") as f:
+                    patch_text = f.read()
+
+        # Search for one or more "CVE: " lines
+        text_match = False
+        for match in cve_match.finditer(patch_text):
+            # Get only the CVEs without the "CVE: " tag
+            cves = patch_text[match.start()+5:match.end()]
+            for cve in cves.split():
+                bb.debug(2, "Patch %s solves %s" % (patch_file, cve))
+                patched_cves.add(cve)
+                text_match = True
+
+        if not fname_match and not text_match:
+            bb.debug(2, "Patch %s doesn't solve CVEs" % patch_file)
+
+    return patched_cves
+
+
+def get_cpe_ids(cve_product, version):
+    """
+    Get list of CPE identifiers for the given product and version
+    """
+
+    version = version.split("+git")[0]
+
+    cpe_ids = []
+    for product in cve_product.split():
+        # CVE_PRODUCT in recipes may include vendor information for CPE identifiers. If not,
+        # use wildcard for vendor.
+        if ":" in product:
+            vendor, product = product.split(":", 1)
+        else:
+            vendor = "*"
+
+        cpe_id = f'cpe:2.3:a:{vendor}:{product}:{version}:*:*:*:*:*:*:*'
+        cpe_ids.append(cpe_id)
+
+    return cpe_ids
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [OE-core][PATCH] classes/cve-check: Move get_patches_cves to library
  2021-08-11 14:51 [OE-core][PATCH] classes/cve-check: Move get_patches_cves to library Joshua Watt
@ 2021-08-19 16:04 ` Marta Rybczynska
  2021-08-19 16:29   ` Joshua Watt
  0 siblings, 1 reply; 3+ messages in thread
From: Marta Rybczynska @ 2021-08-19 16:04 UTC (permalink / raw)
  To: Joshua Watt; +Cc: OE-core, saul.wold

[-- Attachment #1: Type: text/plain, Size: 393 bytes --]

On Wed, Aug 11, 2021 at 4:52 PM Joshua Watt <JPEWhacker@gmail.com> wrote:

> Moving the function will allow other classes to capture which CVEs have
> been patched, in particular SBoM generation.
>
> Also add a function to capture the CPE ID from the CVE Product and
> Version
>
>
Do you have a link to some resource on how you plan to use it for SBOM
generation?

Thanks,
Marta

[-- Attachment #2: Type: text/html, Size: 765 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [OE-core][PATCH] classes/cve-check: Move get_patches_cves to library
  2021-08-19 16:04 ` Marta Rybczynska
@ 2021-08-19 16:29   ` Joshua Watt
  0 siblings, 0 replies; 3+ messages in thread
From: Joshua Watt @ 2021-08-19 16:29 UTC (permalink / raw)
  To: Marta Rybczynska; +Cc: OE-core, Saul Wold

[-- Attachment #1: Type: text/plain, Size: 643 bytes --]

I have a branch called jpew/sbom in poky-contrib with my WIP changes.

http://git.yoctoproject.org/cgit.cgi/poky-contrib/log/?h=jpew/sbom

On Thu, Aug 19, 2021, 11:04 AM Marta Rybczynska <rybczynska@gmail.com>
wrote:

>
> On Wed, Aug 11, 2021 at 4:52 PM Joshua Watt <JPEWhacker@gmail.com> wrote:
>
>> Moving the function will allow other classes to capture which CVEs have
>> been patched, in particular SBoM generation.
>>
>> Also add a function to capture the CPE ID from the CVE Product and
>> Version
>>
>>
> Do you have a link to some resource on how you plan to use it for SBOM
> generation?
>
> Thanks,
> Marta
>

[-- Attachment #2: Type: text/html, Size: 1429 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-08-19 16:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-11 14:51 [OE-core][PATCH] classes/cve-check: Move get_patches_cves to library Joshua Watt
2021-08-19 16:04 ` Marta Rybczynska
2021-08-19 16:29   ` Joshua Watt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.