Message ID | 20231016070106.2772303-1-mikko.rapeli@linaro.org |
---|---|
State | New |
Headers | show |
Series | cve-check.bbclass: support embedded SW components with different version number | expand |
On Mon, Oct 16, 2023 at 9:01 AM Mikko Rapeli <mikko.rapeli@linaro.org> wrote: > > Many recipes embed other SW components. The name and version of the > embedded SW component differs from the main recipe. To detect CVEs in the > embedded SW component, it needs to be added to CVE_PRODUCT list using > name of the SW product in CVE database or with "vendor:product" syntax. > Then the version of the embedded SW component can be set using > CVE_VERSION_product variable. > > For example in meta-arm, trusted-firmware-a embeds mbed_tls SW component. > Thus trusted-firmware-a can add CVE_PRODUCT for it since CVE database > uses product name "mbed_tls": > > CVE_PRODUCT += "mbed_tls" > > and set the version of mbed_tls: > > CVE_VERSION_mbed_tls = "2.28.4" > > (Real patches for both are a bit more complex due to conditional build > enabling mbed_tls support and due to mbed_tls version being set in an > .inc file.) > I like the support for embedded software. In this approach, I'm wondering how it would work for packages like curl that have multiple CPEs. Would we need to duplicate the list of CPEs? There are layers/recipes where we have a very long list of embedded components, meta-zephyr is probably the best example. Cheers, Marta
Hi, On Thu, Oct 19, 2023 at 10:19:53AM +0200, Marta Rybczynska wrote: > On Mon, Oct 16, 2023 at 9:01 AM Mikko Rapeli <mikko.rapeli@linaro.org> wrote: > > > > Many recipes embed other SW components. The name and version of the > > embedded SW component differs from the main recipe. To detect CVEs in the > > embedded SW component, it needs to be added to CVE_PRODUCT list using > > name of the SW product in CVE database or with "vendor:product" syntax. > > Then the version of the embedded SW component can be set using > > CVE_VERSION_product variable. > > > > For example in meta-arm, trusted-firmware-a embeds mbed_tls SW component. > > Thus trusted-firmware-a can add CVE_PRODUCT for it since CVE database > > uses product name "mbed_tls": > > > > CVE_PRODUCT += "mbed_tls" > > > > and set the version of mbed_tls: > > > > CVE_VERSION_mbed_tls = "2.28.4" > > > > (Real patches for both are a bit more complex due to conditional build > > enabling mbed_tls support and due to mbed_tls version being set in an > > .inc file.) > > > > I like the support for embedded software. In this approach, I'm wondering > how it would work for packages like curl that have multiple CPEs. Would we > need to duplicate the list of CPEs? The current approach of listing multiple CPEs in CVE_PRODUCT still works. It's just possible to include a different version for an entry in CVE_PRODUCT via CVE_VERSION_swcomponent variable. It will fall back to PV. > There are layers/recipes where we have a very long list of embedded components, > meta-zephyr is probably the best example. Yes, I think this embedding of SW components is very common. I think some of the LICENSE data does reflect this but not in all cases. Cheers, -Mikko
Hi This change will need some adaptations in the create-spdx.bbclass to handle this new variable with _PN Jose Mikko Rapeli <mikko.rapeli@linaro.org> escreveu no dia quinta, 19/10/2023 à(s) 10:13: > Hi, > > On Thu, Oct 19, 2023 at 10:19:53AM +0200, Marta Rybczynska wrote: > > On Mon, Oct 16, 2023 at 9:01 AM Mikko Rapeli <mikko.rapeli@linaro.org> > wrote: > > > > > > Many recipes embed other SW components. The name and version of the > > > embedded SW component differs from the main recipe. To detect CVEs in > the > > > embedded SW component, it needs to be added to CVE_PRODUCT list using > > > name of the SW product in CVE database or with "vendor:product" syntax. > > > Then the version of the embedded SW component can be set using > > > CVE_VERSION_product variable. > > > > > > For example in meta-arm, trusted-firmware-a embeds mbed_tls SW > component. > > > Thus trusted-firmware-a can add CVE_PRODUCT for it since CVE database > > > uses product name "mbed_tls": > > > > > > CVE_PRODUCT += "mbed_tls" > > > > > > and set the version of mbed_tls: > > > > > > CVE_VERSION_mbed_tls = "2.28.4" > > > > > > (Real patches for both are a bit more complex due to conditional build > > > enabling mbed_tls support and due to mbed_tls version being set in an > > > .inc file.) > > > > > > > I like the support for embedded software. In this approach, I'm wondering > > how it would work for packages like curl that have multiple CPEs. Would > we > > need to duplicate the list of CPEs? > > The current approach of listing multiple CPEs in CVE_PRODUCT still works. > It's just possible to include a different version for an entry in > CVE_PRODUCT > via CVE_VERSION_swcomponent variable. It will fall back to PV. > > > There are layers/recipes where we have a very long list of embedded > components, > > meta-zephyr is probably the best example. > > Yes, I think this embedding of SW components is very common. I think some > of the > LICENSE data does reflect this but not in all cases. > > Cheers, > > -Mikko > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#189437): > https://lists.openembedded.org/g/openembedded-core/message/189437 > Mute This Topic: https://lists.openembedded.org/mt/101991269/5052612 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [ > quaresma.jose@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=- > >
Hi, On Thu, Oct 19, 2023 at 12:54:44PM +0100, Jose Quaresma wrote: > Hi > > This change will need some adaptations in the create-spdx.bbclass to handle > this new variable with _PN Good point. How does SPDX tooling handle embedded SW components in recipe sources? I presume it does not because recipe and license don't handle it either. Should there be a more generic PN_subpn, PV_subpn, LICENSE_subpn and matching CVE_PRODUCT and CVE_VERSION? I don't have use cases for these currently. I would like to fix the CVE reporting issues with embedded SW components though. mbedtls being one good example. Or would it be better to convert mbedtls users to use the meta-oe side recipe for it? Additionally I don't currently read the SDPX output. I don't have use cases for it. I do check recipes and their metadata like LICENSE though. Feels like the SDPX data is used as reporting/export data format which is fed to some other tools which are not open source. Can of worms... Cheers, -Mikko
Hi, Could something like this work? --- a/meta/lib/oe/cve_check.py +++ b/meta/lib/oe/cve_check.py @@ -140,15 +140,14 @@ def get_patched_cves(d): return patched_cves -def get_cpe_ids(cve_product, version): +def get_cpe_ids(cve_product, cve_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(): + version = (d.getVar("CVE_VERSION_%s" % product) or cve_version).split("+git")[0] # CVE_PRODUCT in recipes may include vendor information for CPE identifiers. If not, # use wildcard for vendor. if ":" in product: Cheers, -Mikko
Mikko Rapeli <mikko.rapeli@linaro.org> escreveu no dia quinta, 19/10/2023 à(s) 13:21: > Hi, > > On Thu, Oct 19, 2023 at 12:54:44PM +0100, Jose Quaresma wrote: > > Hi > > > > This change will need some adaptations in the create-spdx.bbclass to > handle > > this new variable with _PN > > Good point. How does SPDX tooling handle embedded SW components in recipe > sources? > As far as I know SPDX doesn't support this at all because the class has a way of knowing that these components exist. > > I presume it does not because recipe and license don't handle it either. > Should > there be a more generic PN_subpn, PV_subpn, LICENSE_subpn and matching > CVE_PRODUCT > and CVE_VERSION? I don't have use cases for these currently. I would like > to fix > the CVE reporting issues with embedded SW components though. mbedtls being > one good > example. > > Or would it be better to convert mbedtls users to use the meta-oe side > recipe for it? > In a perfect world this would be the way but as we know the world is far from perfect :) > > Additionally I don't currently read the SDPX output. I don't have use > cases for it. > I do check recipes and their metadata like LICENSE though. Feels like the > SDPX data > is used as reporting/export data format which is fed to some other tools > which are > not open source. > Can of worms... > Given that one of the main characteristics of the SPDX metadata is that they enable and have a complete description of the software used, this can and will be used by other tools to do all types of analysis. AI models will love eating this... > > Cheers, > > -Mikko >
Mikko Rapeli <mikko.rapeli@linaro.org> escreveu no dia quinta, 19/10/2023 à(s) 13:45: > Hi, > > Could something like this work? > > --- a/meta/lib/oe/cve_check.py > +++ b/meta/lib/oe/cve_check.py > @@ -140,15 +140,14 @@ def get_patched_cves(d): > return patched_cves > > > -def get_cpe_ids(cve_product, version): > +def get_cpe_ids(cve_product, cve_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(): > + version = (d.getVar("CVE_VERSION_%s" % product) or > cve_version).split("+git")[0] > Looks like your patch fixes the remaining issue but don't know if it will be better to get the CVE_VERSION_ after splitting the vendor from the product Jose > # CVE_PRODUCT in recipes may include vendor information for CPE > identifiers. If not, > # use wildcard for vendor. > if ":" in product: > > Cheers, > > -Mikko >
On Fri, Oct 20, 2023 at 08:56:43AM +0100, Jose Quaresma wrote: > Mikko Rapeli <mikko.rapeli@linaro.org> escreveu no dia quinta, 19/10/2023 > �(s) 13:45: > > > Hi, > > > > Could something like this work? > > > > --- a/meta/lib/oe/cve_check.py > > +++ b/meta/lib/oe/cve_check.py > > @@ -140,15 +140,14 @@ def get_patched_cves(d): > > return patched_cves > > > > > > -def get_cpe_ids(cve_product, version): > > +def get_cpe_ids(cve_product, cve_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(): > > + version = (d.getVar("CVE_VERSION_%s" % product) or > > cve_version).split("+git")[0] > > > > Looks like your patch fixes the remaining issue > but don't know if it will be better to get the CVE_VERSION_ after > splitting the vendor from the product This is now in v2. For the CVE_VERSION_%s, it uses what ever product was defined in CVE_PRODUCT space separated list so it is used before vendor and product split. Cheers, -Mikko
diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass index b55f4299da..9c41d54188 100644 --- a/meta/classes/cve-check.bbclass +++ b/meta/classes/cve-check.bbclass @@ -309,7 +309,16 @@ def check_cves(d, patched_cves): # If this has been unset then we're not scanning for CVEs here (for example, image recipes) if not products: return ([], [], [], []) - pv = d.getVar("CVE_VERSION").split("+git")[0] + + # Version is PV, CVE_VERSION or CVE_VERSION_%s where %s is one of the entries in CVE_PRODUCT. + # Enables checking embedded SW component CVEs provided that CVE_PRODUCT contains the embedded SW + # component and that version of that component is set via CVE_VERSION_embedded_component variable. + pv = {} + for product in products: + version = (d.getVar("CVE_VERSION_%s" % product) or "").split("+git")[0] + if version == "": + version = d.getVar("CVE_VERSION").split("+git")[0] + pv[product] = version # If the recipe has been skipped/ignored we return empty lists if pn in d.getVar("CVE_CHECK_SKIP_RECIPE").split(): @@ -329,6 +338,7 @@ def check_cves(d, patched_cves): # For each of the known product names (e.g. curl has CPEs using curl and libcurl)... for product in products: + full_product = product cves_in_product = False if ":" in product: vendor, product = product.split(":", 1) @@ -341,7 +351,7 @@ def check_cves(d, patched_cves): cve = cverow[0] if cve in cve_ignore: - bb.note("%s-%s ignores %s" % (product, pv, cve)) + bb.note("%s-%s ignores %s" % (product, pv[full_product], cve)) cves_ignored.append(cve) continue elif cve in patched_cves: @@ -366,27 +376,27 @@ def check_cves(d, patched_cves): version_start = convert_cve_version(version_start) version_end = convert_cve_version(version_end) - if (operator_start == '=' and pv == version_start) or version_start == '-': + if (operator_start == '=' and pv[full_product] == version_start) or version_start == '-': vulnerable = True else: if operator_start: try: - vulnerable_start = (operator_start == '>=' and Version(pv,suffix) >= Version(version_start,suffix)) - vulnerable_start |= (operator_start == '>' and Version(pv,suffix) > Version(version_start,suffix)) + vulnerable_start = (operator_start == '>=' and Version(pv[full_product],suffix) >= Version(version_start,suffix)) + vulnerable_start |= (operator_start == '>' and Version(pv[full_product],suffix) > Version(version_start,suffix)) except: bb.warn("%s: Failed to compare %s %s %s for %s" % - (product, pv, operator_start, version_start, cve)) + (product, pv[full_product], operator_start, version_start, cve)) vulnerable_start = False else: vulnerable_start = False if operator_end: try: - vulnerable_end = (operator_end == '<=' and Version(pv,suffix) <= Version(version_end,suffix) ) - vulnerable_end |= (operator_end == '<' and Version(pv,suffix) < Version(version_end,suffix) ) + vulnerable_end = (operator_end == '<=' and Version(pv[full_product],suffix) <= Version(version_end,suffix) ) + vulnerable_end |= (operator_end == '<' and Version(pv[full_product],suffix) < Version(version_end,suffix) ) except: bb.warn("%s: Failed to compare %s %s %s for %s" % - (product, pv, operator_end, version_end, cve)) + (product, pv[full_product], operator_end, version_end, cve)) vulnerable_end = False else: vulnerable_end = False
Many recipes embed other SW components. The name and version of the embedded SW component differs from the main recipe. To detect CVEs in the embedded SW component, it needs to be added to CVE_PRODUCT list using name of the SW product in CVE database or with "vendor:product" syntax. Then the version of the embedded SW component can be set using CVE_VERSION_product variable. For example in meta-arm, trusted-firmware-a embeds mbed_tls SW component. Thus trusted-firmware-a can add CVE_PRODUCT for it since CVE database uses product name "mbed_tls": CVE_PRODUCT += "mbed_tls" and set the version of mbed_tls: CVE_VERSION_mbed_tls = "2.28.4" (Real patches for both are a bit more complex due to conditional build enabling mbed_tls support and due to mbed_tls version being set in an .inc file.) Now trusted-firmware-a CVE check output shows: NOTE: recipe trusted-firmware-a-2.9.0+gitd3e71ead6ea5bc3555ac90a446efec84ef6c6122-r0: task do_cve_check: Started WARNING: trusted-firmware-a-2.9.0+gitd3e71ead6ea5bc3555ac90a446efec84ef6c6122-r0 do_cve_check: Found unpatched CVE (CVE-2021-36647 CVE-2021-43666 CVE-2021-45451 CVE-2023-43615), for more information check /home/builder/src/base/build/tmp/work/arm64-poky-linux/trusted-firmware-a/2.9.0+gitd3e71ead6ea5bc3555ac90a446efec84ef6c6122/temp/cve.log NOTE: recipe trusted-firmware-a-2.9.0+gitd3e71ead6ea5bc3555ac90a446efec84ef6c6122-r0: task do_cve_check: Succeeded Here CVE-2023-43615 is a newly added and fixed CVE in version 2.28.5 and the CVEs from 2021 need to be checked but are likely fixed in 2.28.3 and newer 2.28.y releases. Note that CVE-2023-43615 does not impact trusted-firmware-a since it doesn't use TLS or null or RC4 ciphers, but I think it's a good idea to extend CVE checker for this use case. I hope the "CVE_VERSION_vendor:product" does not cause odd breakages. Signed-off-by: Mikko Rapeli <mikko.rapeli@linaro.org> --- meta/classes/cve-check.bbclass | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)