vms-ff5: sign the OVMX kernel modules — clears TAINT_UNSIGNED_MODULE (E/bit 13) - #539
Merged
Merged
Conversation
…(bit 13/'E') Enable CONFIG_MODULE_SIG=y + CONFIG_MODULE_SIG_ALL=y in the bootable kernel config, embed a committed OVMX signing cert in the built-in trusted keyring (CONFIG_MODULE_SIG_KEY), and sign vms.ko/vmsfs.ko so finit_module() verifies them at load and does NOT set TAINT_UNSIGNED_MODULE. Builds on vms-934's in-tree modules (parent vms-19e "owns-kernel"). CONFIG_MODULE_SIG_FORCE is DELIBERATELY NOT set (vms-ff5 decision): signing is proven first without enforcement so a pipeline slip can never brick the boot. The Dockerfile hard-gates that SIG_FORCE stays off and that SIG/SIG_KEY are on. Key provenance — committed, not ephemeral: the item's "build-ephemeral key is fine to start" is INCOMPATIBLE with vms-d73's cut-release-reproducible gate, which runs on this PR (it touches distro/Dockerfile.bootable) and byte-compares two --no-cache builds of vmlinuz + initramfs. An ephemeral key regenerates randomly per build, changing both the keyring cert in vmlinuz and the module signatures in the initramfs. A committed deterministic key (distro/kernel/ovmx-module-signing-key.pem) keeps every signed byte identical build-to-build. Since SIG_FORCE is off, the key gates nothing at load — it only lets the kernel verify the signature; a public checked-in key is correct here. Proof (Rule 9, real boot): tests/qemu/test_signed_modules.sh mirrors test_intree_modules.sh — static modinfo signature check on the shipped vms.ko/vmsfs.ko, plus a loglevel=7 boot asserting no "module verification failed / signature and/or required key missing" notice (i.e. bit 13 not set), with the vms-934 intree=Y assertions kept green. Wired as its own CI step + boot path filter. The standalone src/kernel OOT build + tests/qemu OOT harness are untouched (no fork). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…h misparse) merge_config.sh extracts the symbol name from any fragment line beginning '# CONFIG_...', so comment lines that started with '# CONFIG_MODULE_SIG...' were misread as directives and printed a spurious 'redefined by fragment' warning. The merged .config was already correct (the Dockerfile gate proved it), but reword so no comment line begins with '# CONFIG_' -- prose refs go mid-line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
baron-3dl
added a commit
that referenced
this pull request
Aug 14, 2026
…s a build secret (#559) GitHub secret-scanning flagged distro/kernel/ovmx-module-signing-key.pem: a real PEM private key (+ self-signed cert) committed on origin/main via #539 (vms-ff5). It was committed deliberately, to keep module-signature bytes reproducible (vms-d73) — but a committed private key is PUBLIC. Anyone with read access can sign a module the OVMX kernel keyring trusts, which defeats the entire purpose of the signing work (and is the exact "reports-verified but anyone-can-forge" LARP class the authenticity invariants exist to kill). Fix — the key is never committed; it is a build input, held fixed only when determinism is needed: - Dockerfile.bootable: the key arrives as the `ovmx_module_signing_key` BuildKit secret; with no secret, an ephemeral key is minted in-stage (the kernel does NOT auto-generate at a custom CONFIG_MODULE_SIG_KEY path). Modules stay signed + verifiable either way; SIG_FORCE stays off. - cut-release.sh: passes OVMX_MODULE_SIGNING_KEY through as --secret when set. - ci.yml cut-release-reproducible: mints ONE job-scoped ephemeral key and feeds it to both cuts, so they stay byte-identical (vms-d73) with no key in git. This is what keeps the reproducibility gate green. - git rm the key; .gitignore it; correct the config/doc comments that called it "committed". The leaked key must be treated as compromised: every future OVMX artifact is signed by a different key, so the leaked one signs nothing we ship (revoked in effect). Purging the dead blob from git history + force-push, and provisioning a persistent secret for third-party-reproducible signed RELEASES, are operator calls left to follow-up. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Signs the in-tree OVMX kernel modules (vms.ko/vmsfs.ko) so loading them no longer sets TAINT_UNSIGNED_MODULE (bit 13 / 'E'). Owns-kernel pole (vms-19e), rel-0.5. Builds directly on vms-934 (in-tree modules, PR #533).
What changed
distro/kernel/ovmx-x86_64.config:CONFIG_MODULE_SIG=y+CONFIG_MODULE_SIG_ALL=y+CONFIG_MODULE_SIG_SHA256=y, withCONFIG_MODULE_SIG_KEY="ovmx-module-signing-key.pem".CONFIG_MODULE_SIG_FORCEdeliberately left off (deferred — sign-but-don't-force, no boot-brick risk).distro/kernel/ovmx-module-signing-key.pem: committed self-signed module-signing key (priv+cert PEM). Its cert is embedded in the kernel's built-in trusted keyring so the kernel auto-verifies the signature at load.distro/Dockerfile.bootable(kernel-build stage): copies the key into the tree before config/build; signs the harvested vms.ko/vmsfs.ko with it (guarded against double-signing); hard-gatesCONFIG_MODULE_SIG=y+ the pinnedSIG_KEY+SIG_FORCEstill off; the shipped-.kore-check now also asserts a signature is present.tests/qemu/test_signed_modules.sh+ CI step + boot path filter: the real-boot taint proof.Why a committed key, not the item's "ephemeral to start"
The ephemeral key the item suggested is incompatible with vms-d73's
cut-release-reproduciblegate, which runs on this PR (it touchesDockerfile.bootable) and byte-compares two--no-cachebuilds ofvmlinuz+initramfs. An ephemeral key regenerates randomly per build → the keyring cert invmlinuzand the module signatures in theinitramfsdiffer → gate RED. A committed deterministic key keeps every signed byte identical. SinceSIG_FORCEis off, the key gates nothing at load — it only lets the kernel verify the signature; a public checked-in key is the correct, necessary choice here. (This promotes the item's "persisted-key follow-up" into this PR.)Proof (Rule 9 / real boot, no userspace fake)
test_signed_modules.shmirrorstest_intree_modules.sh:modinfo -F signer/sig_id/sig_hashalgoon the vms.ko/vmsfs.ko extracted from the actual boot initramfs.loglevel=7, asserts the modules load (%OVMX-I-EXEC,%OVMX-I-MOUNTED) AND nomodule verification failed / signature and/or required key missingnotice → bit 13 not set on the real boot.intree=Y/ no-out-of-tree-taint assertions stay green.The standalone
src/kernelOOT build +tests/qemuOOT harness are untouched (no fork).rd: vms-ff5 (parent vms-19e, blocks vms-566).
🤖 Generated with Claude Code