Le suivi des vulnérabilités d’un système embarqué est essentiel. Nous avons vu dans l’article précédent comment analyser les fichiers produits par Yocto Project pour extraire la liste des CVE (Common Vulnerabilities and Exposures) présentes lors d’une production d’image. Nous avions observé que des vulnérabilités étaient en nombre limité pour la plupart des packages, mais qu’un nombre astronomique de CVE étaient mentionné pour le kernel Linux.
Nous allons voir à présent comment filtrer les résultats pour n’avoir à traiter qu’un nombre raisonnable de vulnérabilités.
L’actualité est particulièrement riche en ce qui concerne la cybersécurité, notamment pour les systèmes embarqués. Après l’entrée en vigueur des obligations de notifications incluses dans le Cyber Resilience Act début septembre, après la faille de sécurité touchant les groupes frigorifiques début octobre, la semaine passée a été bien remplie à vérifier les versions de PHP et mettre à jour les systèmes concernés. Contrairement à ce que l’on peut imaginer, les vulnérabilités de PHP ne concernent pas uniquement les serveurs, mais aussi des équipements embarqués qui l’emploient pour proposer une IHM sur leur port HTTP/HTTPS.
Il est donc plus que jamais crucial de déterminer dès la production initiale d’un système embarqué les éventuelles vulnérabilités présentes pour les éliminer, et s’assurer régulièrement de l’absence de nouvelles failles exploitables.
Production d’une image
Comme exemple de système dont on souhaite vérifier les éventuelles vulnérabilités, nous allons prendre une image minimale produite avec Yocto Project pour un émulateur Qemu Arm. Je commence par installer Yocto Cooker comme indiqué dans cet article :
$ python3 -m venv cooker-env
$ source cooker-env/bin/activate
$ pip3 install yocto-cooker
[...]
Je clone ensuite le repository de Cooker pour prendre le menu d’exemple qemu-sample-menu-blacksail.json basé sur la dernière branche de Yocto Project, Blacksail, publiée la semaine passée.
$ git clone https://github.com/cpb-/yocto-cooker
[...]
$ cp yocto-cooker/sample-menus/qemu-sample-menu-blacksail.json .
Je l’édite pour ajouter une ligne dans la section local.conf :
"local.conf": [
"MACHINE = 'qemuarm' ",
"DISTRO = 'poky' ",
"IMAGE_FEATURES += 'empty-root-password' ",
"OE_FRAGMENTS += 'core/yocto/sbom-cve-check' "
]
Nous l’avons vu dans l’article précédent, cela permet d’extraire la liste des vulnérabilités connues dans les packages produits.
Lançons la compilation :
$ cooker cook qemu-sample-menu-blacksail.json
[...]
WARNING: core-image-base-1.0-r0 do_sbom_cve_check: alsa-lib-1.2.16.1: Found unpatched CVEs: CVE-2026-90781, CVE-2026-96674, CVE-2026-96675
WARNING: core-image-base-1.0-r0 do_sbom_cve_check: busybox-1.38.0: Found unpatched CVEs: CVE-2026-38752, CVE-2026-38753, CVE-2026-38755
WARNING: core-image-base-1.0-r0 do_sbom_cve_check: expat-2.8.5: Found unpatched CVEs: CVE-2026-102633, CVE-2026-113351, CVE-2026-115506, CVE-2026-77214
[...]
WARNING: core-image-base-1.0-r0 do_sbom_cve_check: linux-yocto-7.2.6+git: Found unpatched CVEs: CVE-1999-0524, CVE-2010-4563, CVE-2019-14899, [...] CVE-2026-99077, CVE-2026-99080, CVE-2026-99084, CVE-2026-99085, CVE-2026-99999
[...]
NOTE: Tasks Summary: Attempted 6164 tasks of which 6142 didn't need to be rerun and all succeeded.
Summary: There were 14 WARNING messages.
Les quatorze warnings indiquent que certains composants contiennent des vulnérabilités connues.
Liste des vulnérabilités présentes : cve-parse
Je clone le repository de Yocto CVE Parse comme nous l’avons vu dans l’article précédent :
$ git clone https://github.com/cpb-/yocto-cve-parser
[...]
Je demande à cve-parse une liste complète, en filtrant les packages effectivement présents :
$ ./yocto-cve-parser/cve-parse builds/build-qemuarm/tmp/deploy/images/qemuarm/core-image-base-qemuarm.rootfs.sbom-cve-check.yocto.json -f builds/build-qemuarm/tmp/deploy/images/qemuarm/core-image-base-qemuarm.rootfs.spdx.json --restricted
COMPONENT VERSION TOTAL PATCHED UNPATCHED IGNORED OTHER
acl 2.4.0 4 4 0 0 0
alsa-lib 1.2.16.1 6 3 3 0 0
avahi 0.9~rc5 26 25 0 1 0
base-files 3.0.14 1 0 0 1 0
bluez5 5.87 43 40 0 3 0
busybox 1.38.0 49 46 3 0 0
dbus 1.16.2 26 26 0 0 0
dosfstools 4.2 2 2 0 0 0
expat 2.8.5 72 68 4 0 0
glib-2.0 2.90.0 35 35 0 0 0
glibc 2.44+git 179 163 10 6 0
initscripts 1.0 2 2 0 0 0
libcap 2.78 5 5 0 0 0
libffi 3.8.0 1 1 0 0 0
libgcc 16.2.0 16 16 0 0 0
libpcre2 10.48 19 18 1 0 0
libtirpc 1.3.8 5 5 0 0 0
libx11 1.8.13 22 18 4 0 0
libxcb 1.17.0 1 1 0 0 0
libxdmcp 1.1.5 1 1 0 0 0
libxml2 2.15.4 120 120 0 0 0
linux-yocto 7.2.6+git 21502 20243 418 841 0
ncurses 6.6 31 31 0 0 0
openssl 4.0.3 322 321 0 1 0
readline 8.3 1 1 0 0 0
rpcbind 1.3.1 4 4 0 0 0
shadow 4.20.2 13 12 0 1 0
tar 1.35 20 17 2 1 0
ttyrun 2.44.0 1 1 0 0 0
util-linux 2.42.4 35 34 1 0 0
xz 5.8.4 9 8 0 1 0
zlib 1.3.2 16 14 2 0 0
TOTAL 22589 21285 448 856 0
Components: 32; unique CVEs: 22586
L’option --restricted de cve-parse a été ajoutée depuis le dernier article. Elle permet de n’afficher que les packages avec un total de vulnérabilités non nul.
Une ligne attire le regard, celle du kernel : linux-yocto avec plus de 20000 enregistrements CVE et plus de 400 classés « Unpatched » !
Lors de sa conférence « Security in the LLM age » aux Kernel Recipes 2026 Greg Kroah Hartman, le mainteneur des branches stable et long-term du noyau, a abordé l’augmentation du nombre de CVE. Avec l’arrivée des LLM, le nombre de CVE enregistrées est passé d’une cinquantaine par semaine il y a un an (ce qui semblait déjà énorme) à 33 par jour à présent.
La plupart d’entre-elles sont bénignes ou inapplicables (je vous conseille de voir son analyse des 79 vulnérabilités médiatisées comme « découvertes par Mythos »), mais cela nécessite quand même une analyse cas-par-cas, ce qui lui impose une charge de travail élevée.

Nous ne sommes pas à la même échelle ici : il n’y a « que » 400 CVE non-patchées, mais c’est quand même trop pour la maintenance régulière d’un système embarqué. Nous allons utiliser un script fourni par Open Embedded pour conserver uniquement les vulnérabilités se trouvant dans des portions de code compilées pour notre image.
Filtrage des vulnérabilités kernel
Tout d’abord nous devons ajouter deux lignes au local.conf et relancer le build (oui, on aurait pu le faire plus tôt, mais je préfère expliquer mes actions progressivement).
"local.conf": [
"MACHINE = 'qemuarm' ",
"DISTRO = 'poky' ",
"IMAGE_FEATURES += 'empty-root-password' ",
"OE_FRAGMENTS += 'core/yocto/sbom-cve-check' ",
"KERNEL_EXTRA_FEATURES:append = ' features/debug/debug-kernel.scc' ",
"SPDX_INCLUDE_COMPILED_SOURCES:pn-linux-yocto = '1' "
]
Après avoir relancé le build avec cooker cook qemu-sample-menu-blacksail.json le fichier builds/build-qemuarm/tmp/deploy/images/qemuarm/core-image-base-qemuarm.rootfs.spdx.json contient entre autres la liste des fichiers sources du noyau qui ont été compilés. En voici un exemple :
{
"type": "software_File",
"spdxId": "http://spdx.org/spdxdocs/linux-yocto-f9f75dbe-e63f-5a48-86d8-e19d0ec693db/9439fb773aa0308ba9f94d1c42b7902cda81ba3dfd21aaa3cb263aa740994f85/sourcefile/14760",
"software_primaryPurpose": "source",
"creationInfo": "_:CreationInfo4",
"name": "linux-yocto-7.2.6+git/arch/arm/kernel/irq.c",
"verifiedUsing": [
{
"type": "Hash",
"algorithm": "sha256",
"hashValue": "99c925c2016f219c9e8320da093959374194fb7cfbdad22f6a6457660b77188d"
},
{
"type": "Hash",
"algorithm": "sha512",
"hashValue": "070cbf06eee488298f5706644b1e0fecdc6a88f2aee5f9c09effbcb10eff9e241415107cfa44c5d643990a8ce233df205c991a6e3d4ad7d604e68d950976eb93"
}
]
},
Nous allons à présent récupérer la base de données des CVE actuelles du kernel. Depuis deux ans et demi, la « Linux Kernel Organization » est devenue autorité d’identification des CVE liées au kernel et la quantité de vulnérabilités enregistrées a sensiblement augmenté.
$ git clone https://git.kernel.org/pub/scm/linux/security/vulns.git
[...]
Nous appelons un script fourni dans le layer openembedded-core qui va filtrer les vulnérabilités en se limitant aux fichiers source effectivement compilés durant notre build. Pour le faire fonctionner j’ai dû ajouter sur ma machine un module Python avec python3 -m pip install zstandard.
Le script va consulter le répertoire de vulnérabilités indiqué par l’option --datadir, utiliser le fichier fourni avec l’option --debug-sources-file pour connaître les fichiers effectivement compilés, lire le rapport donné par --old-cve-report et remplir le fichier mentionné par l’option --new-cve-report.
$ python3 ./layers/openembedded-core/scripts/contrib/improve_kernel_cve_report.py --datadir vulns/ --debug-sources-file builds/build-qemuarm/tmp/pkgdata/qemuarm/debugsources/linux-yocto-debugsources.json.zstd --old-cve-report builds/build-qemuarm/tmp/deploy/images/qemuarm/core-image-base-qemuarm.rootfs.sbom-cve-check.yocto.json --new-cve-report filtered-cve.json
[improve_kernel_cve_report.py:445] Total compiled files 5482
[improve_kernel_cve_report.py:478] Checking kernel 7.2.6+git
[improve_kernel_cve_report.py:93] CVE-2024-0000 doesn't have good metadata
[improve_kernel_cve_report.py:93] CVE-2024-0053 doesn't have good metadata
[improve_kernel_cve_report.py:193] Total CVEs ignored due to not applicable config: 1232
[improve_kernel_cve_report.py:194] Total CVEs not vulnerable due version-not-in-range: 16806
[improve_kernel_cve_report.py:195] Total vulnerable CVEs: 0
[improve_kernel_cve_report.py:197] Total CVEs already backported in 7.2: 0
[improve_kernel_cve_report.py:482] Total kernel cves from kernel CNA: 18360
[improve_kernel_cve_report.py:484] Total kernel before processing cves: 21502
[improve_kernel_cve_report.py:492] Total kernel cves after processing: 21826
Les deux dernières lignes peuvent laisser perplexe : on passe de 21502 à 21826, ce n’est pas un filtrage très efficace ! En réalité le script enrichit le rapport et peut ajouter des entrées, il ne fait pas que supprimer des lignes. Néanmoins le nombre de CVE non patchées est plus raisonnable. J’utilise le fichier filtré pour alimenter cve-parse :
$ ./yocto-cve-parser/cve-parse filtered-cve.json --component linux-yocto -u --stat
COMPONENT VERSION TOTAL PATCHED UNPATCHED IGNORED OTHER
linux-yocto 7.2.6+git 11 0 11 0 0
TOTAL 11 0 11 0 0
Onze vulnérabilités non-patchées, nous avons bien progressé. Voyons les numéros de CVE :
$ ./yocto-cve-parser/cve-parse filtered-cve.json --component linux-yocto -u
COMPONENT VERSION CVE STATUS CVSS SCORE SEVERITY
linux-yocto 7.2.6+git CVE-2023-3640 Unpatched 3.x 7.8 High
linux-yocto 7.2.6+git CVE-2019-14899 Unpatched 3.x 7.4 High
linux-yocto 7.2.6+git CVE-2021-3864 Unpatched 3.x 7.0 High
linux-yocto 7.2.6+git CVE-2023-3397 Unpatched 3.x 7.0 High
linux-yocto 7.2.6+git CVE-2023-6238 Unpatched 3.x 6.7 Medium
linux-yocto 7.2.6+git CVE-2023-6240 Unpatched 3.x 6.5 Medium
linux-yocto 7.2.6+git CVE-2021-3714 Unpatched 3.x 5.9 Medium
linux-yocto 7.2.6+git CVE-2020-10774 Unpatched 3.x 5.5 Medium
linux-yocto 7.2.6+git CVE-2022-4543 Unpatched 3.x 5.5 Medium
linux-yocto 7.2.6+git CVE-2010-4563 Unpatched 2.0 5.0 Medium
linux-yocto 7.2.6+git CVE-1999-0524 Unpatched 3.x 4.0 Medium
Examen des CVE restantes
Nous allons examiner en détail les quelques vulnérabilités les plus critiques (colonne SCORE les plus élevées).
$ ./yocto-cve-parser/cve-parse filtered-cve.json cve CVE-2023-3640 --details
component: linux-yocto
version: 7.2.6+git
layer: core
cve: CVE-2023-3640
status: Unpatched
cvss: 3.x
score: 7.8
severity: High
issue.id: CVE-2023-3640
issue.status: Unpatched
issue.link: https://nvd.nist.gov/vuln/detail/CVE-2023-3640
issue.summary: A possible unauthorized memory access flaw was found in the Linux kernel's cpu_entry_area mapping of X86 CPU data to memory, where a user may guess the location of exception stacks or other important data. Based on the previous CVE-2023-0597, the 'Randomize per-cpu entry area' feature was implemented in /arch/x86/mm/cpu_entry_area.c, which works through the init_cea_offsets() function when KASLR is enabled. However, despite this feature, there is still a risk of per-cpu entry area leaks. This issue could allow a local user to gain access to some important data with memory in an expected location and potentially escalate their privileges on the system.
issue.scorev2: 0.0
issue.scorev3: 7.8
issue.scorev4: 0.0
issue.modified: 2026-07-21T20:05:58.000
issue.vector: LOCAL
issue.vectorString: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
issue.detail: no-version-ranges
issue.description: Check package version
La description vise clairement du code x86. Notre script l’a affichée car il n’a pas pu vérifier la plage de versions vulnérables (issue.detail: no-version-ranges).
Cette CVE peut être ignorée pour notre produit, même dans ses versions ultérieures. Nous pourrions ajouter la ligne suivante dans un fichier .bbappend surchargeant la recette du noyau pour cette cible.
CVE_STATUS[CVE-2023-3640] = "not-applicable-config: x86-specific and target is qemuarm."
La seconde CVE par gravité décroissante est décrite ainsi :
$ ./yocto-cve-parser/cve-parse filtered-cve.json cve CVE-2019-14899 --details
component: linux-yocto
version: 7.2.6+git
layer: core
cve: CVE-2019-14899
status: Unpatched
cvss: 3.x
score: 7.4
severity: High
issue.id: CVE-2019-14899
issue.status: Unpatched
issue.link: https://nvd.nist.gov/vuln/detail/CVE-2019-14899
issue.summary: A vulnerability was discovered in Linux, FreeBSD, OpenBSD, MacOS, iOS, and Android that allows a malicious access point, or an adjacent user, to determine if a connected user is using a VPN, make positive inferences about the websites they are visiting, and determine the correct sequence and acknowledgement numbers in use, allowing the bad actor to inject data into the TCP stream. This provides everything that is needed for an attacker to hijack active connections inside the VPN tunnel.
[...]
Cette entrée concerne un scénario assez précis, impliquant un attaquant qui peut injecter des données dans le flux TCP d’un utilisateur employant un VPN. On ne peut pas l’éliminer complètement, il faut examiner spécifiquement si elle concerne notre système.
Voyons la suivante :
$ ./yocto-cve-parser/cve-parse filtered-cve.json cve CVE-2021-3864 --details
component: linux-yocto
version: 7.2.6+git
layer: core
cve: CVE-2021-3864
status: Unpatched
cvss: 3.x
score: 7.0
severity: High
issue.id: CVE-2021-3864
issue.status: Unpatched
issue.link: https://nvd.nist.gov/vuln/detail/CVE-2021-3864
issue.summary: A flaw was found in the way the dumpable flag setting was handled when certain SUID binaries executed its descendants. The prerequisite is a SUID binary that sets real UID equal to effective UID, and real GID equal to effective GID. The descendant will then have a dumpable value set to 1. As a result, if the descendant process crashes and core_pattern is set to a relative value, its core dump is stored in the current directory with uid:gid permissions. An unprivileged local user with eligible root SUID binary could use this flaw to place core dumps into root-owned directories, potentially resulting in escalation of privileges.
[...]
L’exploitation de cette vulnérabilité est assez complexe, car elle implique un fichier exécutable Set-UID modifiant ses identifiants R-UID et R-GID puis lançant un descendant qui déclenchera l’écriture d’un fichier core. Sur un système embarqué on peut assez facilement lister les exécutables Set-UID et les examiner au cas par cas. Une solution avancée par RedHat consiste à mettre un chemin d’accès absolu dans le paramêtre kernel.core_pattern du noyau.
Nous choisissons de conserver cette CVE et de noter en commentaire de notre .bbappend du kernel qu’elle peut être contournée par un sysctl kernel.core_pattern=/tmp/core par exemple.
Pour la CVE suivante, on s’intéresse au système de fichiers JFS.
$ ./yocto-cve-parser/cve-parse filtered-cve.json cve CVE-2023-3397 --details
component: linux-yocto
version: 7.2.6+git
layer: core
cve: CVE-2023-3397
status: Unpatched
cvss: 3.x
score: 7.0
severity: High
issue.id: CVE-2023-3397
issue.status: Unpatched
issue.link: https://nvd.nist.gov/vuln/detail/CVE-2023-3397
issue.summary: A race condition occurred between the functions lmLogClose and txEnd in JFS, in the Linux Kernel, executed in different threads. This flaw allows a local attacker with normal user privileges to crash the system or leak internal kernel information.
[...]
Pour s’assurer que le système de fichier n’est pas compilé dans le kernel, il ne suffit pas de consulter /proc/filesystems sur la cible, car rien n’empêche que JFS soit compilé sous forme de module du kernel non encore chargé. Pour vérifier plus précisément, on analysera le fichier de configuration du noyau :
root@qemuarm:~# zcat /proc/config.gz | grep -E 'CONFIG_JFS_FS'
# CONFIG_JFS_FS is not set
On peut ignorer cette CVE et ajouter donc dans notre fichier .bbappend
CVE_STATUS[CVE-2023-3397] = "not-applicable-config: CONFIG_JFS_FS is disabled in the target kernel"
Voyons une dernière vulnérabilité en détail :
$ ./yocto-cve-parser/cve-parse filtered-cve.json cve CVE-2023-6238 --details
component: linux-yocto
version: 7.2.6+git
layer: core
cve: CVE-2023-6238
status: Unpatched
cvss: 3.x
score: 6.7
severity: Medium
issue.id: CVE-2023-6238
issue.status: Unpatched
issue.link: https://nvd.nist.gov/vuln/detail/CVE-2023-6238
issue.summary: A buffer overflow vulnerability was found in the NVM Express (NVMe) driver in the Linux kernel. Only privileged user could specify a small meta buffer and let the device perform larger Direct Memory Access (DMA) into the same buffer, overwriting unrelated kernel memory, causing random kernel crashes and memory corruption.
[...]
La consultation de la configuration du kernel montre que le support NVME est désactivé (NVMEM n’a rien à voir) :
# zcat /proc/config.gz | grep -E 'NVME'
# NVME Support
# CONFIG_BLK_DEV_NVME is not set
# CONFIG_NVME_FC is not set
# CONFIG_NVME_TCP is not set
# CONFIG_NVME_TARGET is not set
# end of NVME Support
CONFIG_RTC_NVMEM=y
CONFIG_NVMEM=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVMEM_LAYOUTS=y
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# CONFIG_NVMEM_RMEM is not set
On peut donc raisonnablement éliminer cette CVE avec une ligne comme :
CVE_STATUS[CVE-2023-6238] = "not-applicable-config: NVMe support is disabled"
dans un fichier d’amendement de la recette kernel.
En continuant la liste, nous voyons que nous pouvons conserver et étudier la possibilité d’exploitation dans notre environnement propre de certaines vulnérabilités :
- CVE-2023-6240 suivant l’utilisation du déchiffrement RSA dans le noyau de la cible.
- CVE-2021-3714 concernant KSM, un mémcanisme de fusion de pages mémoire identiques non activé sur notre cible (vérifier si
zcat /proc/config.gz | grep CONFIG_KSMrenvoie bien# CONFIG_KSM is not set)
On peut aussi éliminer certaines CVE :
- CVE-2020-10774 qui concerne des patches spécifiques de RedHat.
- CVE-2022-4543 qui s’appuie sur une fuite d’adresse des processeurs Intel x86.
- CVE-2010-4563 décrit une possibilité de détecter la présence d’un hôte écoutant le réseau par ICMPv6. Ubuntu par exemple a justifié sa décision de ne pas publier de correctif par l’impact limité.
- CVE-1999-0524 concernant des réponses ICMP donnant des informations de masque ou d’horodatage. RedHat propose un filtrage au niveau du pare-feu que l’on peut appliquer au besoin.
Conclusion
En conclusion on voit que d’une liste initialement impressionnante (plus de 400 vulnérabilités non patchées dans le kernel), nous sommes descendus à 11 vulnérabilités qui n’ont pas été éliminées et qui peuvent être éventuellement présentes dans les fichiers sources. Notons bien que cette étape n’est qu’une réduction du nombre de CVE à étudier en détail, pas d’une correction des failles restantes.
En examinant précisément les 11 CVE nous pouvons en ignorer rapidement 7. Pour les 4 restantes, il faudra vérifier si elles sont éventuellement exploitables sur notre carte.
N’oublions pas que ces opérations seront à répéter régulièrement :
- à chaque modification de la configuration du kernel bien sûr puisque la liste des fichiers sources compilés peut changer,
- périodiquement, afin de vérifier si de nouvelles CVE ont été ajoutées qui concerne nos fichiers compilés (en exécutant
git pulldans le répertoirevulns/).
C’est une charge de travail non négligeable pour maintenir correctement un système embarqué.
Une alternative, si vous ne souhaitez pas assurer vous-même ce suivi : Eris Linux. En effet la vérification régulière des vulnérabilités du socle logiciel (dont le kernel) est assurée par nos soins. Il ne vous reste à surveiller que les CVE concernant votre code applicatif et les composants logiciels qu’il embarque (bibliothèques par exemple) dans les containers.
