From ec02a76ff51822a6ad78f50988b432bc9e4949a9 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Mon, 21 Oct 2024 16:14:51 -0400 Subject: [PATCH 1/3] chroot-realpath: init Now it's placed between initrd-switch-root.target and initrd-switch-root.service, meaning it is truly the last thing to happen before switch-root, as it should be. --- pkgs/by-name/ch/chroot-realpath/package.nix | 21 ++++++++++++++++ .../by-name/ch/chroot-realpath/src/Cargo.lock | 7 ++++++ .../by-name/ch/chroot-realpath/src/Cargo.toml | 9 +++++++ .../ch/chroot-realpath/src/src/main.rs | 24 +++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 pkgs/by-name/ch/chroot-realpath/package.nix create mode 100644 pkgs/by-name/ch/chroot-realpath/src/Cargo.lock create mode 100644 pkgs/by-name/ch/chroot-realpath/src/Cargo.toml create mode 100644 pkgs/by-name/ch/chroot-realpath/src/src/main.rs diff --git a/pkgs/by-name/ch/chroot-realpath/package.nix b/pkgs/by-name/ch/chroot-realpath/package.nix new file mode 100644 index 000000000000..af537cb48e45 --- /dev/null +++ b/pkgs/by-name/ch/chroot-realpath/package.nix @@ -0,0 +1,21 @@ +{ + lib, + rustPlatform, +}: + +let + cargo = lib.importTOML ./src/Cargo.toml; +in +rustPlatform.buildRustPackage { + pname = cargo.package.name; + version = cargo.package.version; + + src = ./src; + + cargoLock.lockFile = ./src/Cargo.lock; + + meta = { + description = "Output a path's realpath within a chroot."; + maintainers = [ lib.maintainers.elvishjerricco ]; + }; +} diff --git a/pkgs/by-name/ch/chroot-realpath/src/Cargo.lock b/pkgs/by-name/ch/chroot-realpath/src/Cargo.lock new file mode 100644 index 000000000000..d00f13df1877 --- /dev/null +++ b/pkgs/by-name/ch/chroot-realpath/src/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "chroot-realpath" +version = "0.1.0" diff --git a/pkgs/by-name/ch/chroot-realpath/src/Cargo.toml b/pkgs/by-name/ch/chroot-realpath/src/Cargo.toml new file mode 100644 index 000000000000..52348e7596e9 --- /dev/null +++ b/pkgs/by-name/ch/chroot-realpath/src/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "chroot-realpath" +version = "0.1.0" +edition = "2021" + +[dependencies] + +[profile.release] +opt-level = "z" diff --git a/pkgs/by-name/ch/chroot-realpath/src/src/main.rs b/pkgs/by-name/ch/chroot-realpath/src/src/main.rs new file mode 100644 index 000000000000..4e7873bf0798 --- /dev/null +++ b/pkgs/by-name/ch/chroot-realpath/src/src/main.rs @@ -0,0 +1,24 @@ +use std::env; +use std::io::{stdout, Error, ErrorKind, Write}; +use std::os::unix::ffi::OsStrExt; +use std::os::unix::fs; + +fn main() -> std::io::Result<()> { + let args: Vec = env::args().collect(); + + if args.len() != 3 { + return Err(Error::new( + ErrorKind::InvalidInput, + format!("Usage: {} ", args[0]), + )); + } + + fs::chroot(&args[1])?; + std::env::set_current_dir("/")?; + + let path = std::fs::canonicalize(&args[2])?; + + stdout().write_all(path.into_os_string().as_bytes())?; + + Ok(()) +} From f065a81ab496a43b864398107754257bcd756fce Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Mon, 21 Oct 2024 16:14:51 -0400 Subject: [PATCH 2/3] nixos/systemd-stage-1: Use chroot-realpath --- nixos/modules/system/boot/systemd/initrd.nix | 7 +++++-- nixos/modules/system/etc/etc-activation.nix | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index 1915fef59cc4..e7c5c81770a1 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -482,6 +482,9 @@ in { # so NSS can look up usernames "${pkgs.glibc}/lib/libnss_files.so.2" + + # Resolving sysroot symlinks without code exec + "${pkgs.chroot-realpath}/bin/chroot-realpath" ] ++ optionals cfg.package.withCryptsetup [ # fido2 support "${cfg.package}/lib/cryptsetup/libcryptsetup-token-systemd-fido2.so" @@ -522,7 +525,7 @@ in { script = /* bash */ '' set -uo pipefail - export PATH="/bin:${cfg.package.util-linux}/bin" + export PATH="/bin:${cfg.package.util-linux}/bin:${pkgs.chroot-realpath}/bin" # Figure out what closure to boot closure= @@ -543,7 +546,7 @@ in { # Resolve symlinks in the init parameter. We need this for some boot loaders # (e.g. boot.loader.generationsDir). - closure="$(chroot /sysroot ${pkgs.coreutils}/bin/realpath "$closure")" + closure="$(chroot-realpath /sysroot "$closure")" # Assume the directory containing the init script is the closure. closure="$(dirname "$closure")" diff --git a/nixos/modules/system/etc/etc-activation.nix b/nixos/modules/system/etc/etc-activation.nix index 944920e92335..733166a9175e 100644 --- a/nixos/modules/system/etc/etc-activation.nix +++ b/nixos/modules/system/etc/etc-activation.nix @@ -139,10 +139,10 @@ closure="$(realpath /nixos-closure)" - metadata_image="$(chroot /sysroot ${lib.getExe' pkgs.coreutils "realpath"} "$closure/etc-metadata-image")" + metadata_image="$(${pkgs.chroot-realpath}/bin/chroot-realpath /sysroot "$closure/etc-metadata-image")" ln -s "/sysroot$metadata_image" /etc-metadata-image - basedir="$(chroot /sysroot ${lib.getExe' pkgs.coreutils "realpath"} "$closure/etc-basedir")" + basedir="$(${pkgs.chroot-realpath}/bin/chroot-realpath /sysroot "$closure/etc-basedir")" ln -s "/sysroot$basedir" /etc-basedir ''; }; From 6cfd95fc8ca6fe7cf46c43c81f670869a1929333 Mon Sep 17 00:00:00 2001 From: Will Fancher Date: Tue, 15 Oct 2024 13:35:50 -0400 Subject: [PATCH 3/3] nixos/systemd-stage-1: Order nixos activation after initrd-switch-root.target Now it's placed between initrd-switch-root.target and initrd-switch-root.service, meaning it is truly the last thing to happen before switch-root, as it should be. --- nixos/modules/system/boot/systemd/initrd.nix | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index e7c5c81770a1..e3fadf592925 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -581,14 +581,10 @@ in { ]; services.initrd-nixos-activation = { - requires = [ - config.boot.initrd.systemd.services.initrd-find-nixos-closure.name - ]; - after = [ - "initrd-fs.target" - config.boot.initrd.systemd.services.initrd-find-nixos-closure.name - ]; - requiredBy = [ "initrd.target" ]; + after = [ "initrd-switch-root.target" ]; + requiredBy = [ "initrd-switch-root.service" ]; + before = [ "initrd-switch-root.service" ]; + unitConfig.DefaultDependencies = false; unitConfig = { AssertPathExists = "/etc/initrd-release"; RequiresMountsFor = [