mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
Add an RPM package for Fedora and RHEL. `make -C packaging rpm` builds it from packaging/rpm/fips.spec, and the release workflow attaches it beside the .deb and the systemd tarball. - The package is named `fips-mesh`, because Fedora already ships an unrelated `fips` (a FITS image viewer) that owns /usr/bin/fips. The spec declares `Conflicts: fips`. - It installs the same files, units and fips group as the .deb. fips.service and fips-dns.service are enabled but not started on install; fips-firewall and fips-gateway stay opt-in. - An upgrade queues `systemctl --no-block try-restart` of fips, fips-dns and fips-gateway, and reloads fips-firewall rather than restarting it. - The binaries come from the pinned build image via build-deb-container.sh, so the RPM passes the same glibc floor and dependency checks as the .deb. rpmbuild runs in FIPS_RPM_BUILD_IMAGE, AlmaLinux 9 pinned by digest. - The glibc floor is now 2.34 project-wide, the lowest supported RPM distribution (RHEL 9). testing/check-rpm-floor.sh fails a package that requires a newer glibc. RHEL 8 and openSUSE are not supported. - Erase removes the DNS drop-ins fips-dns-setup wrote and restarts or reloads the resolver whose file it removed, as the Debian postrm does. /etc/fips is kept, since rpm has no purge. - Dev builds are versioned 0.6.0-0.dev.git<date>.<sha>. Tested on Fedora 44 and in AlmaLinux 9 containers with systemd: the package requires GLIBC_2.34 and passes the floor check; install leaves both units enabled and inactive; upgrade returns immediately and the daemon restarts on the new binary; erase removes the units and DNS files and keeps /etc/fips; host-built binaries (GLIBC_2.39) fail the floor check; dnf refuses to install alongside the FITS viewer. The erase branch's resolver restart and reload were exercised in AlmaLinux 9 with systemctl stubbed. No install-test suite covers the RPM yet; it is only built.
94 lines
3.2 KiB
Bash
Executable File
94 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Fail when an RPM records a glibc requirement above the declared floor.
|
|
#
|
|
# The counterpart of check-deb-depends.sh, for the other package format and for
|
|
# a different failure. On the Debian side the package's Depends are written by
|
|
# hand and can disagree with what the binaries need, so that check compares the
|
|
# two. rpm derives the requirement from the ELF files and cannot disagree with
|
|
# them -- which moves the risk one step back: the binaries themselves may have
|
|
# been built somewhere above the floor, and the package that results installs
|
|
# nowhere older, silently, until someone tries.
|
|
#
|
|
# This reads the requirement out of the finished package, which is the artifact
|
|
# that ships and the same table dnf enforces at install time.
|
|
#
|
|
# Usage: check-rpm-floor.sh <package.rpm>...
|
|
#
|
|
# Reads the floor from packaging/build-floor.env unless FIPS_GLIBC_FLOOR is set.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
if [ -z "${FIPS_GLIBC_FLOOR:-}" ]; then
|
|
# shellcheck source=../packaging/build-floor.env
|
|
. "$REPO_ROOT/packaging/build-floor.env"
|
|
fi
|
|
FLOOR="${FIPS_GLIBC_FLOOR:?no floor declared}"
|
|
|
|
command -v rpm >/dev/null 2>&1 || {
|
|
echo "check-rpm-floor: rpm is not installed; cannot check anything." >&2
|
|
echo " Refusing to report a pass I did not establish." >&2
|
|
exit 2
|
|
}
|
|
|
|
[ $# -gt 0 ] || {
|
|
echo "usage: check-rpm-floor.sh <package.rpm>..." >&2
|
|
exit 2
|
|
}
|
|
|
|
# Sorts versions the way rpm does, so 2.10 is above 2.9 rather than below it.
|
|
version_gt() {
|
|
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -1)" = "$1" ] && [ "$1" != "$2" ]
|
|
}
|
|
|
|
FAILED=0
|
|
CHECKED=0
|
|
|
|
for pkg in "$@"; do
|
|
if [ ! -f "$pkg" ]; then
|
|
echo " ERROR $pkg does not exist" >&2
|
|
FAILED=$((FAILED + 1))
|
|
continue
|
|
fi
|
|
|
|
# Every libc.so.6(GLIBC_x.y) entry rpm derived from the packaged binaries.
|
|
# The highest one is the floor the package will be held to.
|
|
need=$(rpm -qp --requires "$pkg" 2>/dev/null \
|
|
| grep -oE 'GLIBC_[0-9.]+' \
|
|
| sed 's/GLIBC_//' \
|
|
| sort -V \
|
|
| tail -1) || true
|
|
|
|
if [ -z "$need" ]; then
|
|
# No requirement at all means the package holds no dynamically linked
|
|
# binary, which for this package means the file list moved. Not a pass.
|
|
echo " ERROR $(basename "$pkg") records no glibc requirement" >&2
|
|
FAILED=$((FAILED + 1))
|
|
continue
|
|
fi
|
|
|
|
CHECKED=$((CHECKED + 1))
|
|
if version_gt "$need" "$FLOOR"; then
|
|
echo " FAIL $(basename "$pkg") requires glibc $need, above the declared floor $FLOOR" >&2
|
|
FAILED=$((FAILED + 1))
|
|
else
|
|
echo " ok $(basename "$pkg") requires glibc $need"
|
|
fi
|
|
done
|
|
|
|
if [ "$FAILED" -ne 0 ]; then
|
|
echo "check-rpm-floor: $FAILED check(s) failed against floor $FLOOR." >&2
|
|
echo " The package was built from binaries compiled above the floor. Build" >&2
|
|
echo " them in the pinned container: packaging/rpm/build-rpm-container.sh." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$CHECKED" -eq 0 ]; then
|
|
echo "check-rpm-floor: nothing was checked; refusing to report a pass." >&2
|
|
exit 2
|
|
fi
|
|
|
|
echo "=== RPM glibc floor check passed ($CHECKED package(s)) ==="
|