mirror of https://github.com/wolfSSL/wolfBoot.git
sbom: generate the keystore before checking the source list
src/keystore.c holds the public keys that authorise a firmware update. The build generates it from the signing key, so a fresh checkout does not hold it, and the missing-source guard read that absence as an absent submodule. Every Make-path SBOM job failed on it. Depend on it, so it exists before the guard runs, and name it in the source list unconditionally: sbom.mk expands SBOM_SRCS through $(call) while reading the makefile, so a file that appears later can never reach the document. Without that second half the guard passed while the document was still one source short, which is the silent under-report the guard exists to prevent. Build the list with $(shell) rather than $(wildcard). GNU make 3.81 caches directory contents, so it never sees a source generated during the same run. Signed-off-by: Sameeh Jubran <sameeh@wolfssl.com>pull/824/head
parent
919de4395a
commit
da1d2cfc27
36
Makefile
36
Makefile
|
|
@ -900,13 +900,26 @@ WOLFBOOT_VERSION:=$(shell sed -n \
|
|||
include/wolfboot/version.h)
|
||||
SBOM_ROOT:=$(WOLFBOOT_ROOT)
|
||||
SBOM_NAME:=wolfboot
|
||||
SBOM_SRCS=$(wildcard $(patsubst %.o,%.c,$(OBJS))) $(wildcard $(patsubst %.o,%.S,$(OBJS)))
|
||||
# $(wildcard) above drops every object whose source is absent, and it does so
|
||||
# before the driver can report it: --skip-missing then has nothing left to warn
|
||||
# about. An absent submodule therefore shrinks the document silently. A
|
||||
# sim-tpm build without lib/wolfTPM checked out loses all eight tpm2*.c sources,
|
||||
# emits no diagnostic, and still validates. An object that maps to no source is
|
||||
# the signal, so compare the two lists and stop.
|
||||
# src/keystore.c carries the public keys that authorise a firmware update. The
|
||||
# build generates it from the signing key, so a fresh tree does not hold it yet.
|
||||
# It is still a compiled source, and a bootloader SBOM that omits its own trust
|
||||
# anchor describes the wrong image, so name it and depend on it below.
|
||||
SBOM_GENERATED_SRCS=$(filter ./src/keystore.c src/keystore.c,\
|
||||
$(patsubst %.o,%.c,$(OBJS)))
|
||||
# $(wildcard) cannot build this list. GNU make 3.81 caches directory contents,
|
||||
# so a source generated during the same run stays invisible for the rest of it;
|
||||
# $(shell) re-reads the filesystem instead. The generated sources go in
|
||||
# unconditionally because sbom.mk expands this list through $(call) while
|
||||
# reading the makefile, which is before any recipe can create them. The driver
|
||||
# opens the file afterwards, by which time the guard has made it exist.
|
||||
SBOM_SRCS=$(sort $(SBOM_GENERATED_SRCS) $(shell for o in $(OBJS); do \
|
||||
for e in c S; do s="$${o%.o}.$$e"; [ -f "$$s" ] && printf '%s ' "$$s"; done; \
|
||||
done))
|
||||
# A source that is absent must not be dropped quietly. Filtering the list to
|
||||
# what happens to be on disk shrinks the document with no diagnostic anywhere:
|
||||
# a sim-tpm build without lib/wolfTPM checked out loses all eight tpm2*.c
|
||||
# sources, emits nothing, and still validates. An object that maps to no
|
||||
# source is the signal, so compare the two lists and stop.
|
||||
SBOM_SRCS_MISSING=$(filter-out $(basename $(SBOM_SRCS)),$(basename $(OBJS)))
|
||||
SBOM_CFLAGS=$(CFLAGS)
|
||||
# wolfBoot's wolfCrypt configuration is derived, not literal: include/user_settings.h
|
||||
|
|
@ -947,7 +960,7 @@ SBOM_GEN?=
|
|||
|
||||
# Guards both SBOM targets: see SBOM_SRCS_MISSING above. SBOM_ALLOW_MISSING=1
|
||||
# accepts the partial document, and still lists what is absent.
|
||||
sbom-check-sources:
|
||||
sbom-check-sources: $(SBOM_GENERATED_SRCS)
|
||||
$(Q)if [ -n "$(strip $(SBOM_SRCS_MISSING))" ]; then \
|
||||
echo "sbom: $(words $(SBOM_SRCS_MISSING)) object(s) map to no source on disk:" >&2; \
|
||||
for o in $(SBOM_SRCS_MISSING); do echo " $$o.c (or .S)" >&2; done; \
|
||||
|
|
@ -955,9 +968,10 @@ sbom-check-sources:
|
|||
echo "sbom: SBOM_ALLOW_MISSING=1 set; the SBOM will describe fewer" >&2; \
|
||||
echo "sbom: sources than the image really holds." >&2; \
|
||||
else \
|
||||
echo "sbom: a submodule or a vendor SDK is absent, so the SBOM would" >&2; \
|
||||
echo "sbom: under-report the image. Check the tree out (git submodule" >&2; \
|
||||
echo "sbom: update --init), or set SBOM_ALLOW_MISSING=1 to accept it." >&2; \
|
||||
echo "sbom: the SBOM would under-report the image. A submodule is" >&2; \
|
||||
echo "sbom: absent (git submodule update --init), a vendor SDK lives" >&2; \
|
||||
echo "sbom: outside the tree, or the build generates that source and" >&2; \
|
||||
echo "sbom: has not run yet. Set SBOM_ALLOW_MISSING=1 to accept it." >&2; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
fi
|
||||
|
|
|
|||
13
docs/SBOM.md
13
docs/SBOM.md
|
|
@ -81,10 +81,15 @@ Obey these limitations when you make an SBOM.
|
|||
### Missing sources
|
||||
|
||||
Each object that the build compiles must map to a source file on disk. If one
|
||||
does not, a submodule or a vendor SDK is absent, and the SBOM would record
|
||||
fewer sources than the image really holds. The `sbom` and `sbom-hal` targets
|
||||
stop and list the objects. Run `git submodule update --init`, or set
|
||||
`SBOM_ALLOW_MISSING=1` to accept a partial document.
|
||||
does not, the SBOM would record fewer sources than the image really holds. The
|
||||
`sbom` and `sbom-hal` targets stop and list the objects. Run `git submodule
|
||||
update --init`, or set `SBOM_ALLOW_MISSING=1` to accept a partial document.
|
||||
|
||||
`src/keystore.c` is the exception. wolfBoot generates it from the signing key,
|
||||
so a fresh tree does not hold it yet. It carries the public keys that authorise
|
||||
a firmware update, so the SBOM must describe it. Both targets generate it first,
|
||||
exactly as a build does, which means `make sbom` on a fresh tree also creates a
|
||||
signing key if none exists.
|
||||
|
||||
## Coverage: the 11 build methods
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue