diff --git a/flake.lock b/flake.lock index 1a212620..a46eb64f 100644 --- a/flake.lock +++ b/flake.lock @@ -1,34 +1,5 @@ { "nodes": { - "crane": { - "inputs": { - "flake-compat": [ - "flake-compat" - ], - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ], - "rust-overlay": [ - "rust-overlay" - ] - }, - "locked": { - "lastModified": 1683505101, - "narHash": "sha256-VBU64Jfu2V4sUR5+tuQS9erBRAe/QEYUxdVMcJGMZZs=", - "owner": "ipetkov", - "repo": "crane", - "rev": "7b5bd9e5acb2bb0cfba2d65f34d8568a894cdb6c", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, "flake-compat": { "flake": false, "locked": { @@ -106,11 +77,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1684077912, - "narHash": "sha256-HNuVjMGmSp3H1MM4ymne3r07ldIB54GgPQViUZjk5Wc=", + "lastModified": 1685071405, + "narHash": "sha256-qENk2wk0Zli0zeLDKMNcs8CfhPIHhtRQgPamlFUM/xw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "57ace723895c43160e102cc126933d8b395391ea", + "rev": "794a24afefde85c3e9b533443c4c73cd871f9e3a", "type": "github" }, "original": { @@ -151,11 +122,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1682596858, - "narHash": "sha256-Hf9XVpqaGqe/4oDGr30W8HlsWvJXtMsEPHDqHZA6dDg=", + "lastModified": 1684842236, + "narHash": "sha256-rYWsIXHvNhVQ15RQlBUv67W3YnM+Pd+DuXGMvCBq2IE=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "fb58866e20af98779017134319b5663b8215d912", + "rev": "61e567d6497bc9556f391faebe5e410e6623217f", "type": "github" }, "original": { @@ -166,36 +137,11 @@ }, "root": { "inputs": { - "crane": "crane", "flake-compat": "flake-compat", "flake-parts": "flake-parts", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", - "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "flake-utils": [ - "flake-utils" - ], - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1684030847, - "narHash": "sha256-z4tOxaN9Cl8C80u6wyZBpPt9A9MbL21fZ3zdB/vG+AU=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "aa1480f16bec7dda3c62b8cdb184c7e823331ba2", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" + "pre-commit-hooks-nix": "pre-commit-hooks-nix" } }, "systems": { diff --git a/flake.nix b/flake.nix index 3df5cc31..b90361b1 100644 --- a/flake.nix +++ b/flake.nix @@ -18,27 +18,13 @@ # avoid having multiple versions in our dependencies. flake-utils.url = "github:numtide/flake-utils"; - crane = { - url = "github:ipetkov/crane"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.rust-overlay.follows = "rust-overlay"; - inputs.flake-utils.follows = "flake-utils"; - inputs.flake-compat.follows = "flake-compat"; - }; - - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs.nixpkgs.follows = "nixpkgs"; - inputs.flake-utils.follows = "flake-utils"; - }; - flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; }; - outputs = inputs@{ self, nixpkgs, crane, rust-overlay, flake-parts, ... }: + outputs = inputs@{ self, nixpkgs, flake-parts, ... }: flake-parts.lib.mkFlake { inherit inputs; } ({ moduleWithSystem, ... }: { imports = [ # Derive the output overlay automatically from all packages that we define. @@ -48,27 +34,20 @@ inputs.pre-commit-hooks-nix.flakeModule ]; - flake.nixosModules.lanzaboote = moduleWithSystem ( - perSystem@{ config }: + flake.nixosModules.lanzaboote = moduleWithSystem (perSystem@{ config }: { ... }: { - imports = [ - ./nix/modules/lanzaboote.nix - ]; + imports = [ ./nix/modules/lanzaboote.nix ]; boot.lanzaboote.package = perSystem.config.packages.tool; - } - ); + }); - flake.nixosModules.uki = moduleWithSystem ( - perSystem@{ config }: + flake.nixosModules.uki = moduleWithSystem (perSystem@{ config }: { lib, ... }: { - imports = [ - ./nix/modules/uki.nix - ]; + imports = [ ./nix/modules/uki.nix ]; - boot.loader.uki.stub = lib.mkDefault "${perSystem.config.packages.fatStub}/bin/lanzaboote_stub.efi"; - } - ); + boot.loader.uki.stub = lib.mkDefault + "${perSystem.config.packages.fatStub}/bin/lanzaboote_stub.efi"; + }); systems = [ "x86_64-linux" @@ -79,94 +58,25 @@ perSystem = { config, system, pkgs, ... }: let - pkgs = import nixpkgs { - system = system; - overlays = [ - rust-overlay.overlays.default - ]; - }; - - inherit (pkgs) lib; - - uefi-rust-stable = pkgs.rust-bin.fromRustupToolchainFile ./rust/stub/rust-toolchain.toml; - craneLib = crane.lib.x86_64-linux.overrideToolchain uefi-rust-stable; - - # Build attributes for a Rust application. - buildRustApp = lib.makeOverridable ( - { src - , target ? null - , doCheck ? true - , extraArgs ? { } - }: - let - commonArgs = { - inherit src; - CARGO_BUILD_TARGET = target; - inherit doCheck; - - # Workaround for https://github.com/ipetkov/crane/issues/262. - dummyrs = pkgs.writeText "dummy.rs" '' - #![allow(unused)] - - #![cfg_attr( - any(target_os = "none", target_os = "uefi"), - no_std, - no_main, - )] - - #[cfg_attr(any(target_os = "none", target_os = "uefi"), panic_handler)] - fn panic(_info: &::core::panic::PanicInfo<'_>) -> ! { - loop {} - } - - #[cfg_attr(any(target_os = "none", target_os = "uefi"), export_name = "efi_main")] - fn main() {} - ''; - } // extraArgs; - - cargoArtifacts = craneLib.buildDepsOnly commonArgs; - in - { - package = craneLib.buildPackage (commonArgs // { - inherit cargoArtifacts; - }); - - clippy = craneLib.cargoClippy (commonArgs // { - inherit cargoArtifacts; - cargoClippyExtraArgs = "-- --deny warnings"; - }); - - rustfmt = craneLib.cargoFmt (commonArgs // { inherit cargoArtifacts; }); - } - ); - - stubCrane = buildRustApp { - src = craneLib.cleanCargoSource ./rust/stub; - target = "x86_64-unknown-uefi"; - doCheck = false; - }; - - fatStubCrane = stubCrane.override { - extraArgs = { - cargoExtraArgs = "--no-default-features --features fat"; + pkgs = import nixpkgs { inherit system; }; + uefiPkgs = import nixpkgs { + inherit system; + crossSystem = { + # linuxArch is wrong here, it will yield arm64 instead of aarch64. + config = "${pkgs.hostPlatform.qemuArch}-windows"; + rustc.config = "${pkgs.hostPlatform.qemuArch}-unknown-uefi"; + libc = null; + useLLVM = true; }; }; + utils = import ./nix/packages/utils.nix; - stub = stubCrane.package; - fatStub = fatStubCrane.package; - - toolCrane = buildRustApp { - src = ./rust/tool; - extraArgs = { - TEST_SYSTEMD = pkgs.systemd; - nativeCheckInputs = with pkgs; [ - binutils-unwrapped - sbsigntool - ]; - }; - }; + inherit (pkgs) lib; - tool = toolCrane.package; + stub = uefiPkgs.callPackage ./nix/packages/stub.nix { }; + fatStub = + uefiPkgs.callPackage ./nix/packages/stub.nix { fatVariant = true; }; + tool = pkgs.callPackage ./nix/packages/tool.nix { }; wrappedTool = pkgs.runCommand "lzbt" { @@ -177,7 +87,9 @@ # Clean PATH to only contain what we need to do objcopy. Also # tell lanzatool where to find our UEFI binaries. makeWrapper ${tool}/bin/lzbt $out/bin/lzbt \ - --set PATH ${lib.makeBinPath [ pkgs.binutils-unwrapped pkgs.sbsigntool ]} \ + --set PATH ${ + lib.makeBinPath [ pkgs.binutils-unwrapped pkgs.sbsigntool ] + } \ --set LANZABOOTE_STUB ${stub}/bin/lanzaboote_stub.efi ''; in @@ -188,24 +100,23 @@ lzbt = wrappedTool; }; - overlayAttrs = { - inherit (config.packages) tool; - }; + overlayAttrs = { inherit (config.packages) tool; }; checks = let nixosLib = import (pkgs.path + "/nixos/lib") { }; - runTest = module: nixosLib.runTest { - imports = [ module ]; - hostPkgs = pkgs; - }; + runTest = module: + nixosLib.runTest { + imports = [ module ]; + hostPkgs = pkgs; + }; in { - toolClippy = toolCrane.clippy; - stubClippy = stubCrane.clippy; - fatStubClippy = fatStubCrane.clippy; - toolFmt = toolCrane.rustfmt; - stubFmt = stubCrane.rustfmt; + stubFmt = uefiPkgs.callPackage (utils.rustfmt stub) { }; + toolFmt = pkgs.callPackage (utils.rustfmt tool) { }; + toolClippy = pkgs.callPackage (utils.clippy tool) { }; + stubClippy = uefiPkgs.callPackage (utils.clippy stub) { }; + fatStubClippy = uefiPkgs.callPackage (utils.clippy fatStub) { }; } // (import ./nix/tests/lanzaboote.nix { inherit pkgs; lanzabooteModule = self.nixosModules.lanzaboote; @@ -236,32 +147,21 @@ export PATH=$PATH:${systemdUkify}/lib/systemd ''; - packages = - let - uefi-run = pkgs.callPackage ./nix/packages/uefi-run.nix { - inherit craneLib; - }; - in - [ - uefi-run - pkgs.openssl - (pkgs.sbctl.override { - databasePath = "pki"; - }) - pkgs.sbsigntool - pkgs.efitools - pkgs.python39Packages.ovmfvartool - pkgs.qemu - pkgs.nixpkgs-fmt - pkgs.statix - pkgs.cargo-release - ]; - - inputsFrom = [ - config.packages.stub - config.packages.tool + packages = [ + pkgs.uefi-run + pkgs.openssl + (pkgs.sbctl.override { databasePath = "pki"; }) + pkgs.sbsigntool + pkgs.efitools + pkgs.python39Packages.ovmfvartool + pkgs.qemu + pkgs.nixpkgs-fmt + pkgs.statix + pkgs.cargo-release ]; + inputsFrom = [ config.packages.stub config.packages.tool ]; + TEST_SYSTEMD = pkgs.systemd; }; }; diff --git a/nix/packages/stub.nix b/nix/packages/stub.nix new file mode 100644 index 00000000..83435a21 --- /dev/null +++ b/nix/packages/stub.nix @@ -0,0 +1,29 @@ +{ rustPlatform, stdenv, lib, fatVariant ? false }: + +rustPlatform.buildRustPackage +{ + pname = "lanzaboote_stub"; + version = "0.3.0"; + src = lib.cleanSource ../../rust/stub; + + # We don't want the thin code. + buildNoDefaultFeatures = true; + buildFeatures = if fatVariant then [ "fat" ] else [ "thin" ]; + + cargoLock = { + lockFile = ../../rust/stub/Cargo.lock; + }; + + # Necessary because our `cc-wrapper` doesn't understand MSVC link options. + RUSTFLAGS = "-Clinker=${stdenv.cc.bintools}/bin/${stdenv.cc.targetPrefix}ld.lld -Clinker-flavor=lld-link"; + # Necessary because otherwise we will get (useless) hardening options in front of + # -flavor link which will break the whole command-line processing for the ld.lld linker. + hardeningDisable = [ "all" ]; + + meta = with lib; { + description = "Lanzaboote UEFI stub for SecureBoot enablement on NixOS systems"; + homepage = "https://github.com/nix-community/lanzaboote"; + license = licenses.mit; + platforms = [ "x86_64-windows" "aarch64-windows" "i686-windows" ]; + }; +} diff --git a/nix/packages/tool.nix b/nix/packages/tool.nix new file mode 100644 index 00000000..ce2faed5 --- /dev/null +++ b/nix/packages/tool.nix @@ -0,0 +1,30 @@ +{ systemd +, binutils-unwrapped +, sbsigntool +, rustPlatform +, lib +}: + +rustPlatform.buildRustPackage +{ + pname = "lanzaboote_tool"; + version = "0.3.0"; + src = lib.cleanSource ../../rust/tool; + + TEST_SYSTEMD = systemd; + + cargoLock = { + lockFile = ../../rust/tool/Cargo.lock; + }; + + nativeCheckInputs = [ + binutils-unwrapped + sbsigntool + ]; + + meta = with lib; { + description = "Lanzaboote UEFI tooling for SecureBoot enablement on NixOS systems"; + homepage = "https://github.com/nix-community/lanzaboote"; + license = licenses.mit; + }; +} diff --git a/nix/packages/uefi-run.nix b/nix/packages/uefi-run.nix deleted file mode 100644 index 4f13d6b1..00000000 --- a/nix/packages/uefi-run.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ fetchFromGitHub, craneLib, makeWrapper, OVMF, qemu }: -craneLib.buildPackage { - src = fetchFromGitHub { - owner = "Richard-W"; - repo = "uefi-run"; - - rev = "8ba33c934525458a784a6620705bcf46c3ca91d2"; - sha256 = "fwzWdOinW/ECVI/65pPB1shxPdl2nZThAqlg8wlWg/g="; - }; - - nativeBuildInputs = [ makeWrapper ]; - - postInstall = '' - # The hook runs for the dependency-only derivation where the binary is not - # produced. We need to skip it there. - if [ -f $out/bin/uefi-run ]; then - wrapProgram "$out/bin/uefi-run" \ - --add-flags '--bios-path ${OVMF.fd}/FV/OVMF.fd --qemu-path ${qemu}/bin/qemu-system-x86_64' - fi - ''; -} diff --git a/nix/packages/utils.nix b/nix/packages/utils.nix new file mode 100644 index 00000000..a5b0e562 --- /dev/null +++ b/nix/packages/utils.nix @@ -0,0 +1,39 @@ +{ + clippy = rustPackage: { lib, rust, clippy }: + let + targetSpec = rust.toRustTargetSpec rustPackage.stdenv.hostPlatform; + inherit (lib) optionalString concatStringsSep; + in + rustPackage.overrideAttrs (old: { + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ clippy ]; + + doCheck = false; + + buildPhase = '' + echo "checking via clippy..." + cargo clippy --target ${targetSpec} ${optionalString (old.buildNoDefaultFeatures or false) "--no-default-features "}${optionalString ((old.buildFeatures or null) != null) ''--features="${concatStringsSep " " old.buildFeatures}" ''}-- -D warnings + if grep -R 'dbg!' ./src; then + echo "use of dbg macro found in code!" + false + fi + ''; + + installPhase = '' + touch $out + ''; + }); + rustfmt = rustPackage: { rustfmt }: rustPackage.overrideAttrs (old: { + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ rustfmt ]; + + doCheck = false; + + buildPhase = '' + echo "checking formatting..." + cargo fmt --all -- --check + ''; + + installPhase = '' + touch $out + ''; + }); +}