Merge pull request #378 from flatcar-linux/slsa-provenance-by-default

Generate SLSA provenance by default
This commit is contained in:
Jeremi Piotrowski 2022-08-15 13:39:13 +02:00 committed by GitHub
commit dc21dda002
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 10 deletions

View File

@ -265,12 +265,15 @@ query_available_package() {
tail -n 1 tail -n 1
} }
# Generate a list of packages installed in an image. # List packages installed directly in portages package database
# Usage: image_packages /image/root image_packages_portage() {
image_packages() {
local profile="${BUILD_DIR}/configroot/etc/portage/profile"
ROOT="$1" PORTAGE_CONFIGROOT="${BUILD_DIR}"/configroot \ ROOT="$1" PORTAGE_CONFIGROOT="${BUILD_DIR}"/configroot \
equery --no-color list --format '$cpv::$repo' '*' equery --no-color list --format '$cpv::$repo' '*'
}
# List packages implicitly contained in rootfs, such as in torcx packages or
# initramfs.
image_packages_implicit() {
local profile="${BUILD_DIR}/configroot/etc/portage/profile"
# We also want to list packages that only exist in the initramfs. # We also want to list packages that only exist in the initramfs.
# Approximate this by listing build dependencies of coreos-kernel that # Approximate this by listing build dependencies of coreos-kernel that
@ -304,6 +307,13 @@ image_packages() {
while read pkg ; do query_available_package "${pkg}" ; done while read pkg ; do query_available_package "${pkg}" ; done
} }
# Generate a list of packages installed in an image.
# Usage: image_packages /image/root
image_packages() {
image_packages_portage "$1"
image_packages_implicit "$1"
}
# Generate a list of installed packages in the format: # Generate a list of installed packages in the format:
# sys-apps/systemd-212-r8::coreos # sys-apps/systemd-212-r8::coreos
write_packages() { write_packages() {
@ -517,6 +527,35 @@ EOF
sudo gzip -9 "${root_fs_dir}"/usr/share/licenses/common/* sudo gzip -9 "${root_fs_dir}"/usr/share/licenses/common/*
} }
# Add /usr/share/SLSA reports for packages indirectly contained within the rootfs
# If the package is available in BOARD_ROOT accesses it from there, otherwise
# needs to download binpkg.
# Reports for torcx packages are also included when adding the torcx package to
# rootfs.
insert_extra_slsa() {
info "Inserting additional SLSA file"
local rootfs="$1"
for atom in $(image_packages_implicit "$rootfs"); do
pkg="${atom%::*}"
pkg="${pkg/\//_}.json.xz"
if [ -f "${BOARD_ROOT}/usr/share/SLSA/${pkg}" ]; then
info "Found ${atom} in BOARD_ROOT"
sudo cp "${BOARD_ROOT}/usr/share/SLSA/${pkg}" "${rootfs}/usr/share/SLSA/"
continue
fi
# let's not die if SLSA information is missing
pkgversion=$( (get_binary_pkg "=${atom}" 2>/dev/null ) || true)
binpkg="$(portageq-${BOARD} pkgdir)/${pkgversion}.tbz2"
if [ -f "${binpkg}" ]; then
info "Found ${atom} at ${binpkg}"
qtbz2 -O -t "${binpkg}" | \
sudo tar -C "${rootfs}" -xj --wildcards './usr/share/SLSA'
continue
fi
warn "Missing SLSA information for ${atom}"
done
}
# Add an entry to the image's package.provided # Add an entry to the image's package.provided
package_provided() { package_provided() {
local p profile="${BUILD_DIR}/configroot/etc/portage/profile" local p profile="${BUILD_DIR}/configroot/etc/portage/profile"
@ -606,7 +645,7 @@ finish_image() {
local casDigest="$(torcx_manifest::get_digest "${FLAGS_torcx_manifest}" "${pkg}" "${version}")" local casDigest="$(torcx_manifest::get_digest "${FLAGS_torcx_manifest}" "${pkg}" "${version}")"
sudo cp "${FLAGS_torcx_root}/pkgs/${BOARD}/${pkg}/${casDigest}/${pkg}:${version}.torcx.tgz" \ sudo cp "${FLAGS_torcx_root}/pkgs/${BOARD}/${pkg}/${casDigest}/${pkg}:${version}.torcx.tgz" \
"${root_fs_dir}${on_disk_path}" "${root_fs_dir}${on_disk_path}"
sudo tar xf "${root_fs_dir}${on_disk_path}" -C "${root_fs_dir}" --wildcards "./usr/share/SLSA"
if [[ "${version}" == "${default_version}" ]]; then if [[ "${version}" == "${default_version}" ]]; then
# Create the default symlink for this package # Create the default symlink for this package
sudo ln -fns "${on_disk_path##*/}" \ sudo ln -fns "${on_disk_path##*/}" \

View File

@ -46,7 +46,8 @@ extract_prod_gcc() {
qtbz2 -O -t "${pkg}" | \ qtbz2 -O -t "${pkg}" | \
sudo tar -C "${root_fs_dir}" -xj \ sudo tar -C "${root_fs_dir}" -xj \
--transform 's#/usr/lib/.*/#/usr/lib64/#' \ --transform 's#/usr/lib/.*/#/usr/lib64/#' \
--wildcards './usr/lib/gcc/*.so*' --wildcards './usr/lib/gcc/*.so*' \
--wildcards './usr/share/SLSA'
package_provided "${gcc}" package_provided "${gcc}"
} }
@ -85,6 +86,7 @@ create_prod_image() {
write_sbom "${root_fs_dir}" "${BUILD_DIR}/${image_sbom}" write_sbom "${root_fs_dir}" "${BUILD_DIR}/${image_sbom}"
write_licenses "${root_fs_dir}" "${BUILD_DIR}/${image_licenses}" write_licenses "${root_fs_dir}" "${BUILD_DIR}/${image_licenses}"
insert_licenses "${BUILD_DIR}/${image_licenses}" "${root_fs_dir}" insert_licenses "${BUILD_DIR}/${image_licenses}" "${root_fs_dir}"
insert_extra_slsa "${root_fs_dir}"
# Assert that if this is supposed to be an official build that the # Assert that if this is supposed to be an official build that the
# official update keys have been used. # official update keys have been used.

View File

@ -262,8 +262,9 @@ _get_dependency_list() {
PORTAGE_CONFIGROOT="$ROOT" emerge "$@" --pretend \ PORTAGE_CONFIGROOT="$ROOT" emerge "$@" --pretend \
--emptytree --root-deps=rdeps --onlydeps --quiet | \ --emptytree --root-deps=rdeps --onlydeps --quiet | \
egrep "$ROOT" |
sed -e 's/[^]]*\] \([^ :]*\).*/=\1/' | sed -e 's/[^]]*\] \([^ :]*\).*/=\1/' |
egrep -v "(=$(echo "${pkgs[*]}")-[0-9])" egrep -v "=($(echo "${pkgs[*]}"))-[0-9]"
} }
# Configure a new ROOT # Configure a new ROOT
@ -288,6 +289,8 @@ $(portageq envvar -v CHOST CBUILD ROOT \
PORTDIR PORTDIR_OVERLAY DISTDIR PKGDIR) PORTDIR PORTDIR_OVERLAY DISTDIR PKGDIR)
HOSTCC=\${CBUILD}-gcc HOSTCC=\${CBUILD}-gcc
PKG_CONFIG_PATH="\${SYSROOT}/usr/lib/pkgconfig/" PKG_CONFIG_PATH="\${SYSROOT}/usr/lib/pkgconfig/"
# Enable provenance reporting by default. Produced files are in /usr/share/SLSA
GENERATE_SLSA_PROVENANCE="true"
EOF EOF
} }
@ -392,7 +395,7 @@ install_cross_libs() {
# In order to get a dependency list we must calculate it before # In order to get a dependency list we must calculate it before
# updating package.provided. Otherwise portage will no-op. # updating package.provided. Otherwise portage will no-op.
$sudo rm -f "${package_provided}/cross-${cross_chost}" $sudo rm -f "${package_provided}/cross-${cross_chost}"
local cross_deps=$(ROOT="$ROOT" _get_dependency_list \ local cross_deps=$(ROOT="$ROOT" SYSROOT="$ROOT" _get_dependency_list \
"$@" "${TOOLCHAIN_PKGS[@]}" | $sudo tee \ "$@" "${TOOLCHAIN_PKGS[@]}" | $sudo tee \
"$ROOT/etc/portage/cross-${cross_chost}-depends") "$ROOT/etc/portage/cross-${cross_chost}-depends")

View File

@ -26,6 +26,24 @@ stage4/root_overlay: ${ROOT_OVERLAY}
EOF EOF
catalyst_stage_default catalyst_stage_default
} }
create_provenance_overlay() {
local root_overlay="$1"
while read f; do
d="${f%/*}"
mkdir -p "${root_overlay}${d}/"
cp "${f}" "${root_overlay}${d}/"
done < <(find /mnt/host/source/src/scripts -name HEAD)
local scripts_git=/mnt/host/source/src/scripts/.git
# `git rev-parse` fails due to the safe.directory setting in SDK container.
# Open-code the ref lookup
read scripts_hash <"${scripts_git}/HEAD"
if [[ "${scripts_hash}" == "ref:"* ]]; then
read scripts_hash<"${scripts_git}/${scripts_hash#ref: }"
echo "${scripts_hash}" >"${root_overlay}${scripts_git}/HEAD"
fi
mkdir -p "${root_overlay}/mnt/host/source/.repo/manifests"
cp "${REPO_MANIFESTS_DIR}/version.txt" "${root_overlay}/mnt/host/source/.repo/manifests"
}
catalyst_init "$@" catalyst_init "$@"
check_gsutil_opts check_gsutil_opts
@ -35,6 +53,7 @@ ROOT_OVERLAY="${TEMPDIR}/stage4-${ARCH}-$FLAGS_version-overlay"
# toolchain_util.sh is required by catalyst_toolchains.sh # toolchain_util.sh is required by catalyst_toolchains.sh
mkdir -p "${ROOT_OVERLAY}/tmp" mkdir -p "${ROOT_OVERLAY}/tmp"
cp "${BUILD_LIBRARY_DIR}/toolchain_util.sh" "${ROOT_OVERLAY}/tmp" cp "${BUILD_LIBRARY_DIR}/toolchain_util.sh" "${ROOT_OVERLAY}/tmp"
create_provenance_overlay "${ROOT_OVERLAY}"
catalyst_build catalyst_build

View File

@ -269,6 +269,9 @@ PORTAGE_BINHOST="${BOARD_BINHOST}"
# You can use --select to override this. # You can use --select to override this.
EMERGE_DEFAULT_OPTS="--oneshot" EMERGE_DEFAULT_OPTS="--oneshot"
# Enable provenance reporting by default. Produced files are in /usr/share/SLSA
GENERATE_SLSA_PROVENANCE="true"
# Allow the user to override or define additional settings. # Allow the user to override or define additional settings.
source "${BOARD_ETC}/portage/make.conf.user" source "${BOARD_ETC}/portage/make.conf.user"
EOF EOF
@ -319,9 +322,9 @@ if [[ ${FLAGS_regen_configs} -eq ${FLAGS_FALSE} ]]; then
install_cross_libs "${BOARD_CHOST}" ${EMERGE_FLAGS} --buildpkg=n install_cross_libs "${BOARD_CHOST}" ${EMERGE_FLAGS} --buildpkg=n
info "Building toolchain dependencies" info "Building toolchain dependencies"
"${EMERGE_WRAPPER}" --buildpkg --buildpkgonly --onlydeps -e \ "${EMERGE_WRAPPER}" --buildpkg --buildpkgonly \
--root="/usr/${BOARD_CHOST}" --sysroot="/usr/${BOARD_CHOST}" \ --root="/usr/${BOARD_CHOST}" --sysroot="/usr/${BOARD_CHOST}" \
${EMERGE_TOOLCHAIN_FLAGS} "${TOOLCHAIN_PKGS[@]}" ${EMERGE_TOOLCHAIN_FLAGS} $(< "/usr/${BOARD_CHOST}/etc/portage/cross-${BOARD_CHOST}-depends")
info "Building toolchain" info "Building toolchain"
"${EMERGE_WRAPPER}" --buildpkg --buildpkgonly \ "${EMERGE_WRAPPER}" --buildpkg --buildpkgonly \
--root="/usr/${BOARD_CHOST}" --sysroot="/usr/${BOARD_CHOST}" \ --root="/usr/${BOARD_CHOST}" --sysroot="/usr/${BOARD_CHOST}" \