Yocto
Perché gli scanner SBOM non vedono cosa contengono le build Yocto
Gli scanner leggono un output, come un filesystem, un binario o un manifest, e deducono che cosa vi è entrato. Un'immagine Yocto ne nasconde la maggior parte: le librerie statiche e i crate Rust vengono compilati nei binari, le patch delle ricette cambiano il codice senza cambiare i numeri di versione, la configurazione del kernel decide quale codice esiste davvero e gli strumenti dell'host di build non arrivano mai nell'immagine. L'alternativa è registrare la build e conservare i metadati di patch e CVE di Yocto stesso.
Aggiornato il
In un minuto
- Host di build: gli strumenti sulla macchina di build danno forma all'immagine e non vi compaiono mai. Uno scanner dell'immagine non può vederli.
- Fetch: BitBake scarica sorgenti, crate Rust, moduli Go e strumenti. Uno scanner vede solo ciò che sopravvive nell'immagine.
- Ricette e patch: una ricetta mantiene la versione upstream e vi applica sopra patch di sicurezza. Uno scanner che confronta le versioni segnala CVE già corrette.
- Codice compilato: librerie statiche, crate e configurazione del kernel finiscono dentro i binari. Uno scanner vede un solo file dove sono entrati decine di componenti.
- Immagine: le immagini di produzione spesso eliminano il database dei pacchetti. Lo scanner non ha quindi alcun elenco da leggere e segnala poco o nulla.
In che cosa una build Yocto differisce da ciò che gli scanner si aspettano
Una build Yocto non è un'installazione tramite package manager. Gran parte di ciò che finisce sul dispositivo viene deciso in fase di build, dentro BitBake, su cinque livelli. Gli scanner guardano un livello a posteriori e devono indovinare il resto.
1. L'host di build
BitBake viene eseguito con strumenti della macchina di build. La variabile HOSTTOOLS elenca gli strumenti dell'host di build
che i task di build possono richiamare, e il sistema di build crea per essi link simbolici in ${TMPDIR}/hosttools. BitBake compila anche
i propri strumenti tramite ricette -native e -cross. Gli strumenti dell'host influenzano l'immagine e,
per progettazione, non ne fanno parte.
2. Fetch
Le ricette indicano i propri sorgenti in SRC_URI, e il fetcher li scarica in DL_DIR. Cerca
prima in DL_DIR, poi in PREMIRRORS, poi upstream e infine in MIRRORS. I crate Rust
arrivano tramite il fetcher crate://, elencati in un file -crates.inc che
cargo-update-recipe-crates genera da Cargo.lock. I moduli Go arrivano tramite la
classe go-mod oppure vengono inclusi in vendoring con go-vendor. BB_NO_NETWORK e
BB_ALLOWED_NETWORKS controllano che cosa può raggiungere il fetcher.
3. Ricette e patch
Ogni ricetta fissa una versione upstream in PV e vi applica sopra delle patch. Una patch con una riga CVE:
nell'intestazione segna quella CVE come corretta. Il numero di versione resta quello upstream, quindi la ricetta può essere corretta
mentre la sua versione dice il contrario.
4. Codice compilato
Le librerie statiche (i pacchetti -staticdev), i crate Rust e i moduli Go finiscono dentro i binari che
li usano. Il kernel e i suoi moduli vengono compilati da una configurazione specifica del prodotto, quindi due piattaforme con la stessa versione
del kernel contengono codice diverso.
5. L'immagine
Il root filesystem. La funzionalità d'immagine package-management installa gli strumenti di gestione dei pacchetti e
conserva il database del package manager. Senza di essa, i file di dati del package manager vengono eliminati dal root
filesystem, cosa comune nelle immagini di produzione.
La cache shared state (sstate), lo stato condiviso
BitBake può ripristinare l'output di un task dalla cache shared state invece di eseguirlo. L'overview manual di Yocto lo dice chiaramente: se gli oggetti precompilati sono disponibili, il compilatore non serve, "quindi il compilatore non viene nemmeno scaricato". I task ripristinati da sstate saltano fetch, compilazione e installazione, e questo conta per qualunque strumento che si basi sull'osservazione di quei passaggi. Se ne parla più avanti nella sezione sulle cache.
Perché gli scanner di immagini e filesystem non vedono la maggior parte
-
Nessun database dei pacchetti. Un'immagine di produzione compilata senza
package-managementnon offre allo scanner alcun elenco da leggere, quindi lo scanner ripiega su euristiche sui file o non segnala quasi nulla. Il risultato sembra completo ed è quasi vuoto. -
Codice statico e in vendoring. Una libreria statica o un crate compilato in
/usr/bin/foonon lascia alcun record di pacchetto.librsvgne è un esempio: l'attuale ricetta di oe-core elenca più di 350 crate Rust, e sul dispositivo è una sola libreria condivisa. -
Host di build e strumenti scaricati. Non sono mai nell'immagine, quindi mai in una scansione dell'immagine, anche se uno
strumento dell'host o una GitHub Action compromessi possono compromettere l'immagine. La backdoor di xz utils (CVE-2024-3094) è entrata nella
libreria durante la sua compilazione, dai tarball della release anziché dal repository Git. A marzo 2025 la CISA ha segnalato
che tutte le versioni della GitHub Action
tj-actions/changed-filessono state compromesse per tre giorni. -
Patch applicate. L'immagine riporta
openssla una versione upstream. La ricetta ha applicato la correzione di una CVE che interessa quella versione e ha contrassegnato la patch conCVE:. Un confronto per intervallo di versioni la segnala comunque. È la forma che assume in Yocto il problema dei backport delle distribuzioni, e una delle principali fonti del rumore trattato in come ridurre il rumore delle vulnerabilità.
Il risultato è un insieme di componenti mancanti e rilevamenti errati, e nulla nel risultato Le dice quale sia quale. Lo stesso ragionamento vale per i container nelle SBOM delle immagini Docker e per i progetti nei vari linguaggi negli strumenti open source per generare SBOM.
Perché la scansione binaria del firmware deve tirare a indovinare
L'analisi binaria confronta stringhe, simboli e firme del codice nel firmware estratto con componenti noti, poi deduce le versioni. Dove il binario porta evidenze chiare, funziona. In un'immagine Yocto spesso deve tirare a indovinare:
- binari privati dei simboli e senza stringhe di versione;
- codice collegato staticamente, dove i confini tra le librerie sono spariti;
- Rust compilato, dove i confini tra i crate scompaiono in un unico eseguibile;
- patch in backport, invisibili in un numero di versione;
- codice del kernel che la configurazione ha incluso o escluso dalla compilazione.
L'analisi binaria è lo strumento giusto per il firmware che non ha compilato Lei: blob dei fornitori, moduli acquistati, un dispositivo che sta valutando. Se non dispone della build, analizzare il binario è l'unica opzione. La regola decisionale è semplice: se lo compila, lo registri; se lo riceve soltanto, lo analizzi e chieda al fornitore una SBOM della sua build.
Che cosa fanno bene gli strumenti SBOM e CVE di Yocto
Il lavoro dello Yocto Project sulle SBOM è ottima ingegneria, e conosce cose che nessuno strumento esterno può conoscere. La sua documentazione afferma che la SBOM è "una descrizione di tutti i componenti utilizzati, delle loro licenze, delle loro dipendenze, dei loro sorgenti, delle modifiche che sono state loro applicate e delle vulnerabilità note che sono state corrette".
create-spdx per release
- 4.3 (Nanbield): la generazione SPDX è attiva per impostazione predefinita.
- 5.1 (Styhead): SPDX 3.0 per impostazione predefinita invece della 2.2, e una classe
vexche fornisce agli strumenti CVE esterni le informazioni di cui hanno bisogno. - 5.3 (Whinlatter):
SPDX_INCLUDE_COMPILED_SOURCES, che include solo i sorgenti usati per la compilazione. - 6.0 (Wrynose, supporto a lungo termine): SPDX 2.2 rimosso; aggiunti
SPDX_INCLUDE_KERNEL_CONFIGeSPDX_INCLUDE_PACKAGECONFIG; le ricette compilate con le classi Cargo, Go, PyPI, npm e CPAN ricevono un package URL del proprio ecosistema.
La SBOM copre ciò che BitBake compila, compresi gli strumenti nativi che compila per l'host. È accurata su tutto ciò che ha una ricetta.
Lo stato delle CVE come VEX dentro la SBOM
In SPDX 3, il sistema di build scrive lo stato delle CVE di ogni ricetta come relazioni VEX: una CVE corretta diventa "fixed",
collegata ai file di patch; una non corretta "affected"; una ignorata "not affected", con il motivo come impact
statement. SPDX_INCLUDE_VEX stabilisce quanto viene incluso: none, current (il valore predefinito,
le vulnerabilità non già corrette nel sorgente upstream) oppure all.
CVE_STATUS e il tag della patch
CVE_STATUS registra una decisione per ogni CVE, sotto forma di motivo e di una descrizione facoltativa. I motivi corrispondono a
corretta (backported-patch, cpe-stable-backport, fixed-version e altri),
non corretta (vulnerable-investigating) e ignorata (cpe-incorrect, disputed,
not-applicable-config, not-applicable-platform, upstream-wontfix).
CVE_STATUS_GROUPS applica una decisione a un gruppo di CVE, e CVE_PRODUCT imposta il nome del prodotto
usato per il confronto.
# In a recipe or .bbappend
CVE_STATUS[CVE-2020-15523] = "not-applicable-platform: Issue only applies on Windows"
# In the header of a patch file
CVE: CVE-2022-3341
Upstream-Status: Backport [link to the upstream commit]
Da cve-check a sbom-cve-check
cve-check confrontava i nomi delle ricette (CVE_PRODUCT) e le versioni con i dati sulle vulnerabilità. Le
note di rilascio della 5.2 avvertono che dall'inizio del 2024 i maintainer della NVD hanno smesso di annotare molte CVE con i
CPE interessati, per cui "gli attuali report CVE possono sembrare buoni, ma la realtà è che alcune vulnerabilità semplicemente non
vengono segnalate". La 5.2 ha anche reso predefinito il feed FKIE al posto della NVD. Yocto 6.0 ha rimosso cve-check e
lo ha sostituito con la classe sbom-cve-check, che esegue
sbom-cve-check di Bootlin sull'output
SPDX. Dalla 5.0 alla 5.3 ha ancora cve-check; lo consideri legacy.
Dove si ferma la SBOM di Yocto
Ciò che Yocto non può vedere è tutto ciò che sta fuori dai metadati di BitBake. Abbiamo compilato core-image-sato due volte su un
runner ARM64 nativo con 32 vCPU, una volta con la generazione SBOM di Yocto e una volta senza, e abbiamo confrontato la SBOM SPDX
3.0.1 di Yocto, scritta come 1.632 file, con la SBOM CycloneDX registrata da CRACI:
-
Componenti. La SBOM registrata da CRACI conteneva tutti i componenti della SBOM di Yocto più 88 che questa non aveva: 23 pacchetti
host sulla macchina di build (come il
cpiodi Ubuntu), 10 sorgenti GitHub, tra cui la GitHub Actionactions/upload-artifact, e 55 altri sorgenti e strumenti scaricati durante la build. -
Crate Rust. Entrambe elencavano le stesse 653 versioni di crate Rust. Nella release che abbiamo compilato, la SBOM di Yocto
le elencava solo come file
.cratecon un percorso di download, senza un package URLpkg:cargo, quindi non potevano essere confrontate con gli advisory. Da Yocto 6.0, le ricette compilate con la classe Cargo riportano un package URL per la ricetta stessa, comepkg:cargo/librsvg; nel codice attuale i singoli download dei crate continuano a non averne. Verifichi che cosa scrive la Sua release. -
Costo. La build con la generazione SBOM di Yocto ha richiesto 155 min 40 s e ha scritto 1.632 file SPDX. Senza
di essa, la build ha richiesto 88 min 48 s, il 43% in meno.
SPDX_INCLUDE_SOURCES,SPDX_INCLUDE_COMPILED_SOURCES,SPDX_INCLUDE_KERNEL_CONFIGeSPDX_INCLUDE_PACKAGECONFIGerano attivi, quindi una configurazione predefinita costa meno. La documentazione di Yocto stessa avverte che, includendo i sorgenti compilati, la SBOM non compressa dicore-image-minimal"può crescere da centinaia di megabyte a diversi gigabyte".
Le ricette native come cmake, llvm, ninja e qemu sono nella SBOM
di Yocto. Il metodo, entrambe le SBOM e il report completo sono in Build Yocto su CRACI.
CVE del kernel Linux: il problema della singola configurazione
Il progetto del kernel Linux ha annunciato il 13 febbraio 2024 di essere diventato una CVE Numbering Authority, e assegna CVE alle correzioni con generosità. La sua documentazione sulle CVE afferma che l'applicabilità di una specifica CVE "spetta all'utente di Linux determinarla", perché "non conosciamo il vostro caso d'uso e non sappiamo quali parti del kernel utilizzate".
Così un confronto sulla versione del kernel produce centinaia di rilevamenti, la maggior parte per codice che la Sua configurazione non compila mai. Quattro piattaforme hardware con quattro configurazioni del kernel danno quattro risposte diverse dalla stessa versione del kernel. Ci sono quattro modi per affrontarlo:
- Solo confronto delle versioni. Viene segnalata ogni CVE della versione. Rumore massimo.
-
Liste di esclusione curate. Voci
CVE_STATUSgenerate dai dati CVE del kernel. A maggio 2026 oe-core ha rimosso la lista generata perlinux-yocto, perchésbom-cve-checklo fa da sé a partire dall'elenco CVE fornito dal kernel, con un report CVE invariato e un SPDX più piccolo di quasi 20 MB. -
Filtro in base a ciò che è stato compilato. Con
SPDX_INCLUDE_COMPILED_SOURCESattivo per la ricetta del kernel,improve_kernel_cve_report.pyverifica se i file interessati da una CVE sono stati usati per compilare il kernel. Il security manual di Yocto afferma che "riduce i falsi positivi delle CVE del 70%-80%". - Registrazione della configurazione.
SPDX_INCLUDE_KERNEL_CONFIG(6.0) scrive la configurazione del kernel nella SBOM, così la risposta può essere verificata in seguito.
Esempio pratico. Una CVE del kernel in un driver di rete. La piattaforma A compila il driver; la piattaforma B no.
| Piattaforma | Driver compilato? | Confronto per versione | Filtro sui sorgenti compilati |
|---|---|---|---|
| A | Sì | Segnalata | Segnalata: i file interessati sono stati compilati |
| B | No | Segnalata | Non segnalata: i file interessati non sono stati compilati |
Per avere oggi report CVE del kernel per piattaforma, esegua gli strumenti di Yocto per i sorgenti compilati una volta per ciascuna configurazione della macchina. È la configurazione a decidere la risposta, quindi il report deve provenire dalla build di ciascuna configurazione.
Cache, mirror e vendoring: dove qualsiasi registrazione deve fare attenzione
-
Una build che ripristina tutto da sstate o da una
DL_DIRgià popolata scarica poco o nulla. Uno strumento che registra i fetch deve portare le proprie evidenze insieme a quelle cache, altrimenti la registrazione si riduce. - Una ricetta che punta a un tarball già in vendoring mostra un solo download, non i crate o i moduli che contiene.
- Qualunque strumento usi, compili le immagini di release da uno stato della cache noto, mantenga mirror sotto il Suo controllo e confronti il numero di componenti tra le build.
Su CRACI, i pacchetti ripristinati dalle cache CI restano nella SBOM, e lo stato di completezza di ogni job segnala ciò che la registrazione non ha potuto vedere.
Che cosa eseguire: una tabella decisionale
| Situazione | Che cosa usare | Che cosa ottiene | Che cosa Le manca ancora |
|---|---|---|---|
| Compila l'immagine in GitHub Actions | Registri la build (CRACI); mantenga create-spdx se si affida al suo stato di patch e CVE |
Pacchetti host, sorgenti e Actions scaricati, un URL pkg:cargo per crate, monitoraggio continuo |
Filtro del kernel per configurazione: usi gli strumenti di Yocto |
| Compila con Yocto in un altro sistema CI o su un build server | create-spdx con sbom-cve-check (o cve-check sulle release precedenti), filtro del kernel con i sorgenti compilati |
Ricette, patch, stato delle CVE come VEX | Un inventario dei pacchetti host e degli strumenti scaricati, tenuto separatamente |
| Riceve firmware che non compila Lei | Analisi binaria e una SBOM della build da parte del fornitore | Componenti dedotti dal binario | Certezza su versioni, patch e input della build |
| Le servono le CVE del kernel per piattaforma | Gli strumenti di Yocto per i sorgenti compilati, per configurazione della macchina | CVE per il codice che ciascuna configurazione compila | I componenti diversi dal kernel, dalla Sua SBOM |
| Dispone solo di uno scanner di immagini | Lo usi per i pacchetti installati, se il database dei pacchetti viene conservato | Una parte dell'elenco dei pacchetti di runtime | Tutto ciò che è compilato all'interno, corretto con patch o rimasto sull'host di build; un risultato pulito non è un'evidenza |
Che cosa vede ciascun metodo
| Classe di componenti | Scanner di immagini | Analisi binaria | Yocto create-spdx |
Registrazione della build (CRACI) |
|---|---|---|---|---|
| Pacchetti installati | Solo se il database dei pacchetti viene conservato | Dedotti dai file | Sì | Sì, dai sorgenti scaricati dalla build |
| Librerie statiche | No | Dedotte dalle firme | Sì, come ricette | Sì, dai sorgenti scaricati dalla build |
| Crate Rust | No | Dedotti; i confini tra i crate scompaiono | Come download .crate, senza un package URL per crate |
Sì, ciascuno con un package URL pkg:cargo |
| Moduli Go | No | Dedotti dal binario | Come download di moduli della ricetta | Sì, se scaricati durante la build |
| Patch applicate e stato delle CVE | No | No | Sì, come VEX | No |
| Configurazione del kernel | No | No | Sì, con SPDX_INCLUDE_KERNEL_CONFIG (6.0) |
No |
| Strumenti host sulla macchina di build | No | No | No (ricette native, sì) | Sì |
| Strumenti di build scaricati fuori dalle ricette e GitHub Actions | No | No | No | Sì |
Il ruolo di CRACI
Per le build Yocto eseguite in GitHub Actions, CRACI è il runner, con fino a 32 vCPU e 96 GB di RAM. Registra ciò che la build ha incorporato, compresi i pacchetti host, i sorgenti e le Actions di GitHub e gli altri sorgenti scaricati, con un package URL per ogni crate Rust: nel confronto pubblicato, tutti i componenti della SBOM di Yocto più 88 che questa non aveva. Confronta i componenti con gli advisory, continua a rivalutare la SBOM man mano che ne vengono pubblicati di nuovi e mostra quali build contenevano una dipendenza vulnerabile.
BitBake può già limitare il proprio fetcher con BB_ALLOWED_NETWORKS. La
policy di egress di CRACI aggiunge un secondo controllo sul runner, verificato prima dell'avvio
del job e fail-closed, così uno script o uno strumento che aggira il fetcher non può comunque raggiungere un host che Lei non
ha autorizzato.
Per la copertura della supply chain, la SBOM di CRACI può sostituire create-spdx. L'SPDX di Yocto riporta comunque le patch
applicate e le CVE contrassegnate come corrette, che CRACI non registra, quindi mantenga attivo create-spdx se si affida a
queste informazioni. La documentazione di CRACI include un esempio che compila core-image-sato. Il motivo per cui la registrazione batte la scansione in
generale è spiegato in SBOM in fase di build; gli strumenti per Yocto sono messi a confronto in
strumenti di sicurezza embedded a confronto e
CRACI vs Timesys Vigiles.
Quando CRACI non è la risposta
- Si affida allo stato delle CVE a livello di patch, come le decisioni
CVE_STATUSe le CVE corrette o ignorate come VEX. Queste informazioni stanno nell'SPDX di Yocto: lo conservi. - Le servono oggi report CVE del kernel per configurazione. Usi gli strumenti di Yocto per i sorgenti compilati.
- Non compila Lei il firmware. Usi l'analisi binaria.
- Le Sue build Yocto vengono eseguite fuori da GitHub Actions o devono essere eseguite sulla Sua infrastruttura. CRACI offre oggi runner gestiti su infrastruttura europea; altri sistemi CI e runner ospitati dal cliente sono nella roadmap.
- Le serve specificamente la SBOM del job Yocto in SPDX. La SBOM di CRACI nel confronto pubblicato era in CycloneDX; la SBOM di Yocto è in SPDX.
Realizza dispositivi connessi per il mercato UE? Legga che cosa richiede il CRA, come funziona VEX e come CRACI si inserisce in telecomunicazioni e apparati di rete, IoT industriale ed elettronica di consumo.
Yocto CVE check e SBOM: domande frequenti
Perché il mio strumento SCA non riesce a scansionare i nostri prodotti basati su Yocto?
Perché la maggior parte degli strumenti SCA legge manifest, lockfile o il database dei pacchetti di un'immagine, mentre una build Yocto decide il proprio contenuto dentro BitBake. Le immagini di produzione spesso eliminano il database dei pacchetti, le librerie statiche e i crate Rust vengono compilati nei binari, le patch delle ricette lasciano invariati i numeri di versione upstream e gli strumenti dell'host di build non arrivano mai nell'immagine.
Posso scansionare un'immagine Yocto o un firmware con Trivy, Grype o uno scanner binario?
Sì, e otterrà una risposta parziale. Uno scanner di immagini legge i pacchetti installati se il database dei pacchetti viene conservato, e non vede ciò che è compilato all'interno. Uno scanner binario deduce i componenti da stringhe e firme e deve tirare a indovinare con binari privati dei simboli, codice statico e Rust compilato. Nessuno dei due vede l'host di build o le patch applicate da una ricetta.
La SBOM di Yocto include i crate Rust e i moduli Go?
Li elenca come sorgenti della ricetta che li usa. Nella release che abbiamo compilato, ogni crate Rust compariva come download .crate con un percorso di download e nessun package URL pkg:cargo. Da Yocto 6.0, le ricette compilate con le classi Cargo e Go ricevono un package URL del proprio ecosistema per la ricetta stessa, non per ogni download di crate o modulo.
Perché il mio scanner segnala CVE che le nostre ricette Yocto correggono già?
Perché confronta i numeri di versione. Una ricetta Yocto mantiene la versione upstream e applica le correzioni di sicurezza come patch, contrassegnate con una riga CVE: o registrate in CVE_STATUS. Un confronto per intervallo di versioni non può vedere la patch. L'SPDX di Yocto registra quelle CVE come corrette, collegate ai file di patch.
Che cosa ha sostituito cve-check in Yocto?
La classe sbom-cve-check, in Yocto 6.0. Esegue sbom-cve-check di Bootlin sull'output SPDX della build. Le release dalla 5.0 alla 5.3 hanno ancora cve-check, che confrontava nomi e versioni delle ricette; le note di rilascio della 5.2 avvertono che i suoi report possono non rilevare vulnerabilità perché molte CVE non riportano più dati CPE.
Come ottengo le CVE del kernel Linux per la mia configurazione del kernel?
Attivi SPDX_INCLUDE_COMPILED_SOURCES per la ricetta del kernel ed esegua improve_kernel_cve_report.py, che verifica se i file interessati da ciascuna CVE sono stati compilati. Il security manual di Yocto afferma che riduce i falsi positivi delle CVE dal 70% all'80%. Lo esegua per ciascuna configurazione della macchina, perché ogni configurazione compila codice diverso.
La cache shared state influisce sulla SBOM?
Può influire. I task ripristinati da sstate saltano fetch e compilazione, quindi uno strumento che si basa sull'osservazione di quei passaggi vede meno. Il create-spdx di Yocto lavora sui metadati delle ricette. Con qualsiasi metodo, compili le immagini di release da uno stato della cache noto e confronti il numero di componenti tra le build.
La SBOM integrata di Yocto è sufficiente per il CRA?
Il CRA richiede una SBOM che copra almeno le dipendenze di primo livello, e la SBOM di Yocto è accurata su ciò che BitBake compila. Non elenca i pacchetti host sulla macchina di build, le GitHub Actions né gli strumenti scaricati fuori dalle ricette. Se ciò sia sufficiente lo decide Lei; la SBOM è un'evidenza del Suo processo, non la conformità in sé.
Porti una build Yocto alla demo
Prenoti una demo: eseguiremo una delle Sue build BitBake su un runner CRACI e vedremo insieme che cosa ha scaricato.
Prenota una demo