Skip to content

Conversation

@masami256
Copy link
Contributor

@masami256 masami256 commented Dec 22, 2025

This PR contains 2 commits.

  • Create source package information file
  • Implement plugin architecture for CVE check

First patch(Create source package information file) add a new class to make recipe source information.
Commit "Implement plugin architecture for CVE check" implement plugin style CVE check feature.

This cve-check feature is experimental so that current script name is cve_check_ng.py and cve check results are stored in tmp/deploy/cve/--/cve_check_ng directory.

Patch: Create source package information file

Add source-info.bbclass to create a JSON file which contains source package
information. This JSON file contains the following attributes:

  • source_package_name
  • source_from

The source_package_name attribute is automatically set from the ${PN} variable.
The source_from attribute is read from the ${EMLINUX_SOURCE_FROM} variable,
which should be defined in your recipe. For example, if the source code is
not a Debian source package, set it to "non-debian":

EMLINUX_SOURCE_FROM="non-debian"

Another example: if the DISTRO variable is "emlinux-bookworm" and the source code
is fetched from Debian Trixie, define the EMLINUX_SOURCE_FROM variable like this:

EMLINUX_SOURCE_FROM="trixie"

The source package information JSON file looks like the following format:

    "emlinux-customization": {
        "source_package_name": "emlinux-customization",
        "source_from": "non-debian",
    }

This JSON file is stored in the build/tmp/deploy/images// directory.
The file name is all-source-info.json.

Patch: Implement plugin architecture for CVE check

This change adds a plugin feature to the CVE check.
The plugin feature makes adding new CVE data sources easier than the
current implementation.

  • Basic Specification

** Plugin directory and naming rule

Plugins are stored in scripts/lib/python/cve/plugin/ within a layer.
Plugin names should use the following format:

eml_cve_<your plugin name>_plugin.py

e.g. scripts/lib/python/cve/plugin/eml_cve_myplugin_plugin.py

** Import path

The plugin's base class and libraries are in meta-emlinux/scripts/lib/python,
so plugins need to import libraries from this directory.
For example, implementing your plugin must include the following line:

from lib.python.cve.plugin.eml_cve_plugin_base import EmlCvePlugin

** Plugin priority

Each plugin has its own priority number. For the priority number, 1 is the lowest.
This number is used to decide if a CVE is patched or unpatched if plugins
have different CVE check results. For example, if PLUGIN-A (priority 1)
states CVE-1111-1111 is patched but PLUGIN-B (priority 10) states it is
unpatched, we adopt PLUGIN-B's analysis result because PLUGIN-B has a higher
priority than PLUGIN-A.

** Base class

The EmlCvePlugin class is the base class for plugins.
This class contains two methods that plugins should implement:

  • update_database
  • run_check

The update_database function updates the CVE database. The run_check function
executes the CVE check and should return an instance of the
CveCheckResultList class, which stores the CVE analysis results.

** CVE check result

The CVE check result is stored in the CveCheckResult class.
This class stores the following data:

  • CVE ID
  • Source package name
  • Patched/Unpatched status

The CveCheckResultList class stores CveCheckResult instances.
When creating an instance of CveCheckResult, you should add it to the
CveCheckResultList class.

** CVE vendor and product

CVE vendor and product information is stored in the CveProductList class.
To get this information, use the _get_cve_products_from_source_package_name
function in the EmlCvePlugin class.

You can use these data like this:

cve_product =
self._get_cve_products_from_source_package_name(src_pkg_name)

for cve_product in cve_products:
    vendor = cve_product.vendor
    product = cve_product.product

** Installed package information

Installed package information is stored in the PackageInfoList class.
This class is iterable and returns source package names.

for src_pkg_name in self.installed_packages:
    data = self.installed_packages[src_pkg_name]

** Common library

Common functions are implemented in lib.py. One useful function
is the check_affected function, which checks if a given version is affected.
This function uses the LooseVersion class to compare versions.

** Logging

Add the following lines to your code to use the logger class:

import logging
logger = logging.getLogger("emlinux-cve-check")
  • Improvements from current CVE check

** Support multiple types in the product list YAML file

The current CVE check feature supports the following format:

package:
  - vendor
  - product

The new CVE check feature supports dictionary style and lists containing
dictionaries:

packageA:
  - vendor
  - product
packageB:
  -
    vendor: vendor name
    product: product name
  -
    vendor: another vendor name
    product: another product name

In the yaml file, product attribute should exist but vendor attibute is
optional. This specification is based on poky's cve-check.bbclass.

** Add options for debugging

Checking CVEs with cve_check_ng.py takes command-line options similar to
cve_check.py. However, some options have been added for debugging:

  • skip-update: Skips the database update process.
  • target-source-package: Checks only the given source package.
  • dpkg-status-file: Uses a specified .dpkg_status file instead of the
    default file in the ${DEPLOY_DIR_IMAGE} directory.

@masami256 masami256 changed the title New CVE check2 cve-check: Implement plugin stype CVE check feature Dec 22, 2025
@masami256 masami256 marked this pull request as ready for review December 22, 2025 23:22
@masami256 masami256 force-pushed the new-cve-check2 branch 2 times, most recently from 78153e3 to d4551f9 Compare January 8, 2026 02:16
SRC_URI:append:raspberrypi3bplus-64 = " file://raspberrypi3-64_defconfig"
SRC_URI:append:raspberrypi4b-64 = " file://raspberrypi4-64_defconfig"

EMLINUX_SOURCE_FROM="non-debian"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this line into meta-emlinux/recipes-kernel/linux/includes/linux-cip-common.inc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. EMLINUX_SOURCE_FROM variable was moved to linux-cip-common.inc file.

Add source-info.bbclass to create a JSON file which contains source package
information. This JSON file contains the following attributes:

- source_package_name
- source_from

The source_package_name attribute is automatically set from the ${PN} variable.
The source_from attribute is read from the ${EMLINUX_SOURCE_FROM} variable,
which should be defined in your recipe. For example, if the source code is
not a Debian source package, set it to "non-debian":

```
EMLINUX_SOURCE_FROM="non-debian"
```

Another example: if the DISTRO variable is "emlinux-bookworm" and the source code
is fetched from Debian Trixie, define the EMLINUX_SOURCE_FROM variable like this:

```
EMLINUX_SOURCE_FROM="trixie"
```

The source package information JSON file looks like the following format:

```
    "emlinux-customization": {
        "source_package_name": "emlinux-customization",
        "source_from": "non-debian",
    }
```

This JSON file is stored in the build/tmp/deploy/images/<MACHINE>/ directory.
The file name is all-source-info.json.

Signed-off-by: Masami Ichikawa <[email protected]>
@masami256 masami256 force-pushed the new-cve-check2 branch 3 times, most recently from 1ac34da to 1ca060f Compare January 16, 2026 05:53
@masami256 masami256 changed the title cve-check: Implement plugin stype CVE check feature cve-check: Implement plugin style CVE check feature Jan 16, 2026
This change adds a plugin feature to the CVE check.
The plugin feature makes adding new CVE data sources easier than the
current implementation.

* Basic Specification

** Plugin directory and naming rule

Plugins are stored in scripts/lib/python/cve/plugin/ within a layer.
Plugin names should use the following format:

```
eml_cve_<your plugin name>_plugin.py
```

e.g. scripts/lib/python/cve/plugin/eml_cve_myplugin_plugin.py

** Import path

The plugin's base class and libraries are in meta-emlinux/scripts/lib/python,
so plugins need to import libraries from this directory.
For example, implementing your plugin must include the following line:

```
from lib.python.cve.plugin.eml_cve_plugin_base import EmlCvePlugin
```

** Plugin priority

Each plugin has its own priority number. For the priority number, 1 is the lowest.
This number is used to decide if a CVE is patched or unpatched if plugins
have different CVE check results. For example, if PLUGIN-A (priority 1)
states CVE-1111-1111 is patched but PLUGIN-B (priority 10) states it is
unpatched, we adopt PLUGIN-B's analysis result because PLUGIN-B has a higher
priority than PLUGIN-A.

** Base class

The EmlCvePlugin class is the base class for plugins.
This class contains two methods that plugins should implement:
- update_database
- run_check

The update_database function updates the CVE database. The run_check function
executes the CVE check and should return an instance of the
CveCheckResultList class, which stores the CVE analysis results.

** CVE check result

The CVE check result is stored in the CveCheckResult class.
This class stores the following data:
- CVE ID
- Source package name
- Patched/Unpatched status

The CveCheckResultList class stores CveCheckResult instances.
When creating an instance of CveCheckResult, you should add it to the
CveCheckResultList class.

** CVE vendor and product

CVE vendor and product information is stored in the CveProductList class.
To get this information, use the _get_cve_products_from_source_package_name
function in the EmlCvePlugin class.

You can use these data like this:

```
cve_product =
self._get_cve_products_from_source_package_name(src_pkg_name)

for cve_product in cve_products:
    vendor = cve_product.vendor
    product = cve_product.product
```

** Installed package information

Installed package information is stored in the PackageInfoList class.
This class is iterable and returns source package names.

```
for src_pkg_name in self.installed_packages:
    data = self.installed_packages[src_pkg_name]
```

** Common library

Common functions are implemented in lib.py. One useful function
is the check_affected function, which checks if a given version is affected.
This function uses the LooseVersion class to compare versions.

** Logging

Add the following lines to your code to use the logger class:

```
import logging
logger = logging.getLogger("emlinux-cve-check")
```

* Improvements from current CVE check

** Support multiple types in the product list YAML file

The current CVE check feature supports the following format:

```
package:
  - vendor
  - product
```

The new CVE check feature supports dictionary style and lists containing
dictionaries:

```
packageA:
  - vendor
  - product
packageB:
  -
    vendor: vendor name
    product: product name
  -
    vendor: another vendor name
    product: another product name
```

In the yaml file, product attribute should exist but vendor attibute is
optional. This specification is based on poky's cve-check.bbclass.

** Add options for debugging

Checking CVEs with cve_check_ng.py takes command-line options similar to
cve_check.py. However, some options have been added for debugging:

- skip-update: Skips the database update process.
- target-source-package: Checks only the given source package.
- dpkg-status-file: Uses a specified .dpkg_status file instead of the
  default file in the ${DEPLOY_DIR_IMAGE} directory.

Signed-off-by: Masami Ichikawa <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants