Bug 2541665
| Summary: | Review Request: modulejail - Shrink Linux kernel-module attack surface | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Justin M. Forbes <jforbes> |
| Component: | Package Review | Assignee: | Jeremy Cline <jeremy> |
| Status: | ASSIGNED --- | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | rawhide | CC: | jeremy, jmforbes, jnuyens, package-review |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | Type: | --- | |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
|
Description
Justin M. Forbes
2026-09-25 21:37:17 UTC
Hi, upstream author here. Thanks Justin for packaging this. Some context for whoever picks up the review: * Debian already ships it. 1.6.1-1 is in unstable and testing (ITP #1138266). * I'm happy to change things upstream if it makes the Fedora package cleaner: - %post runs "modulejail --install-initramfs-hook", which writes /usr/lib/dracut/modules.d/99modulejail-strip/ at install time. The hook keeps the blacklist out of the initramfs. Otherwise dracut bakes the current blacklist into the initramfs on a kernel update, and if the new kernel renames a storage driver the machine could fail to boot (upstream issue #19). Dropping it from the initrd costs no security, since no unprivileged users exist before pivot_root. Right now no package owns those files. I can add a way to generate the hook at build time so the spec ships it in %files instead. - The script runs an update check against api.github.com after each run (MODULEJAIL_NO_UPDATE_CHECK turns it off). I can add a build-time switch so distro packages ship with the check disabled. * Source0 can point at https://github.com/jnuyens/modulejail/archive/v%{version}/%{name}-%{version}.tar.gz If anything else comes up, reply here or open an issue on GitHub and I'll respond quickly. Jasper Hi Justin,
Both changes are in 1.6.3:
1. Package the dracut hook and drop %post/%preun:
%install
./modulejail --install-initramfs-hook --initramfs-builder dracut --destdir %{buildroot}
%files
%dir %{_prefix}/lib/dracut/modules.d/99modulejail-strip
%{_prefix}/lib/dracut/modules.d/99modulejail-strip/module-setup.sh
2. Disable the GitHub update check:
sed -i 's/^UPDATE_CHECK_DEFAULT=1$/UPDATE_CHECK_DEFAULT=0/' %{buildroot}%{_bindir}/modulejail
Tested on Fedora 45: rpm -V is clean, an upgrade from 1.6.2 takes over the old hook file, removal deletes it, and the hook strips the blacklist from hostonly images.
Source0: https://github.com/jnuyens/modulejail/archive/v1.6.3/modulejail-1.6.3.tar.gz
Thanks,
Jasper
Package was updated: SRPM URL: https://jforbes.fedorapeople.org/modulejail/modulejail-1.6.3-1.fc46.src.rpm Scratch build: https://koji.fedoraproject.org/koji/taskinfo?taskID=151723906 spec URL doesn't change. For lack of a better review tool, I've posted my suggestions as a diff below with notes inline. For convenience, the full spec is at https://jcline.fedorapeople.org/new-packages/modulejail.spec and you can fetch all the sources with "spectool -g modulejail.spec". None of these are particularly deal-breaking, so if there's something you don't like that's fine. Name: modulejail Version: 1.6.3 -Release: 1%{?dist} +Release: %{autorelease} I'm lazy and don't care to manually bump the release, this should be paired with %{autochangelog} Summary: Shrink Linux kernel-module attack surface License: GPL-3.0-only URL: https://modulejail.com -Source0: %{name}-%{version}.tar.gz +Source0: https://github.com/jnuyens/modulejail/archive/v%{version}/%{name}-v%{version}.tar.gz This way you can bump the version and run spectool -g on the specfile to fetch the new sources +Source1: https://github.com/jnuyens/modulejail/releases/download/v%{version}/v%{version}.tar.gz.sig +# The repository documents the signing key ID is 095F 5C8B 39AF 010E 7B61 5CD4 487B C00D 69C2 A955 +# +# At the time I fetched this, the following signing key was present: +# +# sq inspect --cert=095F5C8B39AF010E7B615CD4487BC00D69C2A955 --keyring ./jnuyens.gpg +# OpenPGP Certificate. +# +# Fingerprint: 095F5C8B39AF010E7B615CD4487BC00D69C2A955 +# Public-key algo: RSA +# Public-key size: 4096 bits +# Creation time: 2026-05-24 19:26:07 UTC +# Key flags: certification, signing +Source2: https://github.com/jnuyens.gpg Upstream does sign their releases, so pulling in the signature and signing key lets us check that. You can check in the keyfile rather than uploading it as a source if you'd prefer, but either way you'll see if it changes during the normal update workflow. BuildArch: noarch +BuildRequires: openpgpverify Requires: coreutils Requires: findutils Requires: gawk Recommends: curl -%description +%global _description %{expand: ModuleJail snapshots the set of currently loaded modules and writes a modprobe.d blacklist for every kernel module not currently in use, minus a built-in baseline and an optional sysadmin-supplied whitelist. @@ -25,90 +40,39 @@ No daemon, no continuous monitoring, no AI inside the tool. One shell script, run once on a steady-state host, that writes one modprobe.d -blacklist file. +blacklist file.} + +%description %{_description} + This is a silly hack to handle the description macro needing to either be one line or escaping the line breaks %prep -%setup -q +%{openpgpverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +%autosetup -n %{name}-%{version} -p1 + Verify the signature and use autosetup - if you drop in "Patch: some.patch" at the top it'll apply them which is convenient. + +%build +sed -i 's/__VERSION__/%{version}/' man/modulejail.8.in +sed -i "s/__DATE__/$(date -u -d @${SOURCE_DATE_EPOCH} +%Y-%m-%d)/" man/modulejail.8.in +# Updates are shipped via dnf +sed -i 's/^UPDATE_CHECK_DEFAULT=1$/UPDATE_CHECK_DEFAULT=0/' modulejail + Disable updates and set the version and date in the manpage. This seems to be all the build script upstream does. %install install -Dm755 modulejail %{buildroot}%{_bindir}/modulejail -install -Dm644 README.md %{buildroot}%{_docdir}/%{name}/README.md -install -Dm644 LICENSE %{buildroot}%{_docdir}/%{name}/LICENSE -install -Dm644 modulejail.8 %{buildroot}%{_mandir}/man8/modulejail.8 +install -Dm644 man/modulejail.8.in %{buildroot}%{_mandir}/man8/modulejail.8 These days you don't need to manually install files referenced in %doc or %license, they're handled automagically. # Stage the dracut strip hook so the package owns it (see gh #19 and # docs/DEFENSE-IN-DEPTH.md). It keeps the blacklist out of rebuilt # initramfs images; dracut picks it up on the next kernel install. ./modulejail --install-initramfs-hook --initramfs-builder dracut --destdir %{buildroot} -# Distro repositories ship updates through dnf, so a distro build would -# also turn off the post-run GitHub update check here: -# sed -i 's/^UPDATE_CHECK_DEFAULT=1$/UPDATE_CHECK_DEFAULT=0/' %%{buildroot}%%{_bindir}/modulejail -# This upstream package is installed from GitHub releases, so it keeps it. + %files +%license LICENSE +%doc README.md %{_bindir}/modulejail -%dir %{_docdir}/%{name} -%doc %{_docdir}/%{name}/README.md -%license %{_docdir}/%{name}/LICENSE %{_mandir}/man8/modulejail.8* %dir %{_prefix}/lib/dracut/modules.d/99modulejail-strip %{_prefix}/lib/dracut/modules.d/99modulejail-strip/module-setup.sh %changelog -* Tue Oct 27 2026 Justin M. Forbes <jforbes> - 1.6.3-1 -- Initial Fedora packaging - -* Mon May 18 2026 Jasper Nuyens <jnuyens> - 1.6.3-1 -- Add --whitelist-file PATH flag (closes GitHub Issue #2). Reads a - site-local whitelist file (one module per line, # comments, blank - lines ignored), validates each line against [a-zA-Z0-9_-]+, refuses - group- or world-writable files, and appends valid names to the - in-script WHITELIST. Operators no longer lose site-local additions - on .deb/.rpm/curl|sh reinstalls. -- Add --no-syslog-logging flag. Default behaviour change: when - /usr/bin/logger is executable on the host, generated install lines - now call logger with tag 'modulejail' so blocked module loads are - visible via 'journalctl -t modulejail' or 'grep modulejail - /var/log/syslog'. --no-syslog-logging restores the v1.1.4 - /bin/true install-line body byte-for-byte. -- Add archived v1.1.4 regression fixture under - tests/fixtures/v1.1.4-regression/, exercising the body-identical - invariant as a permanent baseline. - -* Wed May 13 2026 Jasper Nuyens <jnuyens> - 1.1.4-1 -- Add project logo to README. -- Test infra: update container fixture to be version-agnostic (was - hardcoded to 1.0.0 strings) and add four new assertions covering the - v1.1.x update-check surface, including a static regression guard - against the v1.1.2 busybox-wget bug. - -* Wed May 13 2026 Jasper Nuyens <jnuyens> - 1.1.3-1 -- Update check now works on Alpine / busybox wget. The wget invocation - used GNU long-form flags (--quiet, --max-redirect=5, - --output-document=-) that busybox wget rejects, causing the check to - silently exit non-zero on every Alpine host. Switched to the - universal short-flag subset (-q, -T 10, -O -) and dropped - --max-redirect (the GitHub tags API does not redirect). No other - changes. - -* Wed May 13 2026 Jasper Nuyens <jnuyens> - 1.1.2-1 -- Adds modulejail(8) manpage; ships at /usr/share/man/man8/modulejail.8.gz. - -* Tue May 12 2026 Jasper Nuyens <jnuyens> - 1.1.1-1 -- Documentation: swap the order of "Why?" and "What ModuleJail is" in - the README so the motivation leads. -- Packaging: drop the per-distro %dist suffix from the RPM filename - (was modulejail-X.Y.Z-1.el9.noarch.rpm, now - modulejail-X.Y.Z-1.noarch.rpm). ModuleJail is a noarch shell script - with no per-major-RHEL semantics. - -* Tue May 12 2026 Jasper Nuyens <jnuyens> - 1.1.0-1 -- Adds .deb and .rpm packaging. -- Adds optional post-run check for a newer release on GitHub: silent on - any failure, 10-second hard timeout, only complains when reachable - and a newer tag exists. Honours MODULEJAIL_NO_UPDATE_CHECK. - -* Tue May 12 2026 Jasper Nuyens <jnuyens> - 1.0.1-1 -- Documentation cleanup release. - -* Tue May 12 2026 Jasper Nuyens <jnuyens> - 1.0.0-1 -- Initial release. +%{autochangelog} If you use this, the changelog is pulled from the git commit. To save this existing log, write it to a "changelog" file in the repository (https://jcline.fedorapeople.org/new-packages/modulejail-1.6.3-1.fc46.src.rpm has it as an example). |