Bug 16417

Summary: uninative-tarball: License, SPDX, VEX, CVE audit and CRA compliance?
Product: [Build System, Metadata & Runtime] OE-Core Reporter: Robert Berger <pokylinux>
Component: configurationAssignee: Paul Barker <paul>
Status: NEW --- QA Contact:
Severity: normal    
Priority: Medium+ CC: ccasciato, randy.macleod, richard.purdie
Version: 6.2   
Target Milestone: 6.2 M2   
Hardware: All   
OS: Multiple   
Whiteboard:
OS type for building Yocto: --- Type of Regression: ---
Verified: Documentation change: Don't know

Description Robert Berger 2026-09-07 08:33:13 UTC
Description:
When a user explicitly attempts to build the uninative-tarball from source code using `bitbake uninative-tarball`, the build system enters an ironic, non-deterministic chicken-and-egg loop. BitBake requires the existence of a pre-built, upstream uninative-tarball binary.

The uninative class is inlcuded in places where it's not needed it seems.

A quick grep shows this:
grep -r uninative | grep INHERIT
openembedded-core/meta/conf/distro/defaultsetup.conf:INHERIT_DISTRO ?= "debian devshell sstate license remove-libtool create-spdx buildstats uninative"
openembedded-core/meta/lib/oeqa/selftest/cases/sstatetests.py:INHERIT:remove = "buildstats-summary buildhistory uninative"
openembedded-core/meta/lib/oeqa/selftest/cases/sstatetests.py:INHERIT:remove = "uninative"
openembedded-core/meta/classes-recipe/populate_sdk_ext.bbclass:                f.write('INHERIT:remove = "uninative"\n')
openembedded-core/meta/classes-recipe/populate_sdk_ext.bbclass:               f.write('INHERIT += "%s"\n' % 'uninative')

uninative | grep inherit
openembedded-core/meta/classes-recipe/populate_sdk_ext.bbclass:            if not bb.data.inherits_class('uninative', d):
openembedded-core/meta/classes-recipe/populate_sdk_ext.bbclass:    if bb.data.inherits_class('uninative', d):
openembedded-core/meta/classes-recipe/populate_sdk_ext.bbclass:            if bb.data.inherits_class('uninative', d):
openembedded-core/meta/classes-recipe/populate_sdk_ext.bbclass:    fixedlsbstring = "universal" if bb.data.inherits_class('uninative', d) else ""
openembedded-core/meta/recipes-devtools/pseudo/pseudo.inc:      if [ '${@bb.data.inherits_class('uninative', d)}' = 'True' ]; then

So I suspect pseudo?

Impact on Compliance & Security:
This architectural behavior breaks the chain of custody for airtight enterprise environments:
* License Compliance / SPDX: Injects untracked, pre-compiled binary primitives into the compilation loop, contaminating the provenance trail.
* CVE Tracking: Obscures the true source lineage, blinding CVE scanners to potential upstream binary patch variances.
* Air-gapped / Sovereign Infrastructure: Breaks builds executing under strict BB_NO_NETWORK = "1" constraints unless complex out-of-band configuration fragments or anonymous inline Python filters are engineered by the user to forcefully strip out the global inherit block.

Steps to Reproduce:
1. Set up a fresh machine configuration tracking modern development branches (e.g., master/Blacksail).
2. Configure an empty DL_DIR and SSTATE_DIR.
3. Execute `bitbake uninative-tarball`.
4. Observe the fetcher calling home to pull down the official pre-compiled tarball from the Yocto servers.

Proposed Fix / Solution:
Remove all dependencies to the downloaded uninative binary when it's built from sources first.

This ensures that when a user asks to build the uninative-tarball from source, it genuinely compiles from source using the host machine's primitives, validating the integrity of generated SPDX manifests and CVE tracking logs.

---

Other proposals to keep the build clean from a precompiled uninative-tarball are welcome.
Comment 1 Robert Berger 2026-09-09 11:20:23 UTC
With this fragment your own custom uninative-tarball can be built from sources:

---

BB_CONF_FRAGMENT_SUMMARY = "Force local uninative-tarball source compilation"
BB_CONF_FRAGMENT_DESCRIPTION = "Blocks upstream pre-built uninative-tarball binary downloads \
to force a pristine local bootstrap from source code archives."

# Block pre-built binary downloads
UNINATIVE_URL = "file:///${TOPDIR}/tmp/fake-uninative/"
UNINATIVE_CHECKSUM[x86_64] = "0000000000000000000000000000000000000000000000000000000000000000"
UNINATIVE_LOADER = ""


---
Comment 2 Robert Berger 2026-09-09 15:24:40 UTC
But even if I do that I don't know e.g. how to do a cve check over it.
Comment 3 Robert Berger 2026-09-10 00:12:48 UTC
after some hacking and fighting against the AI I get those results:

upstream 5.2 uninative tarball:

74  components
53  CVEs patched
192 CVEs unpatched

### 🚨 Unpatched Severity Breakdown
| Severity Tier | Active Count | Risk Level |
| :--- | :--- | :--- |
| 🔴 CRITICAL (>= 9.0) | **0** | ✅ Clear |
| 😠 HIGH (7.0 - 8.9) | **1** | ⚠️ Review Needed |
| 😳 MEDIUM (4.0 - 6.9) | **165** | Monitor |
| 🔵 LOW (< 4.0) | **26** | Informational |

-----

whatever uninative tarball I build (blacksail from mid August)

46  components
116 CVEs patched
52  CVEs unpatched

### 🚨 Unpatched Severity Breakdown
| Severity Tier | Active Count | Risk Level |
| :--- | :--- | :--- |
| 🔴 CRITICAL (>= 9.0) | **0** | ✅ Clear |
| 😠 HIGH (7.0 - 8.9) | **0** | ✅ Clear |
| 😳 MEDIUM (4.0 - 6.9) | **48** | Monitor |
| 🔵 LOW (< 4.0) | **4** | Informational |

-----
Comment 4 Richard Purdie 2026-09-10 15:56:56 UTC
uninative is enabled by default but you don't have to use it, it is optional. If you don't need sstate to be reusable between different distros, turn it off and you've solved the problem.

Also, you do not need to have uninative enabled to build unitnative. If that is causing you concern, again, just turn it off globally.

I'm not really seeing the issue here.
Comment 5 Robert Berger 2026-09-10 17:04:38 UTC
I guess this is how you turn it off globally:

INHERIT:remove = "uninative"
Comment 6 Robert Berger 2026-09-11 06:31:08 UTC
By removing the uninative tarball I guess there are the following potential issues except for sstate reuse

*) when the host OS changes and we don't have uninative things might break - say we can solve this by using a build container and update it per yocto version, if necessary and some NATIVELSBSTRING = "docker-env-xxx"
*) eSDK with the installer will not necessarily work on a host machine, but the standalone eSDK installer does not even build anymore with a recent yocto version, so no issue
*) meta-ide-support eSDK will work as long as it runs in a container similar to the one used for building it
*) so the only remaining issue I can think of is the classic SDK installer, which will be more fragile depending on the host Distro it will be installed on.

Besides this the generic issue is, that most people using the Yocto Project/OE don't even know about the uninative tarball. Some shim is downloaded once at the beginning, but it's not taken into account for CRA compliance and License compliance.

I don't know how I could create a binary identical uninative tarball of this[1] myself with e.g. master (I guess I need a very specific Yocto version so create the 5.2 uninative-tarball).

CVE tracking also seems to be disabled somehow for the uninative tarball even if I build it myself.

[1] https://downloads.yoctoproject.org/releases/uninative/5.2/
Comment 7 Richard Purdie 2026-09-11 15:38:38 UTC
(In reply to Robert Berger from comment #6)
> By removing the uninative tarball I guess there are the following potential
> issues except for sstate reuse
> 
> *) when the host OS changes and we don't have uninative things might break -
> say we can solve this by using a build container and update it per yocto
> version, if necessary and some NATIVELSBSTRING = "docker-env-xxx"

Host OSs usually have backwards compatibility so unless you downgrade or change OS completely, this is unlikely.

> *) eSDK with the installer will not necessarily work on a host machine, but
> the standalone eSDK installer does not even build anymore with a recent
> yocto version, so no issue

eSDK should work as long as the host is the same age or newer.

> *) meta-ide-support eSDK will work as long as it runs in a container similar
> to the one used for building it

Same as the above.

> *) so the only remaining issue I can think of is the classic SDK installer,
> which will be more fragile depending on the host Distro it will be installed
> on.

classic SDK is unchanged but uninative so this isn't relevant.

> Besides this the generic issue is, that most people using the Yocto
> Project/OE don't even know about the uninative tarball. Some shim is
> downloaded once at the beginning, but it's not taken into account for CRA
> compliance and License compliance.

How do you account for the host distro for CRA and license compliance? You can view the uninative shim as something similar.
 
> I don't know how I could create a binary identical uninative tarball of
> this[1] myself with e.g. master (I guess I need a very specific Yocto
> version so create the 5.2 uninative-tarball).

You could use the official tags, e.g.:

https://git.openembedded.org/openembedded-core/tag/?h=uninative-5.2

> CVE tracking also seems to be disabled somehow for the uninative tarball
> even if I build it myself.

Not intentionally. I'm happy to have spdx information included with the uninative releases, it just needs someone to do the work in making that all happen.
Comment 8 Robert Berger 2026-09-16 10:28:59 UTC
@RP: Thanks for the clarification!

Today with my morning coffee and before reading your reply I was thinking about this as well:"How do you account for the host distro for CRA and license compliance? You can view the uninative shim as something similar."

It's a step I am not doing at the moment, but I build in a docker container, so this could be scanned as well. I wrote some recipes like syft[1]/grype[2] and kunnus-scanner[3] which should be able to scan containers as well and probably I will try out some other scanners as well.

For now I found syft/grype especially useful for golang/rust/npm CVE scanning, where we tend to miss things with the standard yocto CVE scan due to the nature of those recipes (all dependencies are typically pulled in from one recipe).

[1] https://gitlab.com/meta-layers/meta-resy/-/tree/master/recipes-devtools/syft?ref_type=heads

[2] https://gitlab.com/meta-layers/meta-resy/-/tree/master/recipes-devtools/grype?ref_type=heads

[3] https://gitlab.com/meta-layers/meta-resy/-/tree/master/recipes-devtools/kunnus-scanner?ref_type=heads
Comment 9 Paul Barker 2026-09-16 12:08:15 UTC
Hi Robert,

This is getting into "Reflections on Trusting Trust" [1] territory. At some point the host compiler was built with a previous version of a host compiler, etc, back to a point where someone toggled a program into a computer by front panel switches back in ancient times.

I think for now we need to continue drawing the boundary around the build system (and what information we collect for SBOM purposes) in the same way as we have been doing. I don't think expanding the size of our (already large) SBOM documents is likely to be helpful.

There are other approaches we could consider here. I'm interested in SLSA provenance [2] and build attestations [3] as a way to capture the wider build environment and process - but I'd want to have more confidence that this will be used by people before we invest resources in trying to support this.


[1]: https://dl.acm.org/doi/10.1145/358198.358210
[2]: https://slsa.dev/spec/v1.2/about
[3]: https://github.com/in-toto/attestation/blob/main/spec/README.md#in-toto-attestation-framework-spec