diff options
| author | Ross Burton <ross.burton@arm.com> | 2023-08-25 17:43:40 +0100 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2023-08-30 04:52:35 -1000 |
| commit | 4a930182bff66e798c9df85845aaf6e53d0c3e35 (patch) | |
| tree | 5d0bb8e4701e0991f5d4859061ec05465226c39b | |
| parent | ebab982e97afc992a6406c976a082337baa335da (diff) | |
| download | poky-4a930182bff66e798c9df85845aaf6e53d0c3e35.tar.gz | |
linux-yocto: add script to generate kernel CVE_CHECK_IGNORE entries
Instead of manually looking up new CVEs and determining what point
releases the fixes are incorporated into, add a script to generate the
CVE_CHECK_IGNORE data automatically.
First, note that this is very much an interim solution until the
cve-check class fetches data from www.linuxkernelcves.com directly.
The script should be passed the path to a local clone of the
linuxkernelcves repository[1] and the kernel version number. It will
then write to standard output the CVE_STATUS entries for every known
kernel CVE.
The script should be periodically reran as CVEs are backported and
kernels upgraded frequently.
[1] https://github.com/nluedtke/linux_kernel_cves
Note: for the backport this is not a cherry-pick of the commit in master
as the variable names are different. This incorporates the following
commits:
linux/generate-cve-exclusions: add version check warning
linux/generate-cve-exclusions.py: fix comparison
linux-yocto: add script to generate kernel CVE_STATUS entries
(From OE-Core rev: f9bfaee1c05a61457ada7850d707a847f327e605)
Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
| -rwxr-xr-x | meta/recipes-kernel/linux/generate-cve-exclusions.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/generate-cve-exclusions.py b/meta/recipes-kernel/linux/generate-cve-exclusions.py new file mode 100755 index 0000000000..b9b87f245d --- /dev/null +++ b/meta/recipes-kernel/linux/generate-cve-exclusions.py | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | #! /usr/bin/env python3 | ||
| 2 | |||
| 3 | # Generate granular CVE status metadata for a specific version of the kernel | ||
| 4 | # using data from linuxkernelcves.com. | ||
| 5 | # | ||
| 6 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 7 | |||
| 8 | import argparse | ||
| 9 | import datetime | ||
| 10 | import json | ||
| 11 | import pathlib | ||
| 12 | import re | ||
| 13 | |||
| 14 | from packaging.version import Version | ||
| 15 | |||
| 16 | |||
| 17 | def parse_version(s): | ||
| 18 | """ | ||
| 19 | Parse the version string and either return a packaging.version.Version, or | ||
| 20 | None if the string was unset or "unk". | ||
| 21 | """ | ||
| 22 | if s and s != "unk": | ||
| 23 | # packaging.version.Version doesn't approve of versions like v5.12-rc1-dontuse | ||
| 24 | s = s.replace("-dontuse", "") | ||
| 25 | return Version(s) | ||
| 26 | return None | ||
| 27 | |||
| 28 | |||
| 29 | def main(argp=None): | ||
| 30 | parser = argparse.ArgumentParser() | ||
| 31 | parser.add_argument("datadir", type=pathlib.Path, help="Path to a clone of https://github.com/nluedtke/linux_kernel_cves") | ||
| 32 | parser.add_argument("version", type=Version, help="Kernel version number to generate data for, such as 6.1.38") | ||
| 33 | |||
| 34 | args = parser.parse_args(argp) | ||
| 35 | datadir = args.datadir | ||
| 36 | version = args.version | ||
| 37 | base_version = f"{version.major}.{version.minor}" | ||
| 38 | |||
| 39 | with open(datadir / "data" / "kernel_cves.json", "r") as f: | ||
| 40 | cve_data = json.load(f) | ||
| 41 | |||
| 42 | with open(datadir / "data" / "stream_fixes.json", "r") as f: | ||
| 43 | stream_data = json.load(f) | ||
| 44 | |||
| 45 | print(f""" | ||
| 46 | # Auto-generated CVE metadata, DO NOT EDIT BY HAND. | ||
| 47 | # Generated at {datetime.datetime.now()} for version {version} | ||
| 48 | |||
| 49 | python check_kernel_cve_status_version() {{ | ||
| 50 | this_version = "{version}" | ||
| 51 | kernel_version = d.getVar("LINUX_VERSION") | ||
| 52 | if kernel_version != this_version: | ||
| 53 | bb.warn("Kernel CVE status needs updating: generated for %s but kernel is %s" % (this_version, kernel_version)) | ||
| 54 | }} | ||
| 55 | do_cve_check[prefuncs] += "check_kernel_cve_status_version" | ||
| 56 | """) | ||
| 57 | |||
| 58 | for cve, data in cve_data.items(): | ||
| 59 | if "affected_versions" not in data: | ||
| 60 | print(f"# Skipping {cve}, no affected_versions") | ||
| 61 | print() | ||
| 62 | continue | ||
| 63 | |||
| 64 | affected = data["affected_versions"] | ||
| 65 | first_affected, last_affected = re.search(r"(.+) to (.+)", affected).groups() | ||
| 66 | first_affected = parse_version(first_affected) | ||
| 67 | last_affected = parse_version(last_affected) | ||
| 68 | |||
| 69 | handled = False | ||
| 70 | if not last_affected: | ||
| 71 | print(f"# {cve} has no known resolution") | ||
| 72 | elif first_affected and version < first_affected: | ||
| 73 | print(f"# fixed-version: only affects {first_affected} onwards") | ||
| 74 | handled = True | ||
| 75 | elif last_affected < version: | ||
| 76 | print(f"# fixed-version: Fixed after version {last_affected}") | ||
| 77 | handled = True | ||
| 78 | else: | ||
| 79 | if cve in stream_data: | ||
| 80 | backport_data = stream_data[cve] | ||
| 81 | if base_version in backport_data: | ||
| 82 | backport_ver = Version(backport_data[base_version]["fixed_version"]) | ||
| 83 | if backport_ver <= version: | ||
| 84 | print(f"# cpe-stable-backport: Backported in {backport_ver}") | ||
| 85 | handled = True | ||
| 86 | else: | ||
| 87 | # TODO print a note that the kernel needs bumping | ||
| 88 | print(f"# {cve} needs backporting (fixed from {backport_ver})") | ||
| 89 | else: | ||
| 90 | print(f"# {cve} needs backporting (fixed from {last_affected})") | ||
| 91 | else: | ||
| 92 | print(f"# {cve} needs backporting (fixed from {last_affected})") | ||
| 93 | |||
| 94 | if handled: | ||
| 95 | print(f'CVE_CHECK_IGNORE += "{cve}"') | ||
| 96 | |||
| 97 | print() | ||
| 98 | |||
| 99 | |||
| 100 | if __name__ == "__main__": | ||
| 101 | main() | ||
