Yocto
Varför SBOM-skannrar missar vad som finns i Yocto-byggen
Skannrar läser ett resultat, till exempel ett filsystem, en binär eller ett manifest, och drar slutsatser om vad som gick in. En Yocto-avbild döljer det mesta av det: statiska bibliotek och Rust-crates kompileras in i binärer, patchar i recept ändrar kod utan att ändra versionsnummer, kärnkonfigurationen avgör vilken kod som överhuvudtaget finns, och byggvärdens verktyg når aldrig avbilden. Alternativet är att registrera bygget och behålla Yoctos egna metadata om patchar och CVE:er.
Uppdaterad
På en minut
- Byggvärd: verktyg på byggmaskinen formar avbilden och syns aldrig i den. En skanner av avbilden kan inte se dem.
- Hämtning: BitBake laddar ner källor, Rust-crates, Go-moduler och verktyg. En skanner ser bara det som finns kvar i avbilden.
- Recept och patchar: ett recept behåller uppströmsversionen och applicerar säkerhetspatchar ovanpå. En skanner som matchar versioner rapporterar CVE:er som redan är åtgärdade.
- Kompilerad kod: statiska bibliotek, crates och kärnkonfigurationen hamnar inuti binärer. En skanner ser en fil där dussintals komponenter gick in.
- Avbild: produktionsavbilder tar ofta bort paketdatabasen. En skanner har då ingen lista att läsa och rapporterar lite eller ingenting.
Hur ett Yocto-bygge skiljer sig från vad skannrar förväntar sig
Ett Yocto-bygge är ingen installation med pakethanterare. Det mesta av det som hamnar på enheten avgörs vid byggtid, inuti BitBake, i fem lager. Skannrar tittar på ett lager i efterhand och måste gissa resten.
1. Byggvärden
BitBake körs med verktyg från byggmaskinen. Variabeln HOSTTOOLS listar de verktyg på byggvärden som
byggtasks får anropa, och byggsystemet symlänkar dem till ${TMPDIR}/hosttools. BitBake bygger också egna
verktyg via -native- och -cross-recept. Värdverktygen påverkar avbilden och är avsiktligt inte en
del av den.
2. Hämtning
Recepten anger sina källor i SRC_URI, och fetchern laddar ner dem till DL_DIR. Den letar först i
DL_DIR, sedan i PREMIRRORS, sedan uppströms och sedan i MIRRORS. Rust-crates kommer
via fetchern crate://, listade i en -crates.inc-fil som cargo-update-recipe-crates
genererar från Cargo.lock. Go-moduler kommer via klassen go-mod eller vendoras med
go-vendor. BB_NO_NETWORK och BB_ALLOWED_NETWORKS styr vad fetchern får nå.
3. Recept och patchar
Varje recept låser en uppströmsversion i PV och applicerar patchar ovanpå. En patch med en
CVE:-rad i sitt huvud markerar den CVE:n som patchad. Versionsnumret förblir uppströmsversionens, så receptet
kan vara åtgärdat medan versionen säger något annat.
4. Kompilerad kod
Statiska bibliotek (-staticdev-paketen), Rust-crates och Go-moduler hamnar inuti de binärer som använder dem.
Kärnan och dess moduler byggs från en produktspecifik konfiguration, så två plattformar med samma kärnversion innehåller
olika kod.
5. Avbilden
Rotfilsystemet. Avbildsfunktionen package-management installerar verktyg för pakethantering och bevarar
pakethanterarens databas. Utan den raderas pakethanterarens datafiler från rotfilsystemet, vilket är vanligt i
produktionsavbilder.
Cachen shared state (sstate), den delade tillståndscachen
BitBake kan återställa utdata från en task ur sstate-cachen i stället för att köra den. Yoctos översiktsmanual säger det rakt ut: om de förbyggda objekten finns tillgängliga behövs inte kompilatorn, ”därför laddas kompilatorn inte ens ner”. Tasks som återställs från sstate hoppar över fetch, compile och install, vilket spelar roll för alla verktyg som bygger på att observera de stegen. Mer om det i avsnittet om cachar nedan.
Varför avbilds- och filsystemskannrar missar det mesta
-
Ingen paketdatabas. En produktionsavbild byggd utan
package-managementger en skanner ingen lista att läsa, så den faller tillbaka på filheuristik eller rapporterar nästan ingenting. Resultatet ser komplett ut och är nästan tomt. -
Statisk och vendorad kod. Ett statiskt bibliotek eller en crate som kompilerats in i
/usr/bin/foolämnar ingen paketpost efter sig.librsvgär ett exempel: det nuvarande oe-core-receptet listar mer än 350 Rust-crates, och på enheten är det ett enda delat bibliotek. -
Byggvärd och hämtade verktyg. De finns aldrig i avbilden, alltså aldrig i en avbildsskanning, trots att
ett komprometterat värdverktyg eller en komprometterad GitHub Action kan kompromettera avbilden. Bakdörren i xz utils
(CVE-2024-3094) kom in i biblioteket medan det byggdes, från release-tarballs och inte från Git-repositoryt. I mars 2025
rapporterade CISA att varje version av GitHub Action
tj-actions/changed-filesvar komprometterad i tre dagar. -
Applicerade patchar. Avbilden anger
openssli en uppströmsversion. Receptet applicerade åtgärden för en CVE som påverkar den versionen och märkte patchen medCVE:. En matchning på versionsintervall flaggar den ändå. Det här är Yoctos variant av distributionernas backport-problem, och en av de största källorna till det brus som tas upp i så minskar du sårbarhetsbruset.
Summan blir en blandning av saknade komponenter och felaktiga fynd, och ingenting i resultatet berättar vilket som är vilket. Samma argument gäller för containrar i SBOM:er för Docker-avbilder och för språkprojekt i SBOM-generatorer med öppen källkod.
Varför binäranalys av firmware måste gissa
Binäranalys matchar strängar, symboler och kodsignaturer i extraherad firmware mot kända komponenter och drar sedan slutsatser om versioner. Där binären bär tydliga belägg fungerar det. I en Yocto-avbild måste den ofta gissa:
- strippade binärer utan versionssträngar;
- statiskt länkad kod, där gränserna mellan bibliotek har försvunnit;
- kompilerad Rust, där gränserna mellan crates försvinner in i en enda körbar fil;
- bakåtporterade patchar, som är osynliga i ett versionsnummer;
- kärnkod som konfigurationen kompilerat in eller ut.
Binäranalys är rätt verktyg för firmware du inte har byggt själv: blobbar från leverantörer, inköpta moduler, en enhet du utvärderar. Om du inte har bygget är analys av binären det enda alternativet. Beslutsregeln är enkel: om du bygger det, registrera det; om du bara tar emot det, analysera det och be leverantören om en SBOM från deras bygge.
Vad Yoctos egna SBOM- och CVE-verktyg gör bra
Yocto Projects SBOM-arbete är gedigen ingenjörskonst, och det vet saker som inget externt verktyg kan veta. Dokumentationen beskriver SBOM:en som ”en beskrivning av alla komponenter du använt, deras licenser, deras beroenden, deras källor, de ändringar som applicerats på dem och de kända sårbarheter som åtgärdats”.
create-spdx per release
- 4.3 (Nanbield): SPDX-generering är påslagen som standard.
- 5.1 (Styhead): SPDX 3.0 som standard i stället för 2.2, och en
vex-klass som ger externa CVE-verktyg den information de behöver. - 5.3 (Whinlatter):
SPDX_INCLUDE_COMPILED_SOURCES, som bara tar med de källor som användes vid kompileringen. - 6.0 (Wrynose, långtidssupport): SPDX 2.2 borttaget;
SPDX_INCLUDE_KERNEL_CONFIGochSPDX_INCLUDE_PACKAGECONFIGtillagda; recept som byggs med klasserna för Cargo, Go, PyPI, npm och CPAN får en paket-URL för sitt ekosystem.
SBOM:en täcker det BitBake bygger, inklusive de native-verktyg den bygger för värden. Den är grundlig för allt som har ett recept.
CVE-status som VEX i SBOM:en
I SPDX 3 skriver byggsystemet varje recepts CVE-status som VEX-relationer: en patchad CVE blir ”fixed”, länkad till
patchfilerna; en opatchad ”affected”; en ignorerad ”not affected”, med skälet som impact statement.
SPDX_INCLUDE_VEX styr hur mycket som tas med: none, current (standard, sårbarheter som
inte redan är åtgärdade i uppströmskällan) eller all.
CVE_STATUS och patchtaggen
CVE_STATUS registrerar ett beslut per CVE, som ett skäl och en valfri beskrivning. Skälen motsvarar patchad
(backported-patch, cpe-stable-backport, fixed-version med flera), opatchad
(vulnerable-investigating) och ignorerad (cpe-incorrect, disputed,
not-applicable-config, not-applicable-platform, upstream-wontfix).
CVE_STATUS_GROUPS tillämpar ett beslut på en grupp CVE:er, och CVE_PRODUCT anger det produktnamn
som används vid matchning.
# 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]
Från cve-check till sbom-cve-check
cve-check matchade receptnamn (CVE_PRODUCT) och versioner mot sårbarhetsdata. Release notes för
5.2 varnar för att NVD:s förvaltare sedan början av 2024 har slutat annotera många CVE:er med de berörda CPE:erna, så att
”de nuvarande CVE-rapporterna kan se bra ut, men i verkligheten rapporteras vissa sårbarheter helt enkelt inte”. 5.2 gjorde
också FKIE-flödet till standard i stället för NVD. Yocto 6.0 tog bort cve-check och ersatte den med klassen
sbom-cve-check, som kör Bootlins
sbom-cve-check på
SPDX-utdata. På 5.0 till 5.3 har du fortfarande cve-check; behandla den som legacy.
Där Yoctos SBOM tar slut
Det Yocto inte kan se är allt utanför BitBakes metadata. Vi byggde core-image-sato två gånger på en native
ARM64-runner med 32 vCPU:er, en gång med Yoctos SBOM-generering och en gång utan, och jämförde Yoctos SBOM i SPDX
3.0.1, skriven som 1 632 filer, med den CycloneDX-SBOM som CRACI registrerade:
-
Komponenter. CRACI:s registrerade SBOM hade varje komponent som Yoctos SBOM hade, plus 88 som den
missade: 23 värdpaket på byggmaskinen (som Ubuntus
cpio), 10 GitHub-källor, bland dem GitHub Actionactions/upload-artifact, och 55 andra källor och verktyg som hämtades under bygget. -
Rust-crates. Båda listade samma 653 versioner av Rust-crates. I den release vi byggde listade Yoctos SBOM
dem bara som
.crate-filer med en nedladdningsplats, utanpkg:cargo-paket-URL, så de gick inte att matcha mot säkerhetsbulletiner. Sedan Yocto 6.0 har recept som byggs med Cargo-klassen en paket-URL för själva receptet, till exempelpkg:cargo/librsvg; i den nuvarande koden saknar de enskilda crate-nedladdningarna fortfarande en. Kontrollera vad din release skriver. -
Kostnad. Bygget med Yoctos SBOM-generering tog 155 min 40 s och skrev 1 632 SPDX-filer. Utan den tog
bygget 88 min 48 s, 43 % mindre.
SPDX_INCLUDE_SOURCES,SPDX_INCLUDE_COMPILED_SOURCES,SPDX_INCLUDE_KERNEL_CONFIGochSPDX_INCLUDE_PACKAGECONFIGvar påslagna, så en standardkonfiguration kostar mindre. Yoctos egen dokumentation varnar för att den okomprimerade SBOM:en förcore-image-minimalmed kompilerade källor inkluderade ”kan växa från hundratals megabyte till flera gigabyte”.
Native-recept som cmake, llvm, ninja och qemu finns i Yoctos SBOM.
Metoden, båda SBOM:erna och hela rapporten finns på Yocto-byggen på CRACI.
CVE:er i Linuxkärnan: problemet per konfiguration
Linuxkärnans projekt meddelade den 13 februari 2024 att det hade blivit CVE Numbering Authority, och det tilldelar frikostigt CVE:er till åtgärder. Dess CVE-dokumentation säger att tillämpligheten för en viss CVE ”är upp till användaren av Linux att avgöra”, eftersom ”vi inte känner till ditt användningsfall, och vi vet inte vilka delar av kärnan du använder”.
En matchning på kärnversion ger därför hundratals fynd, de flesta för kod som din konfiguration aldrig kompilerar. Fyra hårdvaruplattformar med fyra kärnkonfigurationer ger fyra olika svar för samma kärnversion. Det finns fyra sätt att hantera det:
- Endast versionsmatchning. Varje CVE för versionen rapporteras. Maximalt brus.
-
Kurerade undantagslistor.
CVE_STATUS-poster genererade från kärnans CVE-data. I maj 2026 tog oe-core bort sin genererade lista förlinux-yocto, eftersomsbom-cve-checkgör det själv utifrån den CVE-lista kärnan levererar, med en oförändrad CVE-rapport och en SPDX som är nästan 20 MB mindre. -
Filtrering efter vad som kompilerades. Med
SPDX_INCLUDE_COMPILED_SOURCESpåslaget för kärnreceptet kontrollerarimprove_kernel_cve_report.pyom de filer en CVE påverkar användes för att bygga kärnan. Yoctos säkerhetsmanual säger att det ”minskar falska positiva CVE:er med 70 %-80 %”. - Registrera konfigurationen.
SPDX_INCLUDE_KERNEL_CONFIG(6.0) skriver in kärnkonfigurationen i SBOM:en, så att svaret kan kontrolleras senare.
Genomräknat exempel. En CVE i kärnan i en nätverksdrivrutin. Plattform A bygger drivrutinen; plattform B gör det inte.
| Plattform | Drivrutinen kompilerad? | Versionsmatchning | Filter på kompilerade källor |
|---|---|---|---|
| A | Ja | Rapporteras | Rapporteras: de berörda filerna byggdes |
| B | Nej | Rapporteras | Rapporteras inte: de berörda filerna byggdes inte |
För CVE-rapporter för kärnan per plattform i dag kör du Yoctos verktyg för kompilerade källor en gång per maskinkonfiguration. Det är konfigurationen som avgör svaret, så rapporten måste komma från varje konfigurations bygge.
Cachar, speglar och vendoring: där varje registrerare måste vara försiktig
-
Ett bygge som återställer allt från sstate eller från en fylld
DL_DIRhämtar lite eller ingenting. En registrerare som ser hämtningar måste föra med sig sina belägg i de cacharna, annars krymper registreringen. - Ett recept som pekar på en förvendorad tarball visar en nedladdning, inte de crates eller moduler som finns i den.
- Vad du än använder: bygg release-avbilder från ett känt cachetillstånd, ha speglar som du själv kontrollerar och jämför antalet komponenter mellan byggen.
På CRACI stannar paket som återställs från CI-cachar kvar i SBOM:en, och varje jobbs fullständighetsstatus flaggar det som registreringen inte kunde se.
Vad du ska köra: en beslutstabell
| Situation | Vad du använder | Vad du får | Vad du fortfarande saknar |
|---|---|---|---|
| Du bygger avbilden i GitHub Actions | Registrera bygget (CRACI); behåll create-spdx om du förlitar dig på dess patch- och CVE-status |
Värdpaket, hämtade källor och Actions, en pkg:cargo-URL per crate, löpande bevakning |
Kärnfiltrering per konfiguration: använd Yoctos verktyg |
| Du bygger med Yocto i ett annat CI-system eller på en byggserver | create-spdx med sbom-cve-check (eller cve-check på äldre releaser), kärnfiltrering med kompilerade källor |
Recept, patchar, CVE-status som VEX | En inventering av värdpaket och hämtade verktyg, förd separat |
| Du tar emot firmware som du inte bygger | Binäranalys, och en bygg-SBOM från leverantören | Komponenter som härletts ur binären | Säkerhet om versioner, patchar och bygg-indata |
| Du behöver kärnans CVE:er per plattform | Yoctos verktyg för kompilerade källor, per maskinkonfiguration | CVE:er för den kod varje konfiguration bygger | Komponenter utanför kärnan, från din SBOM |
| Du har bara en avbildsskanner | Använd den för installerade paket, om paketdatabasen behålls | En del av paketlistan vid körning | Allt som kompilerats in, patchats eller blivit kvar på byggvärden; ett rent resultat är inget belägg |
Vad varje metod ser
| Komponentklass | Avbildsskanner | Binäranalys | Yocto create-spdx |
Byggregistrering (CRACI) |
|---|---|---|---|---|
| Installerade paket | Bara om paketdatabasen behålls | Härledda ur filer | Ja | Ja, från de källor bygget hämtade |
| Statiska bibliotek | Nej | Härledda ur signaturer | Ja, som recept | Ja, från de källor bygget hämtade |
| Rust-crates | Nej | Härledda; gränserna mellan crates försvinner | Som .crate-nedladdningar, utan paket-URL per crate |
Ja, var och en med en pkg:cargo-paket-URL |
| Go-moduler | Nej | Härledda ur binären | Som receptets modulnedladdningar | Ja, när de hämtas under bygget |
| Applicerade patchar och CVE-status | Nej | Nej | Ja, som VEX | Nej |
| Kärnkonfiguration | Nej | Nej | Ja, med SPDX_INCLUDE_KERNEL_CONFIG (6.0) |
Nej |
| Värdverktyg på byggmaskinen | Nej | Nej | Nej (native-recept, ja) | Ja |
| Byggverktyg som hämtas utanför recept, och GitHub Actions | Nej | Nej | Nej | Ja |
Där CRACI passar in
För Yocto-byggen som körs i GitHub Actions är CRACI runnern, med upp till 32 vCPU:er och 96 GB RAM. Den registrerar vad bygget drog in, inklusive värdpaket, GitHub-källor och Actions samt andra hämtade källor, med en paket-URL för varje Rust-crate: i den publicerade jämförelsen varje komponent som Yoctos SBOM hade, plus 88 som den missade. Den matchar komponenterna mot säkerhetsbulletiner, fortsätter att omvärdera SBOM:en när nya publiceras och visar vilka byggen som innehöll ett sårbart beroende.
BitBake kan redan begränsa sin fetcher med BB_ALLOWED_NETWORKS. CRACI:s
egress-policy lägger till en andra kontroll vid runnern, som kontrolleras innan
jobbet startar och stänger vid fel, så att ett skript eller verktyg som går runt fetchern ändå inte kan nå en värd som du
inte har tillåtit.
För täckning av leveranskedjan kan CRACI:s SBOM ersätta create-spdx. Yoctos SPDX innehåller fortfarande de
applicerade patcharna och de CVE:er som markerats som åtgärdade, vilket CRACI inte registrerar, så behåll
create-spdx påslaget om du förlitar dig på dem. CRACI:s dokumentation innehåller ett exempel som bygger
core-image-sato. Varför registrering i allmänhet slår skanning finns på
SBOM:er från byggtid; Yocto-verktyg jämförs på
säkerhetsverktyg för inbyggda system jämförda och
CRACI vs Timesys Vigiles.
När CRACI inte är svaret
- Du förlitar dig på CVE-status på patchnivå, som beslut i
CVE_STATUSoch patchade eller ignorerade CVE:er som VEX. Det finns i Yoctos SPDX: behåll den. - Du behöver CVE-rapporter för kärnan per konfiguration i dag. Använd Yoctos verktyg för kompilerade källor.
- Du bygger inte firmwaren själv. Använd binäranalys.
- Dina Yocto-byggen körs utanför GitHub Actions, eller måste köras på din egen infrastruktur. CRACI erbjuder i dag hanterade runners på europeisk infrastruktur; andra CI-system och kundhostade runners finns på roadmapen.
- Du behöver SBOM:en för Yocto-jobbet just i SPDX. CRACI:s SBOM i den publicerade jämförelsen var CycloneDX; Yoctos egen SBOM är SPDX.
Bygger du uppkopplade enheter för EU-marknaden? Läs vad CRA kräver, hur VEX fungerar och hur CRACI passar för telekom- och nätverksutrustning, industriell IoT och hemelektronik.
Yocto CVE check och SBOM:er: vanliga frågor
Varför kan mitt SCA-verktyg inte skanna våra Yocto-baserade produkter?
Därför att de flesta SCA-verktyg läser manifest, lockfiler eller en avbilds paketdatabas, medan ett Yocto-bygge avgör sitt innehåll inuti BitBake. Produktionsavbilder tar ofta bort paketdatabasen, statiska bibliotek och Rust-crates kompileras in i binärer, patchar i recept lämnar uppströmsversionernas nummer orörda, och byggvärdens verktyg når aldrig avbilden.
Kan jag skanna en Yocto-avbild eller firmware med Trivy, Grype eller en binärskanner?
Det kan du, och du får ett ofullständigt svar. En avbildsskanner läser de installerade paketen om paketdatabasen behålls, och missar det som kompilerats in. En binärskanner härleder komponenter ur strängar och signaturer och måste gissa vid strippade binärer, statisk kod och kompilerad Rust. Ingen av dem ser byggvärden eller de patchar som ett recept applicerat.
Tar Yoctos SBOM med Rust-crates och Go-moduler?
Den listar dem som källor till receptet som använder dem. I den release vi byggde förekom varje Rust-crate som en .crate-nedladdning med en nedladdningsplats och utan pkg:cargo-paket-URL. Sedan Yocto 6.0 får recept som byggs med klasserna för Cargo och Go en paket-URL för sitt ekosystem för själva receptet, inte för varje crate- eller modulnedladdning.
Varför rapporterar min skanner CVE:er som våra Yocto-recept redan patchar?
Därför att den matchar versionsnummer. Ett Yocto-recept behåller uppströmsversionen och applicerar säkerhetsåtgärder som patchar, märkta med en CVE:-rad eller registrerade i CVE_STATUS. En matchning på versionsintervall kan inte se patchen. Yoctos egen SPDX registrerar de CVE:erna som åtgärdade, länkade till patchfilerna.
Vad ersatte cve-check i Yocto?
Klassen sbom-cve-check, i Yocto 6.0. Den kör Bootlins sbom-cve-check på byggets SPDX-utdata. Release 5.0 till 5.3 har fortfarande cve-check, som matchade receptnamn och versioner; release notes för 5.2 varnar för att dess rapporter kan missa sårbarheter eftersom många CVE:er inte längre har CPE-data.
Hur får jag Linuxkärnans CVE:er för min egen kärnkonfiguration?
Slå på SPDX_INCLUDE_COMPILED_SOURCES för kärnreceptet och kör improve_kernel_cve_report.py, som kontrollerar om de filer varje CVE påverkar kompilerades. Yoctos säkerhetsmanual säger att det minskar falska positiva CVE:er med 70 till 80 %. Kör det per maskinkonfiguration, eftersom varje konfiguration bygger olika kod.
Påverkar shared state-cachen SBOM:en?
Det kan den. Tasks som återställs från sstate hoppar över fetch och compile, så ett verktyg som bygger på att observera de stegen ser mindre. Yoctos create-spdx utgår från receptens metadata. Oavsett metod: bygg release-avbilder från ett känt cachetillstånd och jämför antalet komponenter mellan byggen.
Räcker Yoctos inbyggda SBOM för CRA?
CRA kräver en SBOM som täcker åtminstone beroendena på högsta nivån, och Yoctos SBOM är grundlig för det BitBake bygger. Den listar inte värdpaket på byggmaskinen, GitHub Actions eller verktyg som hämtas utanför recept. Om det räcker är ditt beslut; SBOM:en är belägg för din process, inte efterlevnad i sig.
Ta med ett Yocto-bygge till demon
Boka en demo så kör vi ett av dina BitBake-byggen på en CRACI-runner och går igenom vad det hämtade.
Boka en demo