At Open Source Summit and Embedded Linux Conference Europe in Prague on Wednesday, Christoph Steiger and Negar Masoudifar of Siemens gave the talk Triaging CVEs for the Linux Kernel (slides). Their starting point will be familiar to anyone shipping Linux in a product. The kernel now publishes around 150 CVEs a week, and under the EU Cyber Resilience Act, a blanket statement about kernel security is no longer enough.
Right after them, in the same room, Jan Pfiffner of Grossenbacher Systeme (GESYS) gave An Approach To Managing CVEs With Vendor Kernels (slides). Two talks from two companies, each with its own tool, gave one answer, and it is the one KernelScan is built on: decide each kernel CVE by what your build actually contains. In Pfiffner's words: “judge the build, not the version number.”
With CIP and the Yocto Project working the same way, configuration-based kernel CVE triage is no longer a vendor idea. It is accepted practice.
One method, independently arrived at
The Siemens talk presented kernel-cve-triage, a tool developed under the umbrella of the Civil Infrastructure Platform (CIP), the Linux Foundation project behind the super-long-term-support kernels used in industry. It takes a CVE, the kernel source and version, and the .config, and decides in four steps:
- Is this kernel version in the affected range at all?
- Which source files does the CVE's fix commit touch?
- Which
CONFIG_*options build those files? - Are those options enabled in this
.config?
That is, step for step, how KernelScan decides a CVE. We derive the CONFIG_* conditions from each fix commit and evaluate them against your configuration (see how the config mapper works).
It also compared the tool with the Yocto Project’s cve-check, which asks the same question one level lower: are the affected files in the kernel build? Run on the same kernel version and the same configuration, the two tools largely agreed on which CVEs are patched and which are not. They differed mostly on the CVEs ruled not applicable. Two independent implementations reaching the same verdicts is about the strongest evidence a method can get.
Vendor kernels: the same principle, line by line
Pfiffner applied the principle to vendor kernels, which lag mainline and carry patches of their own. His Yocto layer, meta-kernelcve-test, looks for each CVE's fix on the matching stable branch and tries it against the source actually built. It then checks, for every line the fix touches, whether that line is compiled with the product's .config. On an NVIDIA Jetson Orin Nano vendor kernel (5.15.185), 145 CVEs came out as not compiled. That is evidence for a “not affected” status, not an opinion.
One suggestion from the Siemens talk went further: the kernel’s CVE records themselves should name the affected Kconfig options. When practitioners working on CIP propose putting configuration data into the CVE record itself, it is clear where the field is heading.
What this means for your compliance file. A not_affected verdict because the vulnerable code is not compiled into your kernel is not a shortcut or a vendor trick. It is the same reasoning CIP and the Yocto Project apply. Pfiffner put the CRA side plainly: with a proper risk analysis there is no need to patch every CVE, but “every ‘not affected’ needs a reason you can show.” KernelScan’s VEX states that reason with each verdict. Our CRA Article 14 post covers what that means for reporting.
Beyond the configuration
The Siemens talk was also candid about the limit. In the speakers’ words, current tools can realistically filter around 80 % of CVEs, and further improvement has to come from different approaches. The first one they named was a generic description of threat models and attack vectors. Pfiffner’s talk made the same point from the other side: compiled is not the same as reachable. That is why his layer also sets a CVSS threshold per attack vector.
That is KernelScan’s second layer. On Pro, the CVEs that survive the configuration analysis are checked against how the product is deployed: its exposed interfaces, its user model, the hardening it ships with. The question there is whether the attacker the CVE needs exists on your device. The Siemens talk’s other advice holds too: share the work by building on LTS and SLTS kernels and joining communities like CIP. That brings us to our news.
New in KernelScan: CIP kernels, analysed with CIP’s own fix data
The CIP project maintains Super Long-Term Support (SLTS) kernels for industrial and civil-infrastructure systems: rail, power, building automation, industrial control. The support horizon is around ten years. CIP kernels exist for the 4.4, 4.19, 5.10, 6.1 and 6.12 series, and for all but 6.12 also as a PREEMPT_RT variant.
A CIP kernel starts from a stable kernel, but it does not stop there. For 4.4 and 4.19, upstream stable support has ended, and CIP keeps backporting security fixes for years.
The version number does not show any of that. CIP's 4.19 has stayed at 4.19.325 since stable ended: 4.19.325-cip124 and 4.19.325-cip136 share one base version. Only the -cipN counter tells which fixes are in.
A scanner that sees 4.19.325 therefore sees a kernel abandoned at the end of stable support. It flags every CVE fixed upstream since then, including the ones CIP has already shipped a fix for. On a CIP kernel, configuration analysis alone leaves hundreds of those findings standing.
What that costs, measured
We took a real CIP configuration and analysed it twice: once as its stable base version and once as the CIP release it actually is. The configuration is CIP's own cip_merged_defconfig, built on the real linux-cip tree.
| Configuration | Analysed as | Affected | In triage | Known-exploited (CISA KEV) |
|---|---|---|---|---|
4.19 x86 cip_merged_defconfig | stable 4.19.325 | 1,950 | 696 | 5 |
4.19.325-cip136 | 1,158 (−41 %) | 221 (−68 %) | 1 | |
| 4.19 arm64 (Renesas) | stable 4.19.325 | 717 | 695 | 3 |
4.19.325-cip136 | 446 (−38 %) | 221 (−68 %) | 1 |
On the x86 configuration, 792 findings disappear: CVEs that CIP has already fixed in the kernel you ship. Four of the five known-exploited vulnerabilities go with them, and so do two thirds of the triage queue. No CVE got worse under the CIP analysis.
On 6.1 the difference is small by design (831 → 826 affected). There, upstream stable is still maintained and CIP closely follows it. The CIP analysis pays off where stable support has ended, and that is exactly where SLTS kernels spend most of their life.
Where the data comes from
KernelScan does not guess which fixes a CIP kernel carries. Every CIP verdict rests on what the CIP project publishes itself:
- cip-kernel-sec is the CIP kernel team's own security tracker. It holds one record per CVE and lists, for each CIP branch, the commit that fixes it. Today that is 51,728 CIP fix records across 14,091 CVEs.
- The
linux-ciprelease tags list every CIP release ever tagged: 598 releases across nine trees (420 plain, 178 PREEMPT_RT). That way every real CIP kernel can be named, including releases that fixed no CVE.
Both are read every day and applied strictly:
- A fix counts only from the tagged release that contains it.
- A fix applies only to its own series and its own tree, so an RT release never stands in for the plain kernel, or the other way round.
- When a CVE's record is incomplete, KernelScan keeps the last verified state rather than acting on half of it.
- The CIP data adds to the kernel.org and NVD data you already get. It never overwrites that data and never changes the analysis of non-CIP kernels.
The question KernelScan answers for a CIP kernel is the one CIP itself answers: is the fix for this CVE in my CIP release? The answer comes from CIP's tracker, not from version-number arithmetic.
Credit where it is due: this works because the CIP kernel maintainers publish their tracking openly and keep it current. We consume it as is.
How a CIP verdict is decided
For a product running a CIP release, each CVE is decided against CIP's fix for that branch:
- Your release contains CIP's fix: the verdict is
not_affected. If NVD's version range would still flag your kernel, the VEX entry gives the reason, e.g. “fixed in CIP (cip/4.19) at 4.19.325-cip124”, so scanners that read the VEX stay quiet. - Your release is older than CIP's fix: the CVE stays open, as it would on any kernel without the patch.
- CIP has no record of the CVE: the verdict is the one your stable base would get.
Everything else works as for any kernel. The CONFIG_* analysis still removes CVEs whose code is not compiled into your build, and the deployment-context layer still applies on top.
The public CVE pages show CIP's fix rows too, listed after the stable branches, with each commit linked into linux-cip. An example is CVE-2026-98158.
Telling KernelScan your CIP release
A .config cannot tell a CIP kernel from a stable one. On x86 we compared them and found them byte-identical, and the header only names the base version. So KernelScan asks you:
- Find your release by running
uname -ron the device. For4.19.325-cip136-st20-arm64-renesas, the release is4.19.325-cip136; everything after it is local naming. - Config Scan and the product wizard: upload the
.configand set Kernel tree to CIP SLTS. For a4.19.325or4.4.302config this is preselected, because those are the final stable releases CIP builds on. Then pick your CIP release; the list only offers releases on your config's base version. - API and MCP: pass the release as
kernel_version, e.g."4.19.325-cip136".
The full walkthrough, including the RT trees and the limits, is in the CIP section of the docs.
Good to know
KernelScan knows the fixes CIP ships. If your vendor builds on CIP and adds patches of its own, those are not visible to KernelScan; the verdict reflects the CIP release your kernel is based on. Pick the release the device actually runs: selecting a newer one would clear CVEs that are still open on it.