mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
The released .deb installs cleanly on Debian 12 and Ubuntu 22.04 and the daemon then cannot start, with the loader reporting GLIBC_2.39 not found. Three binaries are affected, fips, fipstop and fips-gateway; fipsctl runs, which is why it stayed quiet, since an install checked by running fipsctl gets a clean answer while the daemon is dead. It is not a v0.5.0 regression: every release artifact from v0.3.0 onward carries the same floor and the same unversioned dependency. The cause is the build machine. Rust's standard library references pidfd_spawnp and pidfd_getpid as weak undefined symbols behind a runtime check, so a binary should fall back where the C library lacks them. Linking against a C library that has them records a hard version dependency instead, and the loader refuses the image on that entry alone. No Rust changed here. One script now produces the Linux artifacts. It builds in a container pinned to the oldest distribution still supported for free by its distributor, named with the floor in packaging/build-floor.env, and runs the floor check on the package it produced, so every producer is gated rather than one workflow. The floor guard reads readelf's Version needs section: the obvious objdump formulation returns 2.2.5 for the shipped fips and would have passed every affected release. The script prints the package path as the only thing on its stdout, which is what lets a caller take it without parsing, and it takes --features. Both required care. The container's own stdout reaches the caller, so the build runs with its output on stderr; without that, a caller using a plain command substitution captures four lines of build chatter along with the path. And a feature build must keep the +<features> marker that distinguishes it from the default build of the same commit, or dpkg sees two packages at one version and a revert silently no-ops. The version is derived on the host, because the image has no git and the source is mounted read-only, so build-deb.sh now applies that marker to an explicit version as well as to one it derives. Both runners now build once through that script and install the artifact. The five deb-install legs previously built their own package each, so one CI run performed five complete release builds and four were waste; they now live in a job of their own that downloads one built package, which also stops the rest of the integration matrix waiting on it. The parity guard read one hardcoded job and now sweeps every job's matrix. The release workflow builds both architectures through the same script, and the systemd tarball takes its binaries out of that package instead of from a second, unchecked set on the runner, then is floor-checked after the strip. Cargo.toml derives the dependency with $auto rather than stating a bare libc6 that nothing can fail. Note the ordering this implies for any pipeline that builds on a current distribution: until it builds through this script, its packages will declare libc6 (>= 2.39). Measured: the container build produces four binaries at 2.34, and one artifact passes all five distributions, 95 checks, in about two minutes. The floor check fails the released 0.5.0 package on three binaries and passes this one. A profiling build produces fips_0.5.1~dev+git<date>.<sha>+profiling-1_amd64.deb.
50 lines
2.0 KiB
INI
50 lines
2.0 KiB
INI
# Build image for the Linux release artifacts.
|
|
#
|
|
# Pinned to the oldest distribution FIPS supports, because the glibc a binary is
|
|
# linked against decides the glibc it will run on. See packaging/build-floor.env
|
|
# for the floor and the reasoning; BASE is passed from there, not written here,
|
|
# so there is one place to change it.
|
|
#
|
|
# This image carries the toolchain and the build dependencies only. It never
|
|
# carries the source: the source is mounted at run time, so editing a file does
|
|
# not invalidate the image and a warm rebuild costs seconds rather than minutes.
|
|
ARG BASE=ubuntu:22.04
|
|
FROM ${BASE}
|
|
|
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
|
|
# dpkg-dev is not in a bare ubuntu:22.04 and is what provides dpkg-shlibdeps,
|
|
# which cargo-deb's "$auto" dependency resolution shells out to. Without it the
|
|
# declared dependencies would silently lose their versions again.
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
pkg-config \
|
|
libdbus-1-dev \
|
|
libclang-dev \
|
|
clang \
|
|
binutils \
|
|
dpkg-dev \
|
|
curl \
|
|
ca-certificates \
|
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
|
|
# The toolchain version is passed in, read from rust-toolchain.toml by the
|
|
# calling script, and the image tag carries it -- so the image cannot drift from
|
|
# the compiler the rest of CI uses, and bumping the pin rebuilds the image. The
|
|
# builder this replaces installed `stable` and never copied rust-toolchain.toml,
|
|
# so it compiled with a different compiler from the release and nothing said so.
|
|
ARG RUST_TOOLCHAIN
|
|
ENV RUSTUP_HOME=/usr/local/rustup \
|
|
CARGO_HOME=/usr/local/cargo \
|
|
PATH=/usr/local/cargo/bin:$PATH
|
|
RUN test -n "${RUST_TOOLCHAIN}" \
|
|
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
|
|
| sh -s -- -y --profile minimal --default-toolchain "${RUST_TOOLCHAIN}" \
|
|
&& chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME"
|
|
|
|
ARG CARGO_DEB_VERSION=3.6.3
|
|
RUN cargo install cargo-deb --version "${CARGO_DEB_VERSION}" --locked \
|
|
&& chmod -R a+w "$CARGO_HOME"
|
|
|
|
WORKDIR /src
|