All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support
       [not found] <188AFCD98EA3E578.3200434@lists.openembedded.org>
@ 2026-01-16 19:05 ` ValentinBoudevin
  2026-01-16 19:05   ` [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
                     ` (5 more replies)
  2026-01-29 21:10 ` [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
  1 sibling, 6 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-16 19:05 UTC (permalink / raw)
  To: openembedded-core
  Cc: daniel.turull, jerome.oufella, antonin.godard, ValentinBoudevin

The script improve_kernel_cve_report.py doesn't have a bbclass.
It can be usefull to have one to generate improved cve-check files at
every run.

This new class can be used to generate a new file in tmp/deploy/images
with a .scouted.json in addition to the existing .json cve-check file.

The new .scouted.json is based on the cve-check file and the SBOM (SPDX3
mandatory) to generate this improved cve-check file with extra entries
found by the script improve_kernel_cve_report.py.

It only requires an inherit on an image recipe (e.g. "inherit
improve_kernel_cve_report" in core-image-minimal).

It can be add to core-image-minimal in a second step if revelant.

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../classes/improve_kernel_cve_report.bbclass | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 meta/classes/improve_kernel_cve_report.bbclass

diff --git a/meta/classes/improve_kernel_cve_report.bbclass b/meta/classes/improve_kernel_cve_report.bbclass
new file mode 100644
index 0000000000..5c496252b4
--- /dev/null
+++ b/meta/classes/improve_kernel_cve_report.bbclass
@@ -0,0 +1,71 @@
+python do_clean:append() {
+    import os, glob
+    if bb.utils.contains('INHERIT', 'create-spdx-2.2', 'false', 'true', d):
+        deploy_dir = d.expand('${DEPLOY_DIR_IMAGE}')
+        for f in glob.glob(os.path.join(deploy_dir, '*scouted.json')):
+            bb.note("Removing " + f)
+            os.remove(f)
+}
+
+python do_clone_kernel_cve() {
+    import subprocess
+    import shutil, os
+    check_spdx = d.getVar("INHERIT")
+    rootdir = os.path.join(d.getVar("WORKDIR"), "vulns")
+    # Check if the feature is enabled and if SPDX 2.2 is not used
+    if "create-spdx-2.2" not in check_spdx:
+        d.setVar("SRC_URI", "git://git.kernel.org/pub/scm/linux/security/vulns.git;branch=master;protocol=https")
+        d.setVar("SRCREV", "${AUTOREV}")
+        src_uri = (d.getVar('SRC_URI') or "").split()
+        # Fetch the kernel vulnerabilities sources
+        fetcher = bb.fetch2.Fetch(src_uri, d)
+        fetcher.download()
+        # Unpack into the standard work directory
+        fetcher.unpack(rootdir)
+        # Remove the folder ${PN} set by unpack
+        subdirs = [d for d in os.listdir(rootdir) if os.path.isdir(os.path.join(rootdir, d))]
+        if len(subdirs) == 1:
+            srcdir = os.path.join(rootdir, subdirs[0])
+            for f in os.listdir(srcdir):
+                shutil.move(os.path.join(srcdir, f), rootdir)
+            shutil.rmtree(srcdir)
+        bb.note("Vulnerabilities repo unpacked into: %s" % rootdir)
+    elif "create-spdx-2.2" in check_spdx:
+        bb.warn(f"improve_kernel_cve_report: Extra Kernel CVEs Scouting is desactivate because incompatible with SPDX 2.2.")
+}
+do_clone_kernel_cve[network] = "1"
+do_clone_kernel_cve[nostamp] = "1"
+do_clone_kernel_cve[doc] = "Clone the latest kernel vulnerabilities from https://git.kernel.org/pub/scm/linux/security/vulns.git"
+addtask clone_kernel_cve after
+
+do_scout_extra_kernel_vulns() {
+    spdx_file="${SPDXIMAGEDEPLOYDIR}/${IMAGE_LINK_NAME}.spdx.json"
+    original_cve_check_file="${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.json"
+    new_cve_report_file="${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.scouted.json"
+    improve_kernel_cve_script="${COREBASE}/scripts/contrib/improve_kernel_cve_report.py"
+
+    if ${@bb.utils.contains('INHERIT', 'create-spdx-2.2', 'true', 'false', d)}; then
+        bbwarn "improve_kernel_cve_report: Skipping extra kernel vulnerabilities scouting because incompatible with SPDX 2."
+        return 0
+    elif [ ! -f "${spdx_file}" ]; then
+        bbwarn "improve_kernel_cve_report: SPDX file not found: ${spdx_file}. Skipping extra kernel vulnerabilities scoutings."
+        return 0
+    elif [ ! -f "${original_cve_check_file}" ]; then
+        bbwarn "improve_kernel_cve_report: CVE_CHECK file not found: ${original_cve_check_file}. Skipping extra kernel vulnerabilities scouting."
+        return 0
+    fi
+
+    #Launch the new script to improve the cve report
+    python3 "${improve_kernel_cve_script}" \
+        --spdx "${spdx_file}" \
+        --old-cve-report "${original_cve_check_file}" \
+        --new-cve-report "${new_cve_report_file}" \
+        --datadir "${WORKDIR}/vulns"
+    bbplain "Improve CVE report with extra kernel cves: ${new_cve_report_file}"
+
+    #Create a symlink as every other JSON file in tmp/deploy/images
+    ln -sf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.scouted.json ${DEPLOY_DIR_IMAGE}/${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}${IMAGE_NAME_SUFFIX}.scouted.json
+}
+do_scout_extra_kernel_vulns[nostamp] = "1"
+do_scout_extra_kernel_vulns[doc] = "Scout extra kernel vulnerabilities and create a new enhanced version of the cve_check file in the deploy directory"
+addtask scout_extra_kernel_vulns after do_create_image_sbom_spdx before do_build
\ No newline at end of file


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

* [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
@ 2026-01-16 19:05   ` ValentinBoudevin
  2026-01-19 10:44     ` Daniel Turull
  2026-01-16 19:05   ` [PATCH v5 1/4] generate-cve-exclusions: Add --output-json option ValentinBoudevin
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-16 19:05 UTC (permalink / raw)
  To: openembedded-core
  Cc: daniel.turull, jerome.oufella, antonin.godard, ValentinBoudevin

Changes since v4:
- Patch 2/4:
  * Renamed the bbclass to kernel-generate-cve-exclusions.bbclass to better reflect its purpose.
  * Add new variable ENABLE_KERNEL_CVE_EXCLUSIONS to enable/disable the
  feature.
  By default, the feature is disabled to avoid unexpected behavior on
  existing builds with linux-yocto.
  * Add new "__anonymous" python function to setup the variables SRC_URI and SRCREV only if
  this feature is enabled with ENABLE_KERNEL_CVE_EXCLUSIONS.
  Also prevent from modifying SRC_URI and SRCREV variables in the default linux-yocto usecase.
  Now, the recipe does not have any impact on the basic "linux-yocto" recipe if the feature is disabled.
  * Add new variables GENERATE_CVE_EXCLUSIONS_DESTSUFFIX and
  GENERATE_CVE_EXCLUSIONS_UNPACK_DIR to customize the working directory path of the
  class.
- Patch 4/4:
  * Update the inherit statement in linux-yocto.inc to reflect the new name of the bbclass with
  "kernel-generate-cve-exclusions".

Changes since v3:
- Patch 2/4:
  * Add variables to control offline mode, source URI and
  SRCREV for deterministic testing (GENERATE_CVE_EXCLUSIONS_SRC_URI,
  GENERATE_CVE_EXCLUSIONS_SRCREV, GENERATE_CVE_EXCLUSIONS_NETWORK).
  * Updated generate_cve_exclusions task scheduling to be executed before
  do_cve_check.

Changes since v2:
- Patch 4/4: Inherit the new bbclass in linux-yocto.inc instead of
  individual recipes.

Changes since v1:
- Patch 2/4: Removed the mandatory execution of the
  generate-cve-exclusions class on every build. It now needs to be
  manually run using:
    bitbake -c generate-cve-exclusions <kernel-recipe>

ValentinBoudevin (4):
  generate-cve-exclusions: Add --output-json option
  generate-cve-exclusions: Add a .bbclass
  generate-cve-exclusions: Move python script
  linux: Add inherit on generate-cve-exclusions

 .../kernel-generate-cve-exclusions.bbclass    | 135 ++++++++++++++++++
 meta/recipes-kernel/linux/linux-yocto.inc     |   3 +
 .../contrib}/generate-cve-exclusions.py       |  64 +++++++--
 3 files changed, 188 insertions(+), 14 deletions(-)
 create mode 100644 meta/classes/kernel-generate-cve-exclusions.bbclass
 rename {meta/recipes-kernel/linux => scripts/contrib}/generate-cve-exclusions.py (71%)



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

* [PATCH v5 1/4] generate-cve-exclusions: Add --output-json option
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
  2026-01-16 19:05   ` [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
@ 2026-01-16 19:05   ` ValentinBoudevin
  2026-01-16 19:05   ` [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-16 19:05 UTC (permalink / raw)
  To: openembedded-core
  Cc: daniel.turull, jerome.oufella, antonin.godard, ValentinBoudevin

This option "--output-json" can be used to return a json file instead of
the standard .inc file provided.
The JSON file can easily be manipulated contrary to the .inc file.

Example output structure of the JSON file:

```json
{
  "cve_status": {
    "CVE-2019-25160": {
      "active": false,
      "message": "fixed-version: Fixed from version 5.0"
    },
    "CVE-2019-25162": {
      "active": false,
      "message": "fixed-version: Fixed from version 6.0"
    },
...
```

Also, this commit doesn't affect or modify any existing behaviour of the
script.

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../linux/generate-cve-exclusions.py          | 64 +++++++++++++++----
 1 file changed, 50 insertions(+), 14 deletions(-)

diff --git a/meta/recipes-kernel/linux/generate-cve-exclusions.py b/meta/recipes-kernel/linux/generate-cve-exclusions.py
index dfc16663a5..5a0a947e06 100755
--- a/meta/recipes-kernel/linux/generate-cve-exclusions.py
+++ b/meta/recipes-kernel/linux/generate-cve-exclusions.py
@@ -91,6 +91,7 @@ def main(argp=None):
     parser = argparse.ArgumentParser()
     parser.add_argument("datadir", type=pathlib.Path, help="Path to a clone of https://github.com/CVEProject/cvelistV5 or https://git.kernel.org/pub/scm/linux/security/vulns.git")
     parser.add_argument("version", type=Version, help="Kernel version number to generate data for, such as 6.1.38")
+    parser.add_argument("--output-json", action="store_true", help="Return CVE_STATUS mapping as JSON")
 
     args = parser.parse_args(argp)
     datadir = args.datadir.resolve()
@@ -99,7 +100,10 @@ def main(argp=None):
 
     data_version = subprocess.check_output(("git", "describe", "--tags", "HEAD"), cwd=datadir, text=True)
 
-    print(f"""
+    cve_status = {}
+
+    if not args.output_json:
+        print(f"""
 # Auto-generated CVE metadata, DO NOT EDIT BY HAND.
 # Generated at {datetime.datetime.now(datetime.timezone.utc)} for kernel version {version}
 # From {datadir.name} {data_version}
@@ -131,26 +135,58 @@ do_cve_check[prefuncs] += "check_kernel_cve_status_version"
             continue
         first_affected, fixed, backport_ver = get_fixed_versions(cve_info, base_version)
         if not fixed:
-            print(f"# {cve} has no known resolution")
+            cve_status[cve] = {
+                "active": True,
+                "message": "no known resolution"
+            }
+            if not args.output_json:
+                print(f"# {cve} has no known resolution")
         elif first_affected and version < first_affected:
-            print(f'CVE_STATUS[{cve}] = "fixed-version: only affects {first_affected} onwards"')
+            cve_status[cve] = {
+                "active": False,
+                "message": f"fixed-version: only affects {first_affected} onwards"
+            }
+            if not args.output_json:
+                print(f'CVE_STATUS[{cve}] = "fixed-version: only affects {first_affected} onwards"')
         elif fixed <= version:
-            print(
-                f'CVE_STATUS[{cve}] = "fixed-version: Fixed from version {fixed}"'
-            )
+            cve_status[cve] = {
+                "active": False,
+                "message": f"fixed-version: Fixed from version {fixed}"
+            }
+            if not args.output_json:
+                print(f'CVE_STATUS[{cve}] = "fixed-version: Fixed from version {fixed}"')
         else:
             if backport_ver:
                 if backport_ver <= version:
-                    print(
-                        f'CVE_STATUS[{cve}] = "cpe-stable-backport: Backported in {backport_ver}"'
-                    )
+                    cve_status[cve] = {
+                        "active": False,
+                        "message": f"cpe-stable-backport: Backported in {backport_ver}"
+                    }
+                    if not args.output_json:
+                        print(f'CVE_STATUS[{cve}] = "cpe-stable-backport: Backported in {backport_ver}"')
                 else:
-                    print(f"# {cve} may need backporting (fixed from {backport_ver})")
+                    cve_status[cve] = {
+                        "active": True,
+                        "message": f"May need backporting (fixed from {backport_ver})"
+                    }
+                    if not args.output_json:
+                        print(f"# {cve} may need backporting (fixed from {backport_ver})")
             else:
-                print(f"# {cve} needs backporting (fixed from {fixed})")
-
-        print()
-
+                cve_status[cve] = {
+                    "active": True,
+                    "message": f"#Needs backporting (fixed from {fixed})"
+                }
+                if not args.output_json:
+                    print(f"# {cve} needs backporting (fixed from {fixed})")
+
+        if not args.output_json:
+            print()
+
+    # Emit structured output if --ret-struct was requested
+    if args.output_json:
+        print(json.dumps({
+            "cve_status": cve_status,
+        }, indent=2))
 
 if __name__ == "__main__":
     main()


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

* [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
  2026-01-16 19:05   ` [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
  2026-01-16 19:05   ` [PATCH v5 1/4] generate-cve-exclusions: Add --output-json option ValentinBoudevin
@ 2026-01-16 19:05   ` ValentinBoudevin
  2026-01-17 13:36     ` [OE-core] " Peter Kjellerstedt
  2026-01-16 19:05   ` [PATCH v5 3/4] generate-cve-exclusions: Move python script ValentinBoudevin
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-16 19:05 UTC (permalink / raw)
  To: openembedded-core
  Cc: daniel.turull, jerome.oufella, antonin.godard, ValentinBoudevin

Add a new class named kernel-generate-cve-exclusions.bbclass to
generate-cve-exclusions to use this script at every run.

Two steps for testing:
1) Inherit this class in the kernel recipe with "inherit
   kernel-generate-cve-exclusions.bbclass"
2) Turn the variable ENABLE_KERNEL_CVE_EXCLUSIONS to "1".
3) Use the following command to generate a cvelistV5 entry with a JSON
   file in in ${WORKDIR}/cvelistV5/ :
   "bitbake linux-yocto -c generate-cve-exclusions"

The JSON file can then be parsed in the following run by cve-check.

This class contains several methods:

*do_clone_cvelistV5: Clone the cvelistV5 repo in
${WORKDIR}/cvelistV5/git

(e.g. bitbake-builds/poky-master/build/tmp/work/qemux86_64-poky-linux/
linux-yocto/6.18.1+git/cvelistV5/git)

*do_generate_cve_exclusions: Use the script generate-cve-exclusions.py.
It uses the new "--output-json" argument to generate a JSON file as an
output stored in ${WORKDIR}/cvelistV5//cve-exclusion_${LINUX_VERSION}.json

*do_cve_check:prepend: Parse the previously generated JSON file to set
the variable CVE_STATUS corretly

The class also provides some variables:
*ENABLE_KERNEL_CVE_EXCLUSIONS: Enable/Disable this class (off by default
to not affect linux-yocto OE example)
*GENERATE_CVE_EXCLUSIONS_SRC_URI and GENERATE_CVE_EXCLUSIONS_SRCREV can
be used to change the source repository or fix a commit with SRCREV
(usefull for deterministic testing)
*GENERATE_CVE_EXCLUSIONS_NETWORK can be set to 0 to provide an offline
mode based on DL_DIR directory.
*GENERATE_CVE_EXCLUSIONS_WORKDIR path used as a working directory for
this class
*GENERATE_CVE_EXCLUSIONS_DESTSUFFIX suffix used for the git unpack
*GENERATE_CVE_EXCLUSIONS_UNPACK_DIR path of the unpack for the git
repository

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../kernel-generate-cve-exclusions.bbclass    | 135 ++++++++++++++++++
 1 file changed, 135 insertions(+)
 create mode 100644 meta/classes/kernel-generate-cve-exclusions.bbclass

diff --git a/meta/classes/kernel-generate-cve-exclusions.bbclass b/meta/classes/kernel-generate-cve-exclusions.bbclass
new file mode 100644
index 0000000000..cd81cc5899
--- /dev/null
+++ b/meta/classes/kernel-generate-cve-exclusions.bbclass
@@ -0,0 +1,135 @@
+# Generate CVE exclusions for the kernel build (set to "1" to enable)
+ENABLE_KERNEL_CVE_EXCLUSIONS ?= "0"
+
+# CVE exclusions source repository settings
+GENERATE_CVE_EXCLUSIONS_SRC_URI ?= "git://github.com/CVEProject/cvelistV5.git;branch=main;protocol=https"
+GENERATE_CVE_EXCLUSIONS_SRCREV ?= "${@bb.fetch2.get_autorev(d)}"
+GENERATE_CVE_EXCLUSIONS_NETWORK ?= "1"
+GENERATE_CVE_EXCLUSIONS_WORKDIR ?= "${WORKDIR}/cvelistV5"
+GENERATE_CVE_EXCLUSIONS_DESTSUFFIX ?= "git"
+GENERATE_CVE_EXCLUSIONS_UNPACK_DIR ?= "${GENERATE_CVE_EXCLUSIONS_WORKDIR}/${GENERATE_CVE_EXCLUSIONS_DESTSUFFIX}"
+
+python __anonymous() {
+    # Only run if CVE exclusions are enabled
+    if d.getVar("ENABLE_KERNEL_CVE_EXCLUSIONS", True) == "1":
+        srcrev = d.getVar("GENERATE_CVE_EXCLUSIONS_SRCREV", True) or ""
+        network = d.getVar("GENERATE_CVE_EXCLUSIONS_NETWORK", True) or "0"
+        # Check offline mode with AUTOREV-like SRCREV
+        if network == "0" and srcrev.strip() in ("${AUTOREV}", "AUTOINC", "INVALID"):
+            bb.fatal("generate-cve-exclusions: Offline mode but SRCREV is set to AUTOREV/AUTOINC/INVALID. "
+                     "Cannot proceed without network access or use a fixed SRCREV.")
+        d.appendVar("SRC_URI", " ${GENERATE_CVE_EXCLUSIONS_SRC_URI};name=generate-cve-exclusions;destsuffix=${GENERATE_CVE_EXCLUSIONS_DESTSUFFIX}")
+        d.setVar("SRCREV_generate-cve-exclusions", d.getVar("GENERATE_CVE_EXCLUSIONS_SRCREV"))
+}
+
+python do_clone_cvelistV5() {
+    import subprocess
+    import shutil, os
+    # Only run if CVE exclusions are enabled
+    if not d.getVar("ENABLE_KERNEL_CVE_EXCLUSIONS") == "1":
+        return
+    network_allowed = d.getVar("GENERATE_CVE_EXCLUSIONS_NETWORK") == "1"
+    workdir = d.getVar("GENERATE_CVE_EXCLUSIONS_WORKDIR")
+    unpack_dir = d.getVar("GENERATE_CVE_EXCLUSIONS_UNPACK_DIR")
+    # Remove existing unpacked directory if any
+    if os.path.exists(workdir):
+        shutil.rmtree(workdir)
+    # Prepare fetcher
+    src_uri_list = (d.getVar('SRC_URI') or "").split()
+    cve_uris = []
+    for uri in src_uri_list:
+        if "name=generate-cve-exclusions" in uri:
+            cve_uris.append(uri)
+    if not cve_uris:
+        bb.note("No CVE exclusions SRC_URI found, skipping fetch")
+        return
+    fetcher = bb.fetch2.Fetch(cve_uris, d)
+    # Clone only if network is allowed
+    if network_allowed:
+        fetcher.download()
+    else:
+        # Offline mode without network access
+        bb.note("GENERATE_CVE_EXCLUSIONS_NETWORK=0: Skipping online fetch. Checking local downloads in DL_DIR...")
+        have_sources = False
+        dl_dir = d.getVar("DL_DIR")
+        srcrev = d.getVar("SRCREV_generate-cve-exclusions")
+        bb.note(f"Checking for sources for SRCREV: {srcrev}")
+        # Check SRCREV is NOT set to AUTOREV
+        if srcrev.strip() in ("${AUTOREV}", "AUTOINC", "INVALID"):
+            bb.fatal("generate-cve-exclusions: Offline mode but SRCREV is set to AUTOREV/AUTOINC/INVALID. Cannot proceed without network access or use a fixed SRCREV.")
+            return
+        # Loop through the fetcher's expanded URL data
+        for ud in fetcher.expanded_urldata():
+            ud.setup_localpath(d)
+            # Check mirror tarballs first
+            for mirror_fname in ud.mirrortarballs:
+                mirror_path = os.path.join(dl_dir, mirror_fname)
+                if os.path.exists(mirror_path):
+                    bb.note(f"Found mirror tarball: {mirror_path}")
+                    have_sources = True
+                    break
+            # If no mirror, check original download path
+            if not have_sources and ud.localpath and os.path.exists(ud.localpath):
+                bb.note(f"Found local download: {ud.localpath}")
+                have_sources = True
+            if not have_sources:
+                bb.fatal("generate-cve-exclusions: Offline mode but required source is missing.\n"f"SRC_URI = {ud.url}")
+                return
+    # Unpack into the standard work directory
+    fetcher.unpack(unpack_dir)
+    # Remove the folder ${PN} set by unpack
+    subdirs = [d for d in os.listdir(unpack_dir) if os.path.isdir(os.path.join(unpack_dir, d))]
+    if len(subdirs) == 1:
+        srcdir = os.path.join(unpack_dir, subdirs[0])
+        for f in os.listdir(srcdir):
+            shutil.move(os.path.join(srcdir, f), unpack_dir)
+        shutil.rmtree(srcdir)
+    bb.note("Vulnerabilities repo unpacked into: %s" % unpack_dir)
+}
+do_clone_cvelistV5[network] = "${GENERATE_CVE_EXCLUSIONS_NETWORK}"
+do_clone_cvelistV5[nostamp] = "1"
+do_clone_cvelistV5[doc] = "Clone CVE information from the CVE Project: https://github.com/CVEProject/cvelistV5.git"
+addtask clone_cvelistV5 before do_generate_cve_exclusions
+
+do_generate_cve_exclusions() {
+    # Only run if CVE exclusions are enabled
+    if [ "${ENABLE_KERNEL_CVE_EXCLUSIONS}" != "1" ]; then
+        return 0
+    fi
+    generate_cve_exclusions_script=${COREBASE}/scripts/contrib/generate-cve-exclusions.py
+    if [ ! -f "${generate_cve_exclusions_script}" ]; then
+        bbwarn "generate-cve-exclusions.py not found in ${COREBASE}."
+        return 0
+    fi
+    if [ ! -d "${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}" ]; then
+        bbwarn "CVE exclusions source directory not found in ${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}."
+        return 0
+    fi
+    python3 "${generate_cve_exclusions_script}" \
+        "${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}" \
+        ${LINUX_VERSION} \
+        --output-json > ${GENERATE_CVE_EXCLUSIONS_WORKDIR}/cve-exclusion_${LINUX_VERSION}.json
+    bbplain "CVE exclusions generated for kernel version ${LINUX_VERSION} at ${GENERATE_CVE_EXCLUSIONS_WORKDIR}/cve-exclusion_${LINUX_VERSION}.json."
+}
+do_generate_cve_exclusions[nostamp] = "1"
+do_generate_cve_exclusions[doc] = "Generate CVE exclusions for the kernel build. (e.g., cve-exclusion_6.12.inc)"
+addtask generate_cve_exclusions after do_clone_cvelistV5 before do_cve_check
+
+python do_cve_check:prepend() {
+    import os
+    import json
+    workdir = d.getVar("GENERATE_CVE_EXCLUSIONS_WORKDIR")
+    kernel_version = d.getVar("LINUX_VERSION")
+    json_input_file = os.path.join(workdir, "cve-exclusion_%s.json" % kernel_version)
+    if os.path.exists(json_input_file):
+        with open(json_input_file, 'r', encoding='utf-8') as f:
+            cve_data = json.load(f)
+        cve_status_dict = cve_data.get("cve_status", {})
+        count = 0
+        for cve_id, info in cve_status_dict.items():
+            if info.get("active", True):
+                continue
+            d.setVarFlag("CVE_STATUS", cve_id, info.get("message", ""))
+            count += 1
+        bb.note("Loaded %d CVE_STATUS entries from JSON output for kernel %s" % (count, kernel_version))
+}
\ No newline at end of file


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

* [PATCH v5 3/4] generate-cve-exclusions: Move python script
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
                     ` (2 preceding siblings ...)
  2026-01-16 19:05   ` [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
@ 2026-01-16 19:05   ` ValentinBoudevin
  2026-01-16 19:05   ` [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions ValentinBoudevin
  2026-01-19  9:35   ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support Daniel Turull
  5 siblings, 0 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-16 19:05 UTC (permalink / raw)
  To: openembedded-core
  Cc: daniel.turull, jerome.oufella, antonin.godard, ValentinBoudevin

The script should be located with other scripts in scripts/contrib
instead of staying in meta/classes/.

Update the new .bbclass to match this modification

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../linux => scripts/contrib}/generate-cve-exclusions.py          | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename {meta/recipes-kernel/linux => scripts/contrib}/generate-cve-exclusions.py (100%)

diff --git a/meta/recipes-kernel/linux/generate-cve-exclusions.py b/scripts/contrib/generate-cve-exclusions.py
similarity index 100%
rename from meta/recipes-kernel/linux/generate-cve-exclusions.py
rename to scripts/contrib/generate-cve-exclusions.py


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

* [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
                     ` (3 preceding siblings ...)
  2026-01-16 19:05   ` [PATCH v5 3/4] generate-cve-exclusions: Move python script ValentinBoudevin
@ 2026-01-16 19:05   ` ValentinBoudevin
  2026-01-17 13:38     ` [OE-core] " Peter Kjellerstedt
  2026-01-19  9:35   ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support Daniel Turull
  5 siblings, 1 reply; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-16 19:05 UTC (permalink / raw)
  To: openembedded-core
  Cc: daniel.turull, jerome.oufella, antonin.godard, ValentinBoudevin

Update linux-yocto.inc to inherit the new kernel-generate-cve-exclusions
class.

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 meta/recipes-kernel/linux/linux-yocto.inc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/meta/recipes-kernel/linux/linux-yocto.inc b/meta/recipes-kernel/linux/linux-yocto.inc
index 4d0a726bb6..d627afa3a5 100644
--- a/meta/recipes-kernel/linux/linux-yocto.inc
+++ b/meta/recipes-kernel/linux/linux-yocto.inc
@@ -5,6 +5,9 @@ HOMEPAGE = "https://www.yoctoproject.org/"
 
 LIC_FILES_CHKSUM ?= "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
 
+# Generate Dynamic CVE Exclusions
+inherit kernel-generate-cve-exclusions
+
 UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)"
 
 RECIPE_NO_UPDATE_REASON = "Recipe is updated through a separate process"


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

* RE: [OE-core] [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass
  2026-01-16 19:05   ` [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
@ 2026-01-17 13:36     ` Peter Kjellerstedt
  2026-01-19 10:40       ` Daniel Turull
  0 siblings, 1 reply; 21+ messages in thread
From: Peter Kjellerstedt @ 2026-01-17 13:36 UTC (permalink / raw)
  To: valentin.boudevin@gmail.com,
	openembedded-core@lists.openembedded.org
  Cc: daniel.turull@ericsson.com, jerome.oufella@savoirfairelinux.com,
	antonin.godard@bootlin.com

> -----Original Message-----
> From: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> On Behalf Of vboudevin via lists.openembedded.org
> Sent: den 16 januari 2026 20:05
> To: openembedded-core@lists.openembedded.org
> Cc: daniel.turull@ericsson.com; jerome.oufella@savoirfairelinux.com; antonin.godard@bootlin.com; ValentinBoudevin <valentin.boudevin@gmail.com>
> Subject: [OE-core] [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass

The prefix should match the class name.

> 
> Add a new class named kernel-generate-cve-exclusions.bbclass to
> generate-cve-exclusions to use this script at every run.
> 
> Two steps for testing:
> 1) Inherit this class in the kernel recipe with "inherit
>    kernel-generate-cve-exclusions.bbclass"
> 2) Turn the variable ENABLE_KERNEL_CVE_EXCLUSIONS to "1".
> 3) Use the following command to generate a cvelistV5 entry with a JSON
>    file in in ${WORKDIR}/cvelistV5/ :
>    "bitbake linux-yocto -c generate-cve-exclusions"
> 
> The JSON file can then be parsed in the following run by cve-check.
> 
> This class contains several methods:
> 
> *do_clone_cvelistV5: Clone the cvelistV5 repo in
> ${WORKDIR}/cvelistV5/git
> 
> (e.g. bitbake-builds/poky-master/build/tmp/work/qemux86_64-poky-linux/
> linux-yocto/6.18.1+git/cvelistV5/git)
> 
> *do_generate_cve_exclusions: Use the script generate-cve-exclusions.py.
> It uses the new "--output-json" argument to generate a JSON file as an
> output stored in ${WORKDIR}/cvelistV5//cve-exclusion_${LINUX_VERSION}.json
> 
> *do_cve_check:prepend: Parse the previously generated JSON file to set
> the variable CVE_STATUS corretly
> 
> The class also provides some variables:
> *ENABLE_KERNEL_CVE_EXCLUSIONS: Enable/Disable this class (off by default
> to not affect linux-yocto OE example)
> *GENERATE_CVE_EXCLUSIONS_SRC_URI and GENERATE_CVE_EXCLUSIONS_SRCREV can
> be used to change the source repository or fix a commit with SRCREV
> (usefull for deterministic testing)
> *GENERATE_CVE_EXCLUSIONS_NETWORK can be set to 0 to provide an offline
> mode based on DL_DIR directory.
> *GENERATE_CVE_EXCLUSIONS_WORKDIR path used as a working directory for
> this class
> *GENERATE_CVE_EXCLUSIONS_DESTSUFFIX suffix used for the git unpack
> *GENERATE_CVE_EXCLUSIONS_UNPACK_DIR path of the unpack for the git
> repository
> 
> Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
> ---
>  .../kernel-generate-cve-exclusions.bbclass    | 135 ++++++++++++++++++
>  1 file changed, 135 insertions(+)
>  create mode 100644 meta/classes/kernel-generate-cve-exclusions.bbclass
> 
> diff --git a/meta/classes/kernel-generate-cve-exclusions.bbclass b/meta/classes/kernel-generate-cve-exclusions.bbclass
> new file mode 100644
> index 0000000000..cd81cc5899
> --- /dev/null
> +++ b/meta/classes/kernel-generate-cve-exclusions.bbclass
> @@ -0,0 +1,135 @@
> +# Generate CVE exclusions for the kernel build (set to "1" to enable)
> +ENABLE_KERNEL_CVE_EXCLUSIONS ?= "0"
> +
> +# CVE exclusions source repository settings
> +GENERATE_CVE_EXCLUSIONS_SRC_URI ?= "git://github.com/CVEProject/cvelistV5.git;branch=main;protocol=https"
> +GENERATE_CVE_EXCLUSIONS_SRCREV ?= "${@bb.fetch2.get_autorev(d)}"
> +GENERATE_CVE_EXCLUSIONS_NETWORK ?= "1"
> +GENERATE_CVE_EXCLUSIONS_WORKDIR ?= "${WORKDIR}/cvelistV5"
> +GENERATE_CVE_EXCLUSIONS_DESTSUFFIX ?= "git"
> +GENERATE_CVE_EXCLUSIONS_UNPACK_DIR ?= "${GENERATE_CVE_EXCLUSIONS_WORKDIR}/${GENERATE_CVE_EXCLUSIONS_DESTSUFFIX}"
> +
> +python __anonymous() {
> +    # Only run if CVE exclusions are enabled
> +    if d.getVar("ENABLE_KERNEL_CVE_EXCLUSIONS", True) == "1":
> +        srcrev = d.getVar("GENERATE_CVE_EXCLUSIONS_SRCREV", True) or ""
> +        network = d.getVar("GENERATE_CVE_EXCLUSIONS_NETWORK", True) or "0"
> +        # Check offline mode with AUTOREV-like SRCREV
> +        if network == "0" and srcrev.strip() in ("${AUTOREV}", "AUTOINC", "INVALID"):
> +            bb.fatal("generate-cve-exclusions: Offline mode but SRCREV is set to AUTOREV/AUTOINC/INVALID. "
> +                     "Cannot proceed without network access or use a fixed SRCREV.")
> +        d.appendVar("SRC_URI", " ${GENERATE_CVE_EXCLUSIONS_SRC_URI};name=generate-cve-exclusions;destsuffix=${GENERATE_CVE_EXCLUSIONS_DESTSUFFIX}")
> +        d.setVar("SRCREV_generate-cve-exclusions", d.getVar("GENERATE_CVE_EXCLUSIONS_SRCREV"))
> +}
> +
> +python do_clone_cvelistV5() {
> +    import subprocess
> +    import shutil, os
> +    # Only run if CVE exclusions are enabled
> +    if not d.getVar("ENABLE_KERNEL_CVE_EXCLUSIONS") == "1":
> +        return
> +    network_allowed = d.getVar("GENERATE_CVE_EXCLUSIONS_NETWORK") == "1"
> +    workdir = d.getVar("GENERATE_CVE_EXCLUSIONS_WORKDIR")
> +    unpack_dir = d.getVar("GENERATE_CVE_EXCLUSIONS_UNPACK_DIR")
> +    # Remove existing unpacked directory if any
> +    if os.path.exists(workdir):
> +        shutil.rmtree(workdir)
> +    # Prepare fetcher
> +    src_uri_list = (d.getVar('SRC_URI') or "").split()
> +    cve_uris = []
> +    for uri in src_uri_list:
> +        if "name=generate-cve-exclusions" in uri:
> +            cve_uris.append(uri)
> +    if not cve_uris:
> +        bb.note("No CVE exclusions SRC_URI found, skipping fetch")
> +        return
> +    fetcher = bb.fetch2.Fetch(cve_uris, d)
> +    # Clone only if network is allowed
> +    if network_allowed:
> +        fetcher.download()
> +    else:
> +        # Offline mode without network access
> +        bb.note("GENERATE_CVE_EXCLUSIONS_NETWORK=0: Skipping online fetch. Checking local downloads in DL_DIR...")
> +        have_sources = False
> +        dl_dir = d.getVar("DL_DIR")
> +        srcrev = d.getVar("SRCREV_generate-cve-exclusions")
> +        bb.note(f"Checking for sources for SRCREV: {srcrev}")
> +        # Check SRCREV is NOT set to AUTOREV
> +        if srcrev.strip() in ("${AUTOREV}", "AUTOINC", "INVALID"):
> +            bb.fatal("generate-cve-exclusions: Offline mode but SRCREV is set to AUTOREV/AUTOINC/INVALID. Cannot proceed without network access or use a fixed SRCREV.")
> +            return
> +        # Loop through the fetcher's expanded URL data
> +        for ud in fetcher.expanded_urldata():
> +            ud.setup_localpath(d)
> +            # Check mirror tarballs first
> +            for mirror_fname in ud.mirrortarballs:
> +                mirror_path = os.path.join(dl_dir, mirror_fname)
> +                if os.path.exists(mirror_path):
> +                    bb.note(f"Found mirror tarball: {mirror_path}")
> +                    have_sources = True
> +                    break
> +            # If no mirror, check original download path
> +            if not have_sources and ud.localpath and os.path.exists(ud.localpath):
> +                bb.note(f"Found local download: {ud.localpath}")
> +                have_sources = True
> +            if not have_sources:
> +                bb.fatal("generate-cve-exclusions: Offline mode but required source is missing.\n"f"SRC_URI = {ud.url}")
> +                return
> +    # Unpack into the standard work directory
> +    fetcher.unpack(unpack_dir)
> +    # Remove the folder ${PN} set by unpack
> +    subdirs = [d for d in os.listdir(unpack_dir) if os.path.isdir(os.path.join(unpack_dir, d))]
> +    if len(subdirs) == 1:
> +        srcdir = os.path.join(unpack_dir, subdirs[0])
> +        for f in os.listdir(srcdir):
> +            shutil.move(os.path.join(srcdir, f), unpack_dir)
> +        shutil.rmtree(srcdir)
> +    bb.note("Vulnerabilities repo unpacked into: %s" % unpack_dir)
> +}
> +do_clone_cvelistV5[network] = "${GENERATE_CVE_EXCLUSIONS_NETWORK}"
> +do_clone_cvelistV5[nostamp] = "1"
> +do_clone_cvelistV5[doc] = "Clone CVE information from the CVE Project: https://github.com/CVEProject/cvelistV5.git"
> +addtask clone_cvelistV5 before do_generate_cve_exclusions
> +
> +do_generate_cve_exclusions() {
> +    # Only run if CVE exclusions are enabled
> +    if [ "${ENABLE_KERNEL_CVE_EXCLUSIONS}" != "1" ]; then
> +        return 0
> +    fi
> +    generate_cve_exclusions_script=${COREBASE}/scripts/contrib/generate-cve-exclusions.py
> +    if [ ! -f "${generate_cve_exclusions_script}" ]; then
> +        bbwarn "generate-cve-exclusions.py not found in ${COREBASE}."
> +        return 0
> +    fi
> +    if [ ! -d "${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}" ]; then
> +        bbwarn "CVE exclusions source directory not found in ${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}."
> +        return 0
> +    fi
> +    python3 "${generate_cve_exclusions_script}" \
> +        "${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}" \
> +        ${LINUX_VERSION} \
> +        --output-json > ${GENERATE_CVE_EXCLUSIONS_WORKDIR}/cve-exclusion_${LINUX_VERSION}.json
> +    bbplain "CVE exclusions generated for kernel version ${LINUX_VERSION} at ${GENERATE_CVE_EXCLUSIONS_WORKDIR}/cve-exclusion_${LINUX_VERSION}.json."
> +}
> +do_generate_cve_exclusions[nostamp] = "1"
> +do_generate_cve_exclusions[doc] = "Generate CVE exclusions for the kernel build. (e.g., cve-exclusion_6.12.inc)"
> +addtask generate_cve_exclusions after do_clone_cvelistV5 before do_cve_check
> +
> +python do_cve_check:prepend() {
> +    import os
> +    import json
> +    workdir = d.getVar("GENERATE_CVE_EXCLUSIONS_WORKDIR")
> +    kernel_version = d.getVar("LINUX_VERSION")
> +    json_input_file = os.path.join(workdir, "cve-exclusion_%s.json" % kernel_version)
> +    if os.path.exists(json_input_file):
> +        with open(json_input_file, 'r', encoding='utf-8') as f:
> +            cve_data = json.load(f)
> +        cve_status_dict = cve_data.get("cve_status", {})
> +        count = 0
> +        for cve_id, info in cve_status_dict.items():
> +            if info.get("active", True):
> +                continue
> +            d.setVarFlag("CVE_STATUS", cve_id, info.get("message", ""))
> +            count += 1
> +        bb.note("Loaded %d CVE_STATUS entries from JSON output for kernel %s" % (count, kernel_version))
> +}
> \ No newline at end of file

Please add a newline at the end.

//Peter



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

* RE: [OE-core] [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions
  2026-01-16 19:05   ` [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions ValentinBoudevin
@ 2026-01-17 13:38     ` Peter Kjellerstedt
  0 siblings, 0 replies; 21+ messages in thread
From: Peter Kjellerstedt @ 2026-01-17 13:38 UTC (permalink / raw)
  To: valentin.boudevin@gmail.com,
	openembedded-core@lists.openembedded.org
  Cc: daniel.turull@ericsson.com, jerome.oufella@savoirfairelinux.com,
	antonin.godard@bootlin.com

> -----Original Message-----
> From: openembedded-core@lists.openembedded.org <openembedded-core@lists.openembedded.org> On Behalf Of vboudevin via lists.openembedded.org
> Sent: den 16 januari 2026 20:05
> To: openembedded-core@lists.openembedded.org
> Cc: daniel.turull@ericsson.com; jerome.oufella@savoirfairelinux.com; antonin.godard@bootlin.com; ValentinBoudevin <valentin.boudevin@gmail.com>
> Subject: [OE-core] [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions

on generate-cve-exclusions -> of kernel-generate-cve-exclusions

> 
> Update linux-yocto.inc to inherit the new kernel-generate-cve-exclusions
> class.
> 
> Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
> ---
>  meta/recipes-kernel/linux/linux-yocto.inc | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/meta/recipes-kernel/linux/linux-yocto.inc b/meta/recipes-
> kernel/linux/linux-yocto.inc
> index 4d0a726bb6..d627afa3a5 100644
> --- a/meta/recipes-kernel/linux/linux-yocto.inc
> +++ b/meta/recipes-kernel/linux/linux-yocto.inc
> @@ -5,6 +5,9 @@ HOMEPAGE = "https://www.yoctoproject.org/"
> 
>  LIC_FILES_CHKSUM ?= "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
> 
> +# Generate Dynamic CVE Exclusions
> +inherit kernel-generate-cve-exclusions
> +
>  UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+(\.\d+)*)"
> 
>  RECIPE_NO_UPDATE_REASON = "Recipe is updated through a separate process"

//Peter



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

* RE: [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
                     ` (4 preceding siblings ...)
  2026-01-16 19:05   ` [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions ValentinBoudevin
@ 2026-01-19  9:35   ` Daniel Turull
  5 siblings, 0 replies; 21+ messages in thread
From: Daniel Turull @ 2026-01-19  9:35 UTC (permalink / raw)
  To: ValentinBoudevin, openembedded-core@lists.openembedded.org
  Cc: jerome.oufella@savoirfairelinux.com, antonin.godard@bootlin.com

Hi Valentin,

Thanks for your contribution. A bit more feedback.

There is a typo in the patch subject
kerne/kernel


> -----Original Message-----
> From: ValentinBoudevin <valentin.boudevin@gmail.com>
> Sent: Friday, 16 January 2026 20:05
> To: openembedded-core@lists.openembedded.org
> Cc: Daniel Turull <daniel.turull@ericsson.com>;
> jerome.oufella@savoirfairelinux.com; antonin.godard@bootlin.com;
> ValentinBoudevin <valentin.boudevin@gmail.com>
> Subject: [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support
>
> The script improve_kernel_cve_report.py doesn't have a bbclass.
> It can be usefull to have one to generate improved cve-check files at every
> run.
>
> This new class can be used to generate a new file in tmp/deploy/images with
> a .scouted.json in addition to the existing .json cve-check file.
>
> The new .scouted.json is based on the cve-check file and the SBOM (SPDX3
> mandatory) to generate this improved cve-check file with extra entries found
> by the script improve_kernel_cve_report.py.
>
> It only requires an inherit on an image recipe (e.g. "inherit
> improve_kernel_cve_report" in core-image-minimal).
>
> It can be add to core-image-minimal in a second step if revelant.
>
> Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
> ---
>  .../classes/improve_kernel_cve_report.bbclass | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 meta/classes/improve_kernel_cve_report.bbclass
>
> diff --git a/meta/classes/improve_kernel_cve_report.bbclass
> b/meta/classes/improve_kernel_cve_report.bbclass
> new file mode 100644
> index 0000000000..5c496252b4
> --- /dev/null
> +++ b/meta/classes/improve_kernel_cve_report.bbclass
> @@ -0,0 +1,71 @@
> +python do_clean:append() {
> +    import os, glob
> +    if bb.utils.contains('INHERIT', 'create-spdx-2.2', 'false', 'true', d):
> +        deploy_dir = d.expand('${DEPLOY_DIR_IMAGE}')
> +        for f in glob.glob(os.path.join(deploy_dir, '*scouted.json')):
> +            bb.note("Removing " + f)
> +            os.remove(f)
> +}
> +
> +python do_clone_kernel_cve() {
> +    import subprocess
> +    import shutil, os
> +    check_spdx = d.getVar("INHERIT")
> +    rootdir = os.path.join(d.getVar("WORKDIR"), "vulns")
> +    # Check if the feature is enabled and if SPDX 2.2 is not used
> +    if "create-spdx-2.2" not in check_spdx:
> +        d.setVar("SRC_URI",
> "git://git.kernel.org/pub/scm/linux/security/vulns.git;branch=master;protocol
> =https")
> +        d.setVar("SRCREV", "${AUTOREV}")
> +        src_uri = (d.getVar('SRC_URI') or "").split()
> +        # Fetch the kernel vulnerabilities sources
> +        fetcher = bb.fetch2.Fetch(src_uri, d)
> +        fetcher.download()
> +        # Unpack into the standard work directory
> +        fetcher.unpack(rootdir)
> +        # Remove the folder ${PN} set by unpack
> +        subdirs = [d for d in os.listdir(rootdir) if
> os.path.isdir(os.path.join(rootdir, d))]
> +        if len(subdirs) == 1:
> +            srcdir = os.path.join(rootdir, subdirs[0])
> +            for f in os.listdir(srcdir):
> +                shutil.move(os.path.join(srcdir, f), rootdir)
> +            shutil.rmtree(srcdir)
> +        bb.note("Vulnerabilities repo unpacked into: %s" % rootdir)
> +    elif "create-spdx-2.2" in check_spdx:
> +        bb.warn(f"improve_kernel_cve_report: Extra Kernel CVEs Scouting
> +is desactivate because incompatible with SPDX 2.2.") }

The script accepts both spdx2 and spdx3

> +do_clone_kernel_cve[network] = "1"
> +do_clone_kernel_cve[nostamp] = "1"
> +do_clone_kernel_cve[doc] = "Clone the latest kernel vulnerabilities from
> https://git.kern/
> el.org%2Fpub%2Fscm%2Flinux%2Fsecurity%2Fvulns.git&data=05%7C02%7Cd
> aniel.turull%40ericsson.com%7Cca7acecb518d48391e3408de55333e8e%7C92
> e84cebfbfd47abbe52080c6b87953f%7C0%7C0%7C639041875752180972%7C
> Unknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDA
> wMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%
> 7C&sdata=EXS18CY6gFkHdj4C%2F6%2BeknzXrU8h4b3Uct8T2OAQTFE%3D&re
> served=0"
> +addtask clone_kernel_cve after
> +
> +do_scout_extra_kernel_vulns() {
> +    spdx_file="${SPDXIMAGEDEPLOYDIR}/${IMAGE_LINK_NAME}.spdx.json"
> +
> original_cve_check_file="${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.json
> "
> +
> new_cve_report_file="${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.scouted.json
> "
> +
> improve_kernel_cve_script="${COREBASE}/scripts/contrib/improve_kernel_cv
> e_report.py"
> +
> +    if ${@bb.utils.contains('INHERIT', 'create-spdx-2.2', 'true', 'false', d)}; then
> +        bbwarn "improve_kernel_cve_report: Skipping extra kernel
> vulnerabilities scouting because incompatible with SPDX 2."
> +        return 0
> +    elif [ ! -f "${spdx_file}" ]; then
> +        bbwarn "improve_kernel_cve_report: SPDX file not found: ${spdx_file}.
> Skipping extra kernel vulnerabilities scoutings."
> +        return 0
> +    elif [ ! -f "${original_cve_check_file}" ]; then
> +        bbwarn "improve_kernel_cve_report: CVE_CHECK file not found:
> ${original_cve_check_file}. Skipping extra kernel vulnerabilities scouting."
> +        return 0
> +    fi
> +
> +    #Launch the new script to improve the cve report
> +    python3 "${improve_kernel_cve_script}" \
> +        --spdx "${spdx_file}" \

The script automatically detects the spdx format. You can also use the debugsources file to be spdx independent.

> +        --old-cve-report "${original_cve_check_file}" \
> +        --new-cve-report "${new_cve_report_file}" \
> +        --datadir "${WORKDIR}/vulns"
> +    bbplain "Improve CVE report with extra kernel cves:
> ${new_cve_report_file}"
> +
> +    #Create a symlink as every other JSON file in tmp/deploy/images
> +    ln -sf ${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}.scouted.json
> +${DEPLOY_DIR_IMAGE}/${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}$
> {IMAGE_NAM
> +E_SUFFIX}.scouted.json
> +}
> +do_scout_extra_kernel_vulns[nostamp] = "1"
> +do_scout_extra_kernel_vulns[doc] = "Scout extra kernel vulnerabilities and
> create a new enhanced version of the cve_check file in the deploy directory"
> +addtask scout_extra_kernel_vulns after do_create_image_sbom_spdx
> before
> +do_build
> \ No newline at end of file

Daniel

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

* RE: [OE-core] [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass
  2026-01-17 13:36     ` [OE-core] " Peter Kjellerstedt
@ 2026-01-19 10:40       ` Daniel Turull
  0 siblings, 0 replies; 21+ messages in thread
From: Daniel Turull @ 2026-01-19 10:40 UTC (permalink / raw)
  To: Peter Kjellerstedt, valentin.boudevin@gmail.com,
	openembedded-core@lists.openembedded.org
  Cc: jerome.oufella@savoirfairelinux.com, antonin.godard@bootlin.com



> -----Original Message-----
> From: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
> Sent: Saturday, 17 January 2026 14:36
> To: valentin.boudevin@gmail.com; openembedded-
> core@lists.openembedded.org
> Cc: Daniel Turull <daniel.turull@ericsson.com>;
> jerome.oufella@savoirfairelinux.com; antonin.godard@bootlin.com
> Subject: RE: [OE-core] [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass
> 
> [You don't often get email from peter.kjellerstedt@axis.com. Learn why this is
> important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> > -----Original Message-----
> > From: openembedded-core@lists.openembedded.org
> > <openembedded-core@lists.openembedded.org> On Behalf Of vboudevin
> via
> > lists.openembedded.org
> > Sent: den 16 januari 2026 20:05
> > To: openembedded-core@lists.openembedded.org
> > Cc: daniel.turull@ericsson.com; jerome.oufella@savoirfairelinux.com;
> > antonin.godard@bootlin.com; ValentinBoudevin
> > <valentin.boudevin@gmail.com>
> > Subject: [OE-core] [PATCH v5 2/4] generate-cve-exclusions: Add a
> > .bbclass
> 
> The prefix should match the class name.
> 
> >
> > Add a new class named kernel-generate-cve-exclusions.bbclass to
> > generate-cve-exclusions to use this script at every run.
> >
> > Two steps for testing:
> > 1) Inherit this class in the kernel recipe with "inherit
> >    kernel-generate-cve-exclusions.bbclass"
> > 2) Turn the variable ENABLE_KERNEL_CVE_EXCLUSIONS to "1".
> > 3) Use the following command to generate a cvelistV5 entry with a JSON
> >    file in in ${WORKDIR}/cvelistV5/ :
> >    "bitbake linux-yocto -c generate-cve-exclusions"
> >
The task is using _ instead of -

 bitbake linux-yocto -c do_generate_cve_exclusions 

> > The JSON file can then be parsed in the following run by cve-check.
> >
> > This class contains several methods:
> >
> > *do_clone_cvelistV5: Clone the cvelistV5 repo in
> > ${WORKDIR}/cvelistV5/git
> >
> > (e.g. bitbake-builds/poky-master/build/tmp/work/qemux86_64-poky-linux/
> > linux-yocto/6.18.1+git/cvelistV5/git)
> >
> > *do_generate_cve_exclusions: Use the script generate-cve-exclusions.py.
> > It uses the new "--output-json" argument to generate a JSON file as an
> > output stored in
> > ${WORKDIR}/cvelistV5//cve-exclusion_${LINUX_VERSION}.json
> >
> > *do_cve_check:prepend: Parse the previously generated JSON file to set
> > the variable CVE_STATUS corretly
> >
> > The class also provides some variables:
> > *ENABLE_KERNEL_CVE_EXCLUSIONS: Enable/Disable this class (off by
> > default to not affect linux-yocto OE example)
> > *GENERATE_CVE_EXCLUSIONS_SRC_URI and
> GENERATE_CVE_EXCLUSIONS_SRCREV
> > can be used to change the source repository or fix a commit with
> > SRCREV (usefull for deterministic testing)
> > *GENERATE_CVE_EXCLUSIONS_NETWORK can be set to 0 to provide an
> offline
> > mode based on DL_DIR directory.
> > *GENERATE_CVE_EXCLUSIONS_WORKDIR path used as a working directory
> for
> > this class *GENERATE_CVE_EXCLUSIONS_DESTSUFFIX suffix used for the git
> > unpack *GENERATE_CVE_EXCLUSIONS_UNPACK_DIR path of the unpack for
> the
> > git repository
> >
> > Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
> > ---
> >  .../kernel-generate-cve-exclusions.bbclass    | 135 ++++++++++++++++++
> >  1 file changed, 135 insertions(+)
> >  create mode 100644
> > meta/classes/kernel-generate-cve-exclusions.bbclass
> >
> > diff --git a/meta/classes/kernel-generate-cve-exclusions.bbclass
> > b/meta/classes/kernel-generate-cve-exclusions.bbclass
> > new file mode 100644
> > index 0000000000..cd81cc5899
> > --- /dev/null
> > +++ b/meta/classes/kernel-generate-cve-exclusions.bbclass
> > @@ -0,0 +1,135 @@
> > +# Generate CVE exclusions for the kernel build (set to "1" to enable)
> > +ENABLE_KERNEL_CVE_EXCLUSIONS ?= "0"
> > +
> > +# CVE exclusions source repository settings
> > +GENERATE_CVE_EXCLUSIONS_SRC_URI ?=
> "git://github.com/CVEProject/cvelistV5.git;branch=main;protocol=https"
> > +GENERATE_CVE_EXCLUSIONS_SRCREV ?= "${@bb.fetch2.get_autorev(d)}"
> > +GENERATE_CVE_EXCLUSIONS_NETWORK ?= "1"
> > +GENERATE_CVE_EXCLUSIONS_WORKDIR ?= "${WORKDIR}/cvelistV5"
> > +GENERATE_CVE_EXCLUSIONS_DESTSUFFIX ?= "git"
> > +GENERATE_CVE_EXCLUSIONS_UNPACK_DIR ?=
> "${GENERATE_CVE_EXCLUSIONS_WORKDIR}/${GENERATE_CVE_EXCLUSIONS_
> DESTSUFFIX}"
> > +
> > +python __anonymous() {
> > +    # Only run if CVE exclusions are enabled
> > +    if d.getVar("ENABLE_KERNEL_CVE_EXCLUSIONS", True) == "1":
> > +        srcrev = d.getVar("GENERATE_CVE_EXCLUSIONS_SRCREV", True) or ""
> > +        network = d.getVar("GENERATE_CVE_EXCLUSIONS_NETWORK", True)
> or "0"
> > +        # Check offline mode with AUTOREV-like SRCREV
> > +        if network == "0" and srcrev.strip() in ("${AUTOREV}", "AUTOINC",
> "INVALID"):
> > +            bb.fatal("generate-cve-exclusions: Offline mode but SRCREV is set to
> AUTOREV/AUTOINC/INVALID. "
> > +                     "Cannot proceed without network access or use a fixed
> SRCREV.")
> > +        d.appendVar("SRC_URI", "
> ${GENERATE_CVE_EXCLUSIONS_SRC_URI};name=generate-cve-
> exclusions;destsuffix=${GENERATE_CVE_EXCLUSIONS_DESTSUFFIX}")
> > +        d.setVar("SRCREV_generate-cve-exclusions",
> > +d.getVar("GENERATE_CVE_EXCLUSIONS_SRCREV"))
> > +}
> > +
> > +python do_clone_cvelistV5() {
> > +    import subprocess
> > +    import shutil, os
> > +    # Only run if CVE exclusions are enabled
> > +    if not d.getVar("ENABLE_KERNEL_CVE_EXCLUSIONS") == "1":
> > +        return
> > +    network_allowed = d.getVar("GENERATE_CVE_EXCLUSIONS_NETWORK")
> == "1"
> > +    workdir = d.getVar("GENERATE_CVE_EXCLUSIONS_WORKDIR")
> > +    unpack_dir = d.getVar("GENERATE_CVE_EXCLUSIONS_UNPACK_DIR")
> > +    # Remove existing unpacked directory if any
> > +    if os.path.exists(workdir):
> > +        shutil.rmtree(workdir)
> > +    # Prepare fetcher
> > +    src_uri_list = (d.getVar('SRC_URI') or "").split()
> > +    cve_uris = []
> > +    for uri in src_uri_list:
> > +        if "name=generate-cve-exclusions" in uri:
> > +            cve_uris.append(uri)
> > +    if not cve_uris:
> > +        bb.note("No CVE exclusions SRC_URI found, skipping fetch")
> > +        return
> > +    fetcher = bb.fetch2.Fetch(cve_uris, d)
> > +    # Clone only if network is allowed
> > +    if network_allowed:
> > +        fetcher.download()
> > +    else:
> > +        # Offline mode without network access
> > +        bb.note("GENERATE_CVE_EXCLUSIONS_NETWORK=0: Skipping online
> fetch. Checking local downloads in DL_DIR...")
> > +        have_sources = False
> > +        dl_dir = d.getVar("DL_DIR")
> > +        srcrev = d.getVar("SRCREV_generate-cve-exclusions")
> > +        bb.note(f"Checking for sources for SRCREV: {srcrev}")
> > +        # Check SRCREV is NOT set to AUTOREV
> > +        if srcrev.strip() in ("${AUTOREV}", "AUTOINC", "INVALID"):
> > +            bb.fatal("generate-cve-exclusions: Offline mode but SRCREV is set to
> AUTOREV/AUTOINC/INVALID. Cannot proceed without network access or use
> a fixed SRCREV.")
> > +            return
> > +        # Loop through the fetcher's expanded URL data
> > +        for ud in fetcher.expanded_urldata():
> > +            ud.setup_localpath(d)
> > +            # Check mirror tarballs first
> > +            for mirror_fname in ud.mirrortarballs:
> > +                mirror_path = os.path.join(dl_dir, mirror_fname)
> > +                if os.path.exists(mirror_path):
> > +                    bb.note(f"Found mirror tarball: {mirror_path}")
> > +                    have_sources = True
> > +                    break
> > +            # If no mirror, check original download path
> > +            if not have_sources and ud.localpath and
> os.path.exists(ud.localpath):
> > +                bb.note(f"Found local download: {ud.localpath}")
> > +                have_sources = True
> > +            if not have_sources:
> > +                bb.fatal("generate-cve-exclusions: Offline mode but required
> source is missing.\n"f"SRC_URI = {ud.url}")
> > +                return
> > +    # Unpack into the standard work directory
> > +    fetcher.unpack(unpack_dir)
> > +    # Remove the folder ${PN} set by unpack
> > +    subdirs = [d for d in os.listdir(unpack_dir) if
> os.path.isdir(os.path.join(unpack_dir, d))]
> > +    if len(subdirs) == 1:
> > +        srcdir = os.path.join(unpack_dir, subdirs[0])
> > +        for f in os.listdir(srcdir):
> > +            shutil.move(os.path.join(srcdir, f), unpack_dir)
> > +        shutil.rmtree(srcdir)
> > +    bb.note("Vulnerabilities repo unpacked into: %s" % unpack_dir) }
> > +do_clone_cvelistV5[network] =
> "${GENERATE_CVE_EXCLUSIONS_NETWORK}"
> > +do_clone_cvelistV5[nostamp] = "1"
> > +do_clone_cvelistV5[doc] = "Clone CVE information from the CVE Project:
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.
> com%2FCVEProject%2FcvelistV5.git&data=05%7C02%7Cdaniel.turull%40ericss
> on.com%7Cfa5589510fa742416d8a08de55cd6520%7C92e84cebfbfd47abbe52
> 080c6b87953f%7C0%7C0%7C639042537815406521%7CUnknown%7CTWFpb
> GZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zM
> iIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=xnXk6OEkQ
> 28sBu5RzuX3xtWT%2B1hfEEKaSMeoDhreo30%3D&reserved=0"
> > +addtask clone_cvelistV5 before do_generate_cve_exclusions
> > +
> > +do_generate_cve_exclusions() {
> > +    # Only run if CVE exclusions are enabled
> > +    if [ "${ENABLE_KERNEL_CVE_EXCLUSIONS}" != "1" ]; then
> > +        return 0
> > +    fi
> > +    generate_cve_exclusions_script=${COREBASE}/scripts/contrib/generate-
> cve-exclusions.py
> > +    if [ ! -f "${generate_cve_exclusions_script}" ]; then
> > +        bbwarn "generate-cve-exclusions.py not found in ${COREBASE}."
> > +        return 0
> > +    fi
> > +    if [ ! -d "${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}" ]; then
> > +        bbwarn "CVE exclusions source directory not found in
> ${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}."
> > +        return 0
> > +    fi
> > +    python3 "${generate_cve_exclusions_script}" \
> > +        "${GENERATE_CVE_EXCLUSIONS_UNPACK_DIR}" \
> > +        ${LINUX_VERSION} \
> > +        --output-json > ${GENERATE_CVE_EXCLUSIONS_WORKDIR}/cve-
> exclusion_${LINUX_VERSION}.json
> > +    bbplain "CVE exclusions generated for kernel version ${LINUX_VERSION}
> at ${GENERATE_CVE_EXCLUSIONS_WORKDIR}/cve-
> exclusion_${LINUX_VERSION}.json."
> > +}
> > +do_generate_cve_exclusions[nostamp] = "1"
> > +do_generate_cve_exclusions[doc] = "Generate CVE exclusions for the
> kernel build. (e.g., cve-exclusion_6.12.inc)"
> > +addtask generate_cve_exclusions after do_clone_cvelistV5 before
> > +do_cve_check
> > +
> > +python do_cve_check:prepend() {
> > +    import os
> > +    import json
> > +    workdir = d.getVar("GENERATE_CVE_EXCLUSIONS_WORKDIR")
> > +    kernel_version = d.getVar("LINUX_VERSION")
> > +    json_input_file = os.path.join(workdir, "cve-exclusion_%s.json" %
> kernel_version)
> > +    if os.path.exists(json_input_file):
> > +        with open(json_input_file, 'r', encoding='utf-8') as f:
> > +            cve_data = json.load(f)
> > +        cve_status_dict = cve_data.get("cve_status", {})
> > +        count = 0
> > +        for cve_id, info in cve_status_dict.items():
> > +            if info.get("active", True):
> > +                continue
> > +            d.setVarFlag("CVE_STATUS", cve_id, info.get("message", ""))
> > +            count += 1
> > +        bb.note("Loaded %d CVE_STATUS entries from JSON output for
> > +kernel %s" % (count, kernel_version)) }
> > \ No newline at end of file
> 
> Please add a newline at the end.
> 
> //Peter


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

* RE: [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass
  2026-01-16 19:05   ` [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
@ 2026-01-19 10:44     ` Daniel Turull
  0 siblings, 0 replies; 21+ messages in thread
From: Daniel Turull @ 2026-01-19 10:44 UTC (permalink / raw)
  To: ValentinBoudevin, openembedded-core@lists.openembedded.org
  Cc: jerome.oufella@savoirfairelinux.com, antonin.godard@bootlin.com,
	Peter Kjellerstedt, Joshua Watt

Thanks for the changes Valentin,

I have tested series 5 as offline build. When it is not enable, it doesn't interfere with the rest of the build.

For offline build, I had to setup a fix GENERATE_CVE_EXCLUSIONS_SRCREV, since the fetcher doesn't work with AUTOREV (kind of expected). This seems to work.
ENABLE_KERNEL_CVE_EXCLUSIONS = "1"
GENERATE_CVE_EXCLUSIONS_SRCREV = "bcd089af283df7902b33e9cf0cedef5aa2c4a298"
GENERATE_CVE_EXCLUSIONS_NETWORK = "0"

When setting GENERATE_CVE_EXCLUSIONS_SRC_URI to an internal mirror it also works with AUTOREV

ENABLE_KERNEL_CVE_EXCLUSIONS = "1"
GENERATE_CVE_EXCLUSIONS_SRC_URI = "git://internal-mirror/github.com.CVEProject.cvelistV5;protocol=https;branch=main"
GENERATE_CVE_EXCLUSIONS_SRCREV = "AUTOREV"

I have also look at the generate SPDX for the linux-yocto, it includes an additional source, which technically is not that correct I think
jq . tmp/deploy/spdx/3.0.1/qemuarm64/recipes/recipe-linux-yocto.spdx.json | grep cvelistV5 -A 3 -B 10
    {
      "type": "software_Package",
      "spdxId": "http://spdx.org/spdxdocs/linux-yocto-f9f75dbe-e63f-5a48-86d8-e19d0ec693db/a35fa1d8530e46c84d59b6776858eafc75bdd98b8439c2ee06db6fdab151a8c3/source/3",
      "creationInfo": "_:CreationInfo0",
      "extension": [
        {
          "type": "https://rdf.openembedded.org/spdx/3.0/id-alias",
          "https://rdf.openembedded.org/spdx/3.0/alias": "http://spdxdocs.org/openembedded-alias/by-doc-hash/8fe80285f43eb235d61996ced46668293eb3feaba85810b14aed822b4680e56f/linux-yocto/UNIHASH/source/3"
        }
      ],
      "name": "github.com.CVEProject.cvelistV5.git",
      "software_primaryPurpose": "source",
      "software_downloadLocation": "git+https://github.com/CVEProject/cvelistV5.git@bcd089af283df7902b33e9cf0cedef5aa2c4a298"
    },

Also bitbake linux-yocto -c do_generate_cve_exclusions works as expected, if it will be updating the inc file that is used in the linux-yocto with the exclusions, these will also show up in the SPDX file.

Thanks again for trying to push the changes that you have in vulnscout into oe-core.

Best regards
Daniel

> -----Original Message-----
> From: ValentinBoudevin <valentin.boudevin@gmail.com>
> Sent: Friday, 16 January 2026 20:05
> To: openembedded-core@lists.openembedded.org
> Cc: Daniel Turull <daniel.turull@ericsson.com>;
> jerome.oufella@savoirfairelinux.com; antonin.godard@bootlin.com;
> ValentinBoudevin <valentin.boudevin@gmail.com>
> Subject: [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass
> 
> Changes since v4:
> - Patch 2/4:
>   * Renamed the bbclass to kernel-generate-cve-exclusions.bbclass to better
> reflect its purpose.
>   * Add new variable ENABLE_KERNEL_CVE_EXCLUSIONS to enable/disable
> the
>   feature.
>   By default, the feature is disabled to avoid unexpected behavior on
>   existing builds with linux-yocto.
>   * Add new "__anonymous" python function to setup the variables SRC_URI
> and SRCREV only if
>   this feature is enabled with ENABLE_KERNEL_CVE_EXCLUSIONS.
>   Also prevent from modifying SRC_URI and SRCREV variables in the default
> linux-yocto usecase.
>   Now, the recipe does not have any impact on the basic "linux-yocto" recipe if
> the feature is disabled.
>   * Add new variables GENERATE_CVE_EXCLUSIONS_DESTSUFFIX and
>   GENERATE_CVE_EXCLUSIONS_UNPACK_DIR to customize the working
> directory path of the
>   class.
> - Patch 4/4:
>   * Update the inherit statement in linux-yocto.inc to reflect the new name of
> the bbclass with
>   "kernel-generate-cve-exclusions".
> 
> Changes since v3:
> - Patch 2/4:
>   * Add variables to control offline mode, source URI and
>   SRCREV for deterministic testing (GENERATE_CVE_EXCLUSIONS_SRC_URI,
>   GENERATE_CVE_EXCLUSIONS_SRCREV,
> GENERATE_CVE_EXCLUSIONS_NETWORK).
>   * Updated generate_cve_exclusions task scheduling to be executed before
>   do_cve_check.
> 
> Changes since v2:
> - Patch 4/4: Inherit the new bbclass in linux-yocto.inc instead of
>   individual recipes.
> 
> Changes since v1:
> - Patch 2/4: Removed the mandatory execution of the
>   generate-cve-exclusions class on every build. It now needs to be
>   manually run using:
>     bitbake -c generate-cve-exclusions <kernel-recipe>
> 
> ValentinBoudevin (4):
>   generate-cve-exclusions: Add --output-json option
>   generate-cve-exclusions: Add a .bbclass
>   generate-cve-exclusions: Move python script
>   linux: Add inherit on generate-cve-exclusions
> 
>  .../kernel-generate-cve-exclusions.bbclass    | 135 ++++++++++++++++++
>  meta/recipes-kernel/linux/linux-yocto.inc     |   3 +
>  .../contrib}/generate-cve-exclusions.py       |  64 +++++++--
>  3 files changed, 188 insertions(+), 14 deletions(-)  create mode 100644
> meta/classes/kernel-generate-cve-exclusions.bbclass
>  rename {meta/recipes-kernel/linux => scripts/contrib}/generate-cve-
> exclusions.py (71%)


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

* [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass
       [not found] <188AFCD98EA3E578.3200434@lists.openembedded.org>
  2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
@ 2026-01-29 21:10 ` ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 1/4] generate-cve-exclusions: Add output format option ValentinBoudevin
                     ` (3 more replies)
  1 sibling, 4 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-29 21:10 UTC (permalink / raw)
  To: openembedded-core; +Cc: daniel.turull, jerome.oufella, ValentinBoudevin

Changes since v5:
- Add a new commit to add a new receipe cvelistv5-native to clone the
  cvelistv5 repository.
- Update the script generate-cve-exclusions.py to use provide the JSON
  format output with the INC output at the same time using --output-json-file and
  --output-inc-file options.
- Update the .bbclass to use the new cvelistv5-native recipe.
- Remove tasks and variables from the .bbclass to simplify the code:
  * Remove the do_clone_cvelistV5 task.
  * Remove __anonymous function to setup SRC_URI and SRCREV.
  * Remove the variables GENERATE_CVE_EXCLUSIONS_SRC_URI,
    GENERATE_CVE_EXCLUSIONS_SRCREV, GENERATE_CVE_EXCLUSIONS_NETWORK, GENERATE_CVE_EXCLUSIONS_WORKDIR,
    GENERATE_CVE_EXCLUSIONS_DESTSUFFIX, and GENERATE_CVE_EXCLUSIONS_UNPACK_DIR
    since they are not needed anymore.
- Remove direct inclusion in linux-yocto.inc and let the user include the
  bbclass in their kernel recipe if they want to use it.
  Using ENABLE_KERNEL_CVE_EXCLUSIONS variable to enable/disable the feature is
  not needed anymore. Including the bbclass is a cleaner implementation compare to set a variable
  to enable/disable the feature.
- Add the variables:
  *GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON
  *GENERATE_CVE_EXCLUSIONS_OUTPUT_INC
  to customize the output paths of the generated files.

Changes since v4:
- Patch 2/4:
  * Renamed the bbclass to kernel-generate-cve-exclusions.bbclass to better reflect its purpose.
  * Add new variable ENABLE_KERNEL_CVE_EXCLUSIONS to enable/disable the
  feature.
  By default, the feature is disabled to avoid unexpected behavior on
  existing builds with linux-yocto.
  * Add new "__anonymous" python function to setup the variables SRC_URI and SRCREV only if
  this feature is enabled with ENABLE_KERNEL_CVE_EXCLUSIONS.
  Also prevent from modifying SRC_URI and SRCREV variables in the default linux-yocto usecase.
  Now, the recipe does not have any impact on the basic "linux-yocto" recipe if the feature is disabled.
  * Add new variables GENERATE_CVE_EXCLUSIONS_DESTSUFFIX and
  GENERATE_CVE_EXCLUSIONS_UNPACK_DIR to customize the working directory path of the
  class.
- Patch 4/4:
  * Update the inherit statement in linux-yocto.inc to reflect the new name of the bbclass with
  "kernel-generate-cve-exclusions".

Changes since v3:
- Patch 2/4:
  * Add variables to control offline mode, source URI and
  SRCREV for deterministic testing (GENERATE_CVE_EXCLUSIONS_SRC_URI,
  GENERATE_CVE_EXCLUSIONS_SRCREV, GENERATE_CVE_EXCLUSIONS_NETWORK).
  * Updated generate_cve_exclusions task scheduling to be executed before
  do_cve_check.

Changes since v2:
- Patch 4/4: Inherit the new bbclass in linux-yocto.inc instead of
  individual recipes.

Changes since v1:
- Patch 2/4: Removed the mandatory execution of the
  generate-cve-exclusions class on every build. It now needs to be
  manually run using:
    bitbake -c generate-cve-exclusions <kernel-recipe>

ValentinBoudevin (4):
  generate-cve-exclusions: Add output format option
  cvelistv5: add a new recipe
  kernel-generate-cve-exclusions: Add a .bbclass
  generate-cve-exclusions: Move python script

 .../kernel-generate-cve-exclusions.bbclass    |  46 ++++++++
 .../cvelistv5-native/cvelistv5-native_git.bb  |  24 ++++
 .../contrib}/generate-cve-exclusions.py       | 107 +++++++++++++++---
 3 files changed, 160 insertions(+), 17 deletions(-)
 create mode 100644 meta/classes/kernel-generate-cve-exclusions.bbclass
 create mode 100644 meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb
 rename {meta/recipes-kernel/linux => scripts/contrib}/generate-cve-exclusions.py (55%)



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

* [PATCH v6 1/4] generate-cve-exclusions: Add output format option
  2026-01-29 21:10 ` [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
@ 2026-01-29 21:10   ` ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 2/4] cvelistv5: add a new recipe ValentinBoudevin
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-29 21:10 UTC (permalink / raw)
  To: openembedded-core; +Cc: daniel.turull, jerome.oufella, ValentinBoudevin

This option "--output-json-file" can be used to return a json file instead of
the printing the output in a .inc file.
The JSON file can easily be manipulated contrary to the .inc file.

Example output structure of the JSON file:

```json
{
  "cve_status": {
    "CVE-2019-25160": {
      "active": false,
      "message": "fixed-version: Fixed from version 5.0"
    },
    "CVE-2019-25162": {
      "active": false,
      "message": "fixed-version: Fixed from version 6.0"
    },
...
```

Add a second option "--output-inc-file" to also create a .inc at a given
location.

Both "--output-inc-file" and "--output-json-file" can be used at the
same time.

This commit doesn't affect or modify any existing behaviour of the
script.

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../linux/generate-cve-exclusions.py          | 107 +++++++++++++++---
 1 file changed, 90 insertions(+), 17 deletions(-)

diff --git a/meta/recipes-kernel/linux/generate-cve-exclusions.py b/meta/recipes-kernel/linux/generate-cve-exclusions.py
index dfc16663a5..3df0e93e07 100755
--- a/meta/recipes-kernel/linux/generate-cve-exclusions.py
+++ b/meta/recipes-kernel/linux/generate-cve-exclusions.py
@@ -91,19 +91,38 @@ def main(argp=None):
     parser = argparse.ArgumentParser()
     parser.add_argument("datadir", type=pathlib.Path, help="Path to a clone of https://github.com/CVEProject/cvelistV5 or https://git.kernel.org/pub/scm/linux/security/vulns.git")
     parser.add_argument("version", type=Version, help="Kernel version number to generate data for, such as 6.1.38")
+    parser.add_argument("--output-json-file", type=pathlib.Path, help="Write CVE_STATUS mapping to this JSON file")
+    parser.add_argument("--output-inc-file", type=pathlib.Path, help="Write CVE_STATUS mapping to this INC file")
 
     args = parser.parse_args(argp)
     datadir = args.datadir.resolve()
     version = args.version
     base_version = Version(f"{version.major}.{version.minor}")
-
-    data_version = subprocess.check_output(("git", "describe", "--tags", "HEAD"), cwd=datadir, text=True)
-
-    print(f"""
+    print_to_stdout = not args.output_json_file and not args.output_inc_file
+
+    cve_status = {}
+    inc_lines = []
+    
+    if print_to_stdout:
+        data_version = subprocess.check_output(("git", "describe", "--tags", "HEAD"), cwd=datadir, text=True)
+        print(f"""
 # Auto-generated CVE metadata, DO NOT EDIT BY HAND.
 # Generated at {datetime.datetime.now(datetime.timezone.utc)} for kernel version {version}
 # From {datadir.name} {data_version}
 
+python check_kernel_cve_status_version() {{
+    this_version = "{version}"
+    kernel_version = d.getVar("LINUX_VERSION")
+    if kernel_version != this_version:
+        bb.warn("Kernel CVE status needs updating: generated for %s but kernel is %s" % (this_version, kernel_version))
+}}
+do_cve_check[prefuncs] += "check_kernel_cve_status_version"
+""")
+    elif args.output_inc_file:
+        inc_lines.append(f"""
+# Auto-generated CVE metadata, DO NOT EDIT BY HAND.
+# Generated at {datetime.datetime.now(datetime.timezone.utc)} for kernel version {version}
+
 python check_kernel_cve_status_version() {{
     this_version = "{version}"
     kernel_version = d.getVar("LINUX_VERSION")
@@ -131,26 +150,80 @@ do_cve_check[prefuncs] += "check_kernel_cve_status_version"
             continue
         first_affected, fixed, backport_ver = get_fixed_versions(cve_info, base_version)
         if not fixed:
-            print(f"# {cve} has no known resolution")
+            cve_status[cve] = {
+                "active": True,
+                "message": "no known resolution"
+            }
+            if not args.output_json_file:
+                print(f"# {cve} has no known resolution")
+            elif args.output_inc_file:
+                inc_lines.append(f'# {cve} has no known resolution')
         elif first_affected and version < first_affected:
-            print(f'CVE_STATUS[{cve}] = "fixed-version: only affects {first_affected} onwards"')
+            cve_status[cve] = {
+                "active": False,
+                "message": f"fixed-version: only affects {first_affected} onwards"
+            }
+            if not args.output_json_file:
+                print(f'CVE_STATUS[{cve}] = "fixed-version: only affects {first_affected} onwards"')
+            elif args.output_inc_file:
+                inc_lines.append(f'CVE_STATUS[{cve}] = "fixed-version: only affects {first_affected} onwards"')
         elif fixed <= version:
-            print(
-                f'CVE_STATUS[{cve}] = "fixed-version: Fixed from version {fixed}"'
-            )
+            cve_status[cve] = {
+                "active": False,
+                "message": f"fixed-version: Fixed from version {fixed}"
+            }
+            if not args.output_json_file:
+                print(f'CVE_STATUS[{cve}] = "fixed-version: Fixed from version {fixed}"')
+            elif args.output_inc_file:
+                inc_lines.append(f'CVE_STATUS[{cve}] = "fixed-version: Fixed from version {fixed}"')
         else:
             if backport_ver:
                 if backport_ver <= version:
-                    print(
-                        f'CVE_STATUS[{cve}] = "cpe-stable-backport: Backported in {backport_ver}"'
-                    )
+                    cve_status[cve] = {
+                        "active": False,
+                        "message": f"cpe-stable-backport: Backported in {backport_ver}"
+                    }
+                    if not args.output_json_file:
+                        print(f'CVE_STATUS[{cve}] = "cpe-stable-backport: Backported in {backport_ver}"')
+                    elif args.output_inc_file:
+                        inc_lines.append(f'CVE_STATUS[{cve}] = "cpe-stable-backport: Backported in {backport_ver}"')
                 else:
-                    print(f"# {cve} may need backporting (fixed from {backport_ver})")
+                    cve_status[cve] = {
+                        "active": True,
+                        "message": f"May need backporting (fixed from {backport_ver})"
+                    }
+                    if not args.output_json_file:
+                        print(f"# {cve} may need backporting (fixed from {backport_ver})")
+                    elif args.output_inc_file:
+                        inc_lines.append(f'# {cve} may need backporting (fixed from {backport_ver})')
             else:
-                print(f"# {cve} needs backporting (fixed from {fixed})")
-
-        print()
-
+                cve_status[cve] = {
+                    "active": True,
+                    "message": f"#Needs backporting (fixed from {fixed})"
+                }
+                if not args.output_json_file:
+                    print(f"# {cve} needs backporting (fixed from {fixed})")
+                elif args.output_inc_file:
+                    inc_lines.append(f'# {cve} needs backporting (fixed from {fixed})')
+
+        if print_to_stdout:
+            print()
+        elif args.output_inc_file:
+            inc_lines.append("")
+
+    # Emit structured output if --ret-struct was requested
+    if args.output_json_file:
+        args.output_json_file.write_text(
+        json.dumps(
+                {
+                    "cve_status": cve_status,
+                },
+                indent=2
+            ),
+            encoding="utf-8"
+        )
+    if args.output_inc_file:
+        args.output_inc_file.write_text("\n".join(inc_lines), encoding="utf-8")
 
 if __name__ == "__main__":
     main()


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

* [PATCH v6 2/4] cvelistv5: add a new recipe
  2026-01-29 21:10 ` [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 1/4] generate-cve-exclusions: Add output format option ValentinBoudevin
@ 2026-01-29 21:10   ` ValentinBoudevin
  2026-02-01 11:56     ` [OE-core] " Mathieu Dubois-Briand
  2026-02-01 15:12     ` Richard Purdie
  2026-01-29 21:10   ` [PATCH v6 3/4] kernel-generate-cve-exclusions: Add a .bbclass ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 4/4] generate-cve-exclusions: Move python script ValentinBoudevin
  3 siblings, 2 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-29 21:10 UTC (permalink / raw)
  To: openembedded-core; +Cc: daniel.turull, jerome.oufella, ValentinBoudevin

This recipe is in charge of cloning and setting the cvelistv5
repository: https://github.com/CVEProject/cvelistV5

The variable CVELISTV5_USE_AUTOREV can be used to use AUTOREV to use the
latest available commit on the remote repository and stay
up-to-date with the latest CVE information available.

AUTOREV would make the build non-deterministic, turned off by default.

Signed-off-by: ValentinBoudevin <valentin.boudevin@gmail.com>
---
 .../cvelistv5-native/cvelistv5-native_git.bb  | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb

diff --git a/meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb b/meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb
new file mode 100644
index 0000000000..f25dda9f3d
--- /dev/null
+++ b/meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb
@@ -0,0 +1,24 @@
+SUMMARY = "CVE List V5"
+DESCRIPTION = "Official CVE List. It is a catalog of all CVE Records identified by, or reported to, the CVE Program. \
+The cvelistV5 repository hosts downloadable files of CVE Records in the CVE Record Format."
+HOMEPAGE = "https://github.com/CVEProject/cvelistV5"
+LICENSE = "cve-tou"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/cve-tou;md5=4f7e96b3094e80e66b53359a8342c7f8"
+
+inherit native allarch
+
+SRC_URI = "git://github.com/CVEProject/cvelistV5.git;branch=main;protocol=https"
+CVELISTV5_USE_AUTOREV ?= "0"
+CVELISTV5_DEFAULT_SRCREV ?= "644ce1758db1773336ebebb6a0da90e132da0eb7"
+
+python __anonymous () {
+    if d.getVar("CVELISTV5_USE_AUTOREV") == "1":
+        d.setVar("SRCREV", d.getVar("AUTOREV"))
+    else:
+        d.setVar("SRCREV", d.getVar("CVELISTV5_DEFAULT_SRCREV"))
+}
+
+do_install(){
+	install -d ${D}${datadir}/cvelistv5-native
+	cp -r ${UNPACKDIR}/cvelistv5-git/* ${D}${datadir}/cvelistv5-native/
+}


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

* [PATCH v6 3/4] kernel-generate-cve-exclusions: Add a .bbclass
  2026-01-29 21:10 ` [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 1/4] generate-cve-exclusions: Add output format option ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 2/4] cvelistv5: add a new recipe ValentinBoudevin
@ 2026-01-29 21:10   ` ValentinBoudevin
  2026-01-29 21:10   ` [PATCH v6 4/4] generate-cve-exclusions: Move python script ValentinBoudevin
  3 siblings, 0 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-29 21:10 UTC (permalink / raw)
  To: openembedded-core; +Cc: daniel.turull, jerome.oufella, ValentinBoudevin

Add a new class named kernel-generate-cve-exclusions.bbclass to
generate-cve-exclusions to use this script at every run.

Two steps for testing:

1) inherit this class in the kernel recipe with "inherit
   kernel-generate-cve-exclusions.bbclass"
2) Use the following command to generate cve exclusions .json, and .inc
   file : "bitbake linux-yocto -c "do_generate_cve_exclusions"

This class contains several methods:

*do_generate_cve_exclusions: Use the script generate-cve-exclusions.py.
It uses the new "--output-json-file" argument to generate a JSON file as
an output stored in ${GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON}, and a .inc
file in ${GENERATE_CVE_EXCLUSIONS_OUTPUT_INC}

*do_cve_check:prepend: Parse the previously generated JSON file to set
the variable CVE_STATUS corretly

The class also provides some variables:

*GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON: path of the output JSON file used
to set CVE_STATUS
*GENERATE_CVE_EXCLUSIONS_OUTPUT_INC: cve exclusions .inc file output
path. Not used directly by this class (needs to be inherit manually).

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../kernel-generate-cve-exclusions.bbclass    | 46 +++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 meta/classes/kernel-generate-cve-exclusions.bbclass

diff --git a/meta/classes/kernel-generate-cve-exclusions.bbclass b/meta/classes/kernel-generate-cve-exclusions.bbclass
new file mode 100644
index 0000000000..8efa32f6a1
--- /dev/null
+++ b/meta/classes/kernel-generate-cve-exclusions.bbclass
@@ -0,0 +1,46 @@
+# Generate CVE exclusions for the kernel build (set to "1" to enable)
+GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON = "${WORKDIR}/temp/cve-exclusion_${LINUX_VERSION}.json"
+GENERATE_CVE_EXCLUSIONS_OUTPUT_INC  = "${WORKDIR}/temp//cve-exclusion_${LINUX_VERSION}.inc"
+
+do_generate_cve_exclusions() {
+    # Check for required files and directories
+    generate_cve_exclusions_script=${COREBASE}/scripts/contrib/generate-cve-exclusions.py
+    if [ ! -f "${generate_cve_exclusions_script}" ]; then
+        bbwarn "generate-cve-exclusions.py not found in ${generate_cve_exclusions_script}."
+        return 0
+    fi
+    if [ ! -d "${STAGING_DATADIR_NATIVE}/cvelistv5-native" ]; then
+        bbwarn "CVE exclusions source directory not found in ${STAGING_DATADIR_NATIVE}/cvelistv5-native."
+        return 0
+    fi
+    # Generate the CVE exclusions JSON & INC file
+    python3 "${generate_cve_exclusions_script}" \
+        "${STAGING_DATADIR_NATIVE}/cvelistv5-native" \
+        ${LINUX_VERSION} \
+        --output-json-file "${GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON}" \
+        --output-inc-file "${GENERATE_CVE_EXCLUSIONS_OUTPUT_INC}"
+    bbplain "CVE exclusions generated for kernel version ${LINUX_VERSION} at ${GENERATE_CVE_EXCLUSIONS_OUTPUT_INC} and ${GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON}."
+}
+do_generate_cve_exclusions[depends] += "cvelistv5-native:do_populate_sysroot"
+do_generate_cve_exclusions[nostamp] = "1"
+do_generate_cve_exclusions[doc] = "Generate CVE exclusions for the kernel build. (e.g., cve-exclusion_6.12.json)"
+addtask generate_cve_exclusions after do_prepare_recipe_sysroot before do_cve_check
+
+python do_cve_check:prepend() {
+    import os
+    import json
+    workdir = d.getVar("${STAGING_DATADIR_NATIVE}/cvelistv5-native")
+    kernel_version = d.getVar("LINUX_VERSION")
+    json_input_file = d.getVar("GENERATE_CVE_EXCLUSIONS_OUTPUT_JSON")
+    if os.path.exists(json_input_file):
+        with open(json_input_file, 'r', encoding='utf-8') as f:
+            cve_data = json.load(f)
+        cve_status_dict = cve_data.get("cve_status", {})
+        count = 0
+        for cve_id, info in cve_status_dict.items():
+            if info.get("active", True):
+                continue
+            d.setVarFlag("CVE_STATUS", cve_id, info.get("message", ""))
+            count += 1
+        bb.note("Loaded %d CVE_STATUS entries from JSON output for kernel %s" % (count, kernel_version))
+}


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

* [PATCH v6 4/4] generate-cve-exclusions: Move python script
  2026-01-29 21:10 ` [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
                     ` (2 preceding siblings ...)
  2026-01-29 21:10   ` [PATCH v6 3/4] kernel-generate-cve-exclusions: Add a .bbclass ValentinBoudevin
@ 2026-01-29 21:10   ` ValentinBoudevin
  3 siblings, 0 replies; 21+ messages in thread
From: ValentinBoudevin @ 2026-01-29 21:10 UTC (permalink / raw)
  To: openembedded-core; +Cc: daniel.turull, jerome.oufella, ValentinBoudevin

The script should be located with other scripts in scripts/contrib
instead of staying in meta/classes/.

Update the new .bbclass to match this modification

Signed-off-by: Valentin Boudevin <valentin.boudevin@gmail.com>
---
 .../linux => scripts/contrib}/generate-cve-exclusions.py          | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename {meta/recipes-kernel/linux => scripts/contrib}/generate-cve-exclusions.py (100%)

diff --git a/meta/recipes-kernel/linux/generate-cve-exclusions.py b/scripts/contrib/generate-cve-exclusions.py
similarity index 100%
rename from meta/recipes-kernel/linux/generate-cve-exclusions.py
rename to scripts/contrib/generate-cve-exclusions.py


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

* Re: [OE-core] [PATCH v6 2/4] cvelistv5: add a new recipe
  2026-01-29 21:10   ` [PATCH v6 2/4] cvelistv5: add a new recipe ValentinBoudevin
@ 2026-02-01 11:56     ` Mathieu Dubois-Briand
  2026-02-01 15:12     ` Richard Purdie
  1 sibling, 0 replies; 21+ messages in thread
From: Mathieu Dubois-Briand @ 2026-02-01 11:56 UTC (permalink / raw)
  To: valentin.boudevin, openembedded-core; +Cc: daniel.turull, jerome.oufella

On Thu Jan 29, 2026 at 10:10 PM CET, vboudevin via lists.openembedded.org wrote:
> This recipe is in charge of cloning and setting the cvelistv5
> repository: https://github.com/CVEProject/cvelistV5
>
> The variable CVELISTV5_USE_AUTOREV can be used to use AUTOREV to use the
> latest available commit on the remote repository and stay
> up-to-date with the latest CVE information available.
>
> AUTOREV would make the build non-deterministic, turned off by default.
>
> Signed-off-by: ValentinBoudevin <valentin.boudevin@gmail.com>
> ---

Hi Valentin,

As for the other series, you have to add a maintainer entry for the new
recipe.

Thanks,
Mathieu

-- 
Mathieu Dubois-Briand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



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

* Re: [OE-core] [PATCH v6 2/4] cvelistv5: add a new recipe
  2026-01-29 21:10   ` [PATCH v6 2/4] cvelistv5: add a new recipe ValentinBoudevin
  2026-02-01 11:56     ` [OE-core] " Mathieu Dubois-Briand
@ 2026-02-01 15:12     ` Richard Purdie
  2026-02-02 13:48       ` vboudevin
  1 sibling, 1 reply; 21+ messages in thread
From: Richard Purdie @ 2026-02-01 15:12 UTC (permalink / raw)
  To: valentin.boudevin, openembedded-core; +Cc: daniel.turull, jerome.oufella

On Thu, 2026-01-29 at 16:10 -0500, vboudevin via lists.openembedded.org wrote:
> This recipe is in charge of cloning and setting the cvelistv5
> repository: https://github.com/CVEProject/cvelistV5
> 
> The variable CVELISTV5_USE_AUTOREV can be used to use AUTOREV to use the
> latest available commit on the remote repository and stay
> up-to-date with the latest CVE information available.
> 
> AUTOREV would make the build non-deterministic, turned off by default.
> 
> Signed-off-by: ValentinBoudevin <valentin.boudevin@gmail.com>
> ---
>  .../cvelistv5-native/cvelistv5-native_git.bb  | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb
> 
> diff --git a/meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb b/meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb
> new file mode 100644
> index 0000000000..f25dda9f3d
> --- /dev/null
> +++ b/meta/recipes-kernel/cvelistv5-native/cvelistv5-native_git.bb
> @@ -0,0 +1,24 @@
> +SUMMARY = "CVE List V5"
> +DESCRIPTION = "Official CVE List. It is a catalog of all CVE Records identified by, or reported to, the CVE Program. \
> +The cvelistV5 repository hosts downloadable files of CVE Records in the CVE Record Format."
> +HOMEPAGE = "https://github.com/CVEProject/cvelistV5"
> +LICENSE = "cve-tou"
> +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/cve-tou;md5=4f7e96b3094e80e66b53359a8342c7f8"
> +
> +inherit native allarch
> +
> +SRC_URI = "git://github.com/CVEProject/cvelistV5.git;branch=main;protocol=https"
> +CVELISTV5_USE_AUTOREV ?= "0"
> +CVELISTV5_DEFAULT_SRCREV ?= "644ce1758db1773336ebebb6a0da90e132da0eb7"
> +
> +python __anonymous () {
> +    if d.getVar("CVELISTV5_USE_AUTOREV") == "1":
> +        d.setVar("SRCREV", d.getVar("AUTOREV"))
> +    else:
> +        d.setVar("SRCREV", d.getVar("CVELISTV5_DEFAULT_SRCREV"))
> +}
> +
> +do_install(){
> +	install -d ${D}${datadir}/cvelistv5-native
> +	cp -r ${UNPACKDIR}/cvelistv5-git/* ${D}${datadir}/cvelistv5-native/
> +}

Why add a CVELISTV5_DEFAULT_SRCREV variable when this is a standard usage of autorev?

SRCREV = "644ce1758db1773336ebebb6a0da90e132da0eb7"

and then users can set:

SRCREV:pn-cvelistv5-native = "${AUTROREV}"

if they want it, just the same as any other recipe?

Cheers,

Richard



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

* Re: [PATCH v6 2/4] cvelistv5: add a new recipe
  2026-02-01 15:12     ` Richard Purdie
@ 2026-02-02 13:48       ` vboudevin
  2026-02-02 14:04         ` [OE-core] " Marta Rybczynska
  0 siblings, 1 reply; 21+ messages in thread
From: vboudevin @ 2026-02-02 13:48 UTC (permalink / raw)
  To: openembedded-core

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

I wanted to indicate that the recipe is not meant to be used with a fixed commit with a deterministic approach.

Having ${AUTOREV} by default can lead to many offline issues.

I guess the correct implementation would be to specify, in the documentation, the need for "SRCREV:pn-cvelistv5-native = "${AUTOREV}"" to stay up-to-date with CVE data, and also add this information in a comment inside the recipe.

Thank you for your feedback

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

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

* Re: [OE-core] [PATCH v6 2/4] cvelistv5: add a new recipe
  2026-02-02 13:48       ` vboudevin
@ 2026-02-02 14:04         ` Marta Rybczynska
  2026-02-02 19:54           ` vboudevin
  0 siblings, 1 reply; 21+ messages in thread
From: Marta Rybczynska @ 2026-02-02 14:04 UTC (permalink / raw)
  To: valentin.boudevin; +Cc: OE-core

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

Hello,

Cve-check already has variables disabling the database download. Maybe a
rework of the variable set can be an option ti make sure that either both
download, or both dont.

It requires a bit of design, however.

Kind regards
Marta

On Mon, 2 Feb 2026, 14:48 vboudevin via lists.openembedded.org,
<valentin.boudevin=gmail.com@lists.openembedded.org> wrote:

> I wanted to indicate that the recipe is not meant to be used with a fixed
> commit with a deterministic approach.
>
> Having ${AUTOREV} by default can lead to many offline issues.
>
> I guess the correct implementation would be to specify, in the
> documentation, the need for "SRCREV:pn-cvelistv5-native = "${AUTOREV}"" to
> stay up-to-date with CVE data, and also add this information in a comment
> inside the recipe.
>
> Thank you for your feedback
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#230352):
> https://lists.openembedded.org/g/openembedded-core/message/230352
> Mute This Topic: https://lists.openembedded.org/mt/117534181/5827677
> Group Owner: openembedded-core+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [
> rybczynska@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
>

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

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

* Re: [PATCH v6 2/4] cvelistv5: add a new recipe
  2026-02-02 14:04         ` [OE-core] " Marta Rybczynska
@ 2026-02-02 19:54           ` vboudevin
  0 siblings, 0 replies; 21+ messages in thread
From: vboudevin @ 2026-02-02 19:54 UTC (permalink / raw)
  To: openembedded-core

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

Hello Martha,

Thanks for the feedback.

As I understand, you are referring to CVE_DB_UPDATE_INTERVAL, which can be set to a negative value to disable the download.

I have already tried using a custom "do_fetch" task with a git fetch/pull attempt, as well as with a fixed commit reference in failing scenarios.
But, it seems that I can't avoid a parsing issue if the SRCREV is set to ${AUTOREV} with the build machine not connected to any network (due to a failed attempt to resolve the latest commit hash).

A new .bbclass seems appropriate (e.g., non_deterministic_native.bbclass) to handle natives recipes that require an up-to-date git database.
Adding a non-deterministic class to fetch the latest available commit seems a necessary tool for CVE, as you always want to look at the latest available information (e.g., I have a PR also open for improve_kernel_cve, which has the same issue).

This class could be used to redefine fetch and unpack mechanisms provided by the "base" class, as you did with cve-update-nvd2-native.
It would take a default commit as a reference (e.g., "644ce1758db1773336ebebb6a0da90e132da0eb7"), which won't break the build without any network. In addition, the new do_fetch task would try at the same time to pull the latest available commit if any network is available.

But I don't think I want to handle this mechanism in my current PR. It may be preferable to keep it in a future dedicated one. I would prefer to have my boilerplate merge first with a fixed SRCREV.

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

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

end of thread, other threads:[~2026-02-02 19:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <188AFCD98EA3E578.3200434@lists.openembedded.org>
2026-01-16 19:05 ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support ValentinBoudevin
2026-01-16 19:05   ` [PATCH v5 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
2026-01-19 10:44     ` Daniel Turull
2026-01-16 19:05   ` [PATCH v5 1/4] generate-cve-exclusions: Add --output-json option ValentinBoudevin
2026-01-16 19:05   ` [PATCH v5 2/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
2026-01-17 13:36     ` [OE-core] " Peter Kjellerstedt
2026-01-19 10:40       ` Daniel Turull
2026-01-16 19:05   ` [PATCH v5 3/4] generate-cve-exclusions: Move python script ValentinBoudevin
2026-01-16 19:05   ` [PATCH v5 4/4] linux: Add inherit on generate-cve-exclusions ValentinBoudevin
2026-01-17 13:38     ` [OE-core] " Peter Kjellerstedt
2026-01-19  9:35   ` [PATCH 1/1] improve_kerne_cve_report: Add a bbclass support Daniel Turull
2026-01-29 21:10 ` [PATCH v6 0/4] generate-cve-exclusions: Add a .bbclass ValentinBoudevin
2026-01-29 21:10   ` [PATCH v6 1/4] generate-cve-exclusions: Add output format option ValentinBoudevin
2026-01-29 21:10   ` [PATCH v6 2/4] cvelistv5: add a new recipe ValentinBoudevin
2026-02-01 11:56     ` [OE-core] " Mathieu Dubois-Briand
2026-02-01 15:12     ` Richard Purdie
2026-02-02 13:48       ` vboudevin
2026-02-02 14:04         ` [OE-core] " Marta Rybczynska
2026-02-02 19:54           ` vboudevin
2026-01-29 21:10   ` [PATCH v6 3/4] kernel-generate-cve-exclusions: Add a .bbclass ValentinBoudevin
2026-01-29 21:10   ` [PATCH v6 4/4] generate-cve-exclusions: Move python script ValentinBoudevin

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.