From a689fa9925e76da6000a171764c14f25a43cce60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Fri, 21 Feb 2025 12:22:21 +0100 Subject: [PATCH 01/67] chore: rootfs pkg --- flake.nix | 1 + rootfs/default.nix | 30 +++++++++++++++++++++++++ rootfs/mkrootfs.sh | 54 +++++++++++++++++++++++++++++++++++++++++++++ utils/mkinitrd.nix | 55 +++++----------------------------------------- 4 files changed, 90 insertions(+), 50 deletions(-) create mode 100644 rootfs/default.nix create mode 100644 rootfs/mkrootfs.sh diff --git a/flake.nix b/flake.nix index 221d203..90fe634 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,7 @@ glibc = pkgs.callPackage ./glibc { }; systemd = pkgs.callPackage ./systemd { }; dbus-broker = pkgs.callPackage ./dbus-broker { }; + rootfs = pkgs.callPackage ./rootfs { inherit patosPkgs; }; mkinitrd = pkgs.callPackage ./utils/mkinitrd.nix { inherit patosPkgs; }; qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { }; diff --git a/rootfs/default.nix b/rootfs/default.nix new file mode 100644 index 0000000..755050f --- /dev/null +++ b/rootfs/default.nix @@ -0,0 +1,30 @@ +{ + pkgs, + stdenvNoCC, + patosPkgs, + ... +}: +let + version = "0.0.1"; + pname = "patos-rootfs"; +in +stdenvNoCC.mkDerivation (finalAttrs: { + inherit version; + inherit pname; + + buildInputs = with pkgs; [ + glibc + binutils + ]; + + glibcPatos = patosPkgs.glibc.out; + systemd = patosPkgs.systemd.out; + dbusBroker = patosPkgs.dbus-broker.out; + kernel = patosPkgs.kernel.kernel; + busybox = pkgs.busybox.out; + kmodLibs = pkgs.kmod.lib; + kmodBin = pkgs.kmod.out; + libbpf = pkgs.libbpf.out; + + builder = ./mkrootfs.sh; +}) diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh new file mode 100644 index 0000000..b850129 --- /dev/null +++ b/rootfs/mkrootfs.sh @@ -0,0 +1,54 @@ +set -ex -o pipefail + +mkdir -p $out +mkdir -p $out/etc $out/dev $out/proc $out/sys $out/tmp $out/root +ln -sf ../usr/bin $out/bin +ln -sf ../usr/bin $out/sbin +ln -sf ../usr/lib $out/lib +ln -sf ../usr/lib $out/lib64 +ln -sf ../proc/self/mounts $out/etc/mtab + +### install systemd +echo "Installing systemd" +cp -Pr $systemd/* $out/ +find $out -type d -exec chmod 755 {} \; +rm -rf $out/usr/include +rm -rf $out/usr/sbin +rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service +# remove vconsole setup +rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules + +### install PatOS glibc +cp -P $glibcPatos/lib/*.so* $out/usr/lib/ + +### install kernel modules +cp -r $kernel/lib/modules $out/usr/lib/ +find $out/usr/lib/modules -type d -exec chmod 755 {} \; + +### install busybox +cp $busybox/bin/busybox $out/usr/bin/ +$out/usr/bin/busybox --list | xargs -I {} ln -sf busybox $out/usr/bin/{} + +### install dbus broker +cp -r $dbusBroker/* $out/ + +### install lib kmod +cp -P $kmodLibs/lib/* $out/usr/lib +cp -P $kmodBin/bin/* $out/usr/bin + +### install libbpf +cp -P $libbpf/lib/libbpf* $out/usr/lib + +### Find and install all shared libs +find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | sort -u | xargs cp -t $out/usr/lib +find $out -type f -executable -exec chmod 755 {} \; + +# FIXME: ELF patching. Is there a better way? +find $out -type f -executable -exec patchelf --set-rpath /lib:/usr/lib:/usr/lib/systemd {} \; +find $out -type f -executable -exec patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 {} \; +patchelf --remove-rpath $out/usr/lib/ld-linux-x86-64.so.2 + +# strip binaries +find $out -type f -executable -exec strip {} \; +find $out -type d -exec chmod 755 {} \; + diff --git a/utils/mkinitrd.nix b/utils/mkinitrd.nix index 0bd234c..47f7f30 100644 --- a/utils/mkinitrd.nix +++ b/utils/mkinitrd.nix @@ -7,7 +7,6 @@ pkgs.writeShellApplication { name = "mkinitrd"; runtimeInputs = with pkgs; [ - patchelf cpio gzip ]; @@ -17,56 +16,21 @@ pkgs.writeShellApplication { mkdir -p root pushd root + ### copy rootfs + cp -prP ${patosPkgs.rootfs}/* . + find . -type d -exec chmod 755 {} \; + ### create directories - mkdir -p etc dev proc sys tmp root - ln -sf usr/bin bin - ln -sf usr/bin sbin - ln -sf usr/lib lib - ln -sf usr/lib lib64 - ln -sf ../proc/self/mounts etc/mtab ln -sf ../usr/lib/systemd/systemd init - ### install systemd - cp -Pr ${patosPkgs.systemd.out}/* ./ - find . -type d -exec chmod 755 {} \; - rm -rf ./usr/include - rm -rf ./usr/sbin # set default target to basic mkdir usr/lib/systemd/system/basic.target.wants ln -sf basic.target usr/lib/systemd/system/default.target - # remove first boot - rm -f usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service - # remove vconsole setup - rm -f usr/lib/udev/rules.d/90-vconsole.rules - ### install PatOS glibc - cp -Pr ${patosPkgs.glibc.out}/lib/*.so* ./usr/lib/ - - ### install kernel modules - cp -Pr ${patosPkgs.kernel.kernel}/lib/modules ./usr/lib/ - find usr/lib/modules -type d -exec chmod 755 {} \; - - ### install busybox - cp ${pkgs.busybox.out}/bin/busybox ./usr/bin/ - usr/bin/busybox --list | xargs -I {} ln -sf busybox usr/bin/{} - - ### install dbus broker - cp -r ${patosPkgs.dbus-broker.out}/* ./ + # enable dbus broker ln -sf ../dbus-broker.service usr/lib/systemd/system/basic.target.wants/dbus.service ln -sf ../dbus.socket usr/lib/systemd/system/sockets.target.wants/dbus.socket - ### install lib kmod - cp -P ${pkgs.kmod.lib}/lib/* ./usr/lib - cp -P ${pkgs.kmod.out}/bin/* ./usr/bin - - ### install libbpf - cp -P ${pkgs.libbpf.out}/lib/libbpf* ./usr/lib - - ### Find and install all shared libs - find . -type f -executable -exec ldd {} \; 2> /dev/null | awk '{print $3}' | grep -v systemd | grep -v glibc | sort -u | xargs cp -t usr/lib - find . -type f -executable -exec chmod 755 {} \; - - ### Create needed files echo patos > ./etc/hostname cat <<EOF > ./etc/os-release @@ -152,15 +116,6 @@ pkgs.writeShellApplication { EOF ln -sf ../demo.service usr/lib/systemd/system/basic.target.wants/demo.service - # FIXME: ELF patching. Is there a better way? - find . -type f -executable -exec patchelf --set-rpath /lib:/usr/lib:/usr/lib/systemd {} \; 2> /dev/null - find . -type f -executable -exec patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 {} \; 2> /dev/null - patchelf --remove-rpath ./usr/lib/ld-linux-x86-64.so.2 - - # strip binaries - find . -type f -executable -exec strip {} \; 2> /dev/null - find . -type d -exec chmod 755 {} \; - # gen initrd find . -print0 | cpio --null --owner=root:root -o --format=newc | gzip -9 > ../initrd.gz From 9ff916d0a3fbdc615b4fc989da26b2b082992efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 24 Feb 2025 09:14:11 +0100 Subject: [PATCH 02/67] chore: xz compressed initrd and remove systemd patch --- .gitignore | 3 ++- flake.nix | 2 +- ....build-do-not-create-systemdstatedir.patch | 21 ------------------- systemd/default.nix | 6 +----- utils/mkinitrd.nix | 4 ++-- 5 files changed, 6 insertions(+), 30 deletions(-) delete mode 100644 systemd/0017-meson.build-do-not-create-systemdstatedir.patch diff --git a/.gitignore b/.gitignore index 6833589..8cfe0d4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,8 @@ /result /target /out -/initrd.gz +/initrd* +/patos* .*.swp .*.swo .nixos-test-history diff --git a/flake.nix b/flake.nix index 90fe634..9e95404 100644 --- a/flake.nix +++ b/flake.nix @@ -28,7 +28,7 @@ mkdir -p patos/efi/boot ${self.packages.${system}.systemd.out}/usr/bin/ukify build \ --linux ${self.packages.${system}.kernel.kernel}/bzImage \ - --initrd ./initrd.gz \ + --initrd ./initrd.xz \ --cmdline "console=ttyS0" \ -o patos/efi/boot/bootx64.efi ''; diff --git a/systemd/0017-meson.build-do-not-create-systemdstatedir.patch b/systemd/0017-meson.build-do-not-create-systemdstatedir.patch deleted file mode 100644 index debcaab..0000000 --- a/systemd/0017-meson.build-do-not-create-systemdstatedir.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: nikstur <nikstur@outlook.com> -Date: Mon, 6 Nov 2023 22:51:38 +0100 -Subject: [PATCH] meson.build: do not create systemdstatedir - ---- - meson.build | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/meson.build b/meson.build -index bffda86845..cb5dcec0f9 100644 ---- a/meson.build -+++ b/meson.build -@@ -2781,7 +2781,6 @@ install_data('LICENSE.GPL2', - install_subdir('LICENSES', - install_dir : docdir) - --install_emptydir(systemdstatedir) - - ##################################################################### - diff --git a/systemd/default.nix b/systemd/default.nix index 3174f0f..4daf9ed 100644 --- a/systemd/default.nix +++ b/systemd/default.nix @@ -32,10 +32,6 @@ stdenv.mkDerivation (finalAttrs: { dontCheckForBrokenSymlinks = true; - patches = [ - ./0017-meson.build-do-not-create-systemdstatedir.patch - ]; - nativeBuildInputs = with pkgs; [ bash pkg-config @@ -196,7 +192,7 @@ stdenv.mkDerivation (finalAttrs: { (lib.mesonOption "dbussystemservicedir" "/usr/share/dbus-1/system-services") (lib.mesonOption "setfont-path" "/usr/bin/setfont") (lib.mesonOption "loadkeys-path" "/usr/bin/loadkeys") - (lib.mesonOption "sulogin-path" "/usr/bin/sulogin") + (lib.mesonOption "sulogin-path" "/usr/bin/sulogin") (lib.mesonOption "nologin-path" "/usr/bin/nologin") (lib.mesonOption "mount-path" "/usr/bin/mount") (lib.mesonOption "umount-path" "/usr/bin/umount") diff --git a/utils/mkinitrd.nix b/utils/mkinitrd.nix index 47f7f30..201d14c 100644 --- a/utils/mkinitrd.nix +++ b/utils/mkinitrd.nix @@ -8,7 +8,7 @@ pkgs.writeShellApplication { runtimeInputs = with pkgs; [ cpio - gzip + xz ]; text = '' @@ -117,7 +117,7 @@ pkgs.writeShellApplication { ln -sf ../demo.service usr/lib/systemd/system/basic.target.wants/demo.service # gen initrd - find . -print0 | cpio --null --owner=root:root -o --format=newc | gzip -9 > ../initrd.gz + find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz popd rm -rf root From e7470498e5d109c044e52868c192076892cdb371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 24 Feb 2025 15:01:03 +0100 Subject: [PATCH 03/67] fix: create derivation for initrd creation --- flake.nix | 8 +-- rootfs/mkinitrd.nix | 23 ++++++++ rootfs/mkinitrd.sh | 110 ++++++++++++++++++++++++++++++++++++++ utils/mkinitrd.nix | 125 -------------------------------------------- 4 files changed, 137 insertions(+), 129 deletions(-) create mode 100644 rootfs/mkinitrd.nix create mode 100644 rootfs/mkinitrd.sh delete mode 100644 utils/mkinitrd.nix diff --git a/flake.nix b/flake.nix index 9e95404..146376c 100644 --- a/flake.nix +++ b/flake.nix @@ -26,9 +26,9 @@ echo "make UKI..." mkdir -p patos/efi/boot - ${self.packages.${system}.systemd.out}/usr/bin/ukify build \ - --linux ${self.packages.${system}.kernel.kernel}/bzImage \ - --initrd ./initrd.xz \ + ${patosPkgs.systemd.out}/usr/bin/ukify build \ + --linux ${patosPkgs.kernel.kernel}/bzImage \ + --initrd ${patosPkgs.initrd.out}/initrd.xz \ --cmdline "console=ttyS0" \ -o patos/efi/boot/bootx64.efi ''; @@ -38,8 +38,8 @@ systemd = pkgs.callPackage ./systemd { }; dbus-broker = pkgs.callPackage ./dbus-broker { }; rootfs = pkgs.callPackage ./rootfs { inherit patosPkgs; }; + initrd = pkgs.callPackage ./rootfs/mkinitrd.nix { inherit patosPkgs; }; - mkinitrd = pkgs.callPackage ./utils/mkinitrd.nix { inherit patosPkgs; }; qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { }; }; diff --git a/rootfs/mkinitrd.nix b/rootfs/mkinitrd.nix new file mode 100644 index 0000000..f564813 --- /dev/null +++ b/rootfs/mkinitrd.nix @@ -0,0 +1,23 @@ +{ + pkgs, + stdenvNoCC, + patosPkgs, + ... +}: +let + version = "0.0.1"; + pname = "patos-ramdisk"; +in +stdenvNoCC.mkDerivation (finalAttrs: { + inherit version; + inherit pname; + + buildInputs = with pkgs; [ + cpio + xz + ]; + + rootfs = patosPkgs.rootfs.out; + + builder = ./mkinitrd.sh; +}) diff --git a/rootfs/mkinitrd.sh b/rootfs/mkinitrd.sh new file mode 100644 index 0000000..2fe7770 --- /dev/null +++ b/rootfs/mkinitrd.sh @@ -0,0 +1,110 @@ +set -ex -p pipefail +echo "Building initram disk" +mkdir -p $out/root +pushd $out/root + +### copy rootfs +cp -prP $rootfs/* . +find . -type d -exec chmod 755 {} \; + +### create directories +ln -sf ../usr/lib/systemd/systemd init + +# set default target to basic +mkdir usr/lib/systemd/system/basic.target.wants +ln -sf basic.target usr/lib/systemd/system/default.target + +# enable dbus broker +ln -sf ../dbus-broker.service usr/lib/systemd/system/basic.target.wants/dbus-broker.service +ln -sf ../dbus.socket usr/lib/systemd/system/sockets.target.wants/dbus.socket + +### Create needed files +echo patos > ./etc/hostname +cat <<EOF > ./etc/os-release +NAME="PatOS" +PRETTY_NAME="PatOS Platform" +ID=patos +EOF + +cat <<EOF > ./etc/passwd +root::0:0:root:/root:/bin/sh +bin:x:1:1:bin:/bin:/usr/bin/nologin +daemon:x:2:2:daemon:/:/usr/bin/nologin +mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin +ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin +http:x:33:33:http:/srv/http:/usr/bin/nologin +uuidd:x:68:68:uuidd:/:/usr/bin/nologin +messagebus:x:81:81:messagebus:/:/usr/bin/nologin +nobody:x:99:99:nobody:/:/usr/bin/nologin +EOF +chmod 644 ./etc/passwd + +cat <<EOF > ./etc/group +root:x:0:root +bin:x:1:root,bin,daemon +daemon:x:2:root,bin,daemon +sys:x:3:root,bin +adm:x:4:root,daemon +tty:x:5: +disk:x:6:root +lp:x:7:daemon +mem:x:8: +kmem:x:9: +wheel:x:10:root +ftp:x:11: +mail:x:12: +uucp:x:14: +log:x:19:root +utmp:x:20: +locate:x:21: +rfkill:x:24: +smmsp:x:25: +proc:x:26: +http:x:33: +games:x:50: +lock:x:54: +uuidd:x:68: +messagebus:x:81: +network:x:90: +video:x:91: +audio:x:92: +optical:x:93: +floppy:x:94: +storage:x:95: +scanner:x:96: +input:x:97: +power:x:98: +nobody:x:99: +EOF +chmod 644 ./etc/group + +# FIXME: remove this later (just to get a shell in the initramfs) +cat <<EOF > usr/lib/systemd/system/demo.service +[Unit] +Description=Debug Shell (/bin/sulogin) +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStart=/bin/sulogin +Type=idle +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +SendSIGHUP=yes +Restart=always + +[Install] +WantedBy=basic.target +EOF +ln -sf ../demo.service usr/lib/systemd/system/basic.target.wants/demo.service + +# gen initrd +find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz + +popd +rm -rf $out/root diff --git a/utils/mkinitrd.nix b/utils/mkinitrd.nix deleted file mode 100644 index 201d14c..0000000 --- a/utils/mkinitrd.nix +++ /dev/null @@ -1,125 +0,0 @@ -{ - pkgs, - patosPkgs, - ... -}: -pkgs.writeShellApplication { - name = "mkinitrd"; - - runtimeInputs = with pkgs; [ - cpio - xz - ]; - - text = '' - echo "Building initram disk" - mkdir -p root - pushd root - - ### copy rootfs - cp -prP ${patosPkgs.rootfs}/* . - find . -type d -exec chmod 755 {} \; - - ### create directories - ln -sf ../usr/lib/systemd/systemd init - - # set default target to basic - mkdir usr/lib/systemd/system/basic.target.wants - ln -sf basic.target usr/lib/systemd/system/default.target - - # enable dbus broker - ln -sf ../dbus-broker.service usr/lib/systemd/system/basic.target.wants/dbus.service - ln -sf ../dbus.socket usr/lib/systemd/system/sockets.target.wants/dbus.socket - - ### Create needed files - echo patos > ./etc/hostname - cat <<EOF > ./etc/os-release - NAME="PatOS" - PRETTY_NAME="PatOS Platform" - ID=patos - EOF - - cat <<EOF > ./etc/passwd - root::0:0:root:/root:/bin/sh - bin:x:1:1:bin:/bin:/usr/bin/nologin - daemon:x:2:2:daemon:/:/usr/bin/nologin - mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin - ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin - http:x:33:33:http:/srv/http:/usr/bin/nologin - uuidd:x:68:68:uuidd:/:/usr/bin/nologin - messagebus:x:81:81:messagebus:/:/usr/bin/nologin - nobody:x:99:99:nobody:/:/usr/bin/nologin - EOF - chmod 644 ./etc/passwd - - cat <<EOF > ./etc/group - root:x:0:root - bin:x:1:root,bin,daemon - daemon:x:2:root,bin,daemon - sys:x:3:root,bin - adm:x:4:root,daemon - tty:x:5: - disk:x:6:root - lp:x:7:daemon - mem:x:8: - kmem:x:9: - wheel:x:10:root - ftp:x:11: - mail:x:12: - uucp:x:14: - log:x:19:root - utmp:x:20: - locate:x:21: - rfkill:x:24: - smmsp:x:25: - proc:x:26: - http:x:33: - games:x:50: - lock:x:54: - uuidd:x:68: - messagebus:x:81: - network:x:90: - video:x:91: - audio:x:92: - optical:x:93: - floppy:x:94: - storage:x:95: - scanner:x:96: - input:x:97: - power:x:98: - nobody:x:99: - EOF - chmod 644 ./etc/group - - # FIXME: remove this later (just to get a shell in the initramfs) - cat <<EOF > usr/lib/systemd/system/demo.service - [Unit] - Description=Debug Shell (/bin/sulogin) - Conflicts=shutdown.target - Before=shutdown.target - - [Service] - Environment=HOME=/root - WorkingDirectory=/root - ExecStart=/bin/sulogin - Type=idle - StandardInput=tty-force - StandardOutput=inherit - StandardError=inherit - KillMode=process - IgnoreSIGPIPE=no - SendSIGHUP=yes - Restart=always - - [Install] - WantedBy=basic.target - EOF - ln -sf ../demo.service usr/lib/systemd/system/basic.target.wants/demo.service - - # gen initrd - find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz - - popd - rm -rf root - ''; -} From af78f1c930fa6788a81b229ddf608798a1594819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 24 Feb 2025 16:13:43 +0100 Subject: [PATCH 04/67] feat(systemd-repart): build image --- .gitignore | 2 -- flake.nix | 14 +---------- image/default.nix | 27 +++++++++++++++++++++ image/mkimage.sh | 52 +++++++++++++++++++++++++++++++++++++++++ utils/qemu-uefi-tpm.nix | 5 ++-- 5 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 image/default.nix create mode 100644 image/mkimage.sh diff --git a/.gitignore b/.gitignore index 8cfe0d4..97ab6ac 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,6 @@ /result /target /out -/initrd* -/patos* .*.swp .*.swo .nixos-test-history diff --git a/flake.nix b/flake.nix index 146376c..2e4eafa 100644 --- a/flake.nix +++ b/flake.nix @@ -21,18 +21,7 @@ { packages = { default = self.packages.${system}.image; - image = pkgs.writeShellScriptBin "image" '' - set -ex - echo "make UKI..." - - mkdir -p patos/efi/boot - ${patosPkgs.systemd.out}/usr/bin/ukify build \ - --linux ${patosPkgs.kernel.kernel}/bzImage \ - --initrd ${patosPkgs.initrd.out}/initrd.xz \ - --cmdline "console=ttyS0" \ - -o patos/efi/boot/bootx64.efi - ''; - + image = pkgs.callPackage ./image { inherit patosPkgs; }; kernel = pkgs.callPackage ./kernel { }; glibc = pkgs.callPackage ./glibc { }; systemd = pkgs.callPackage ./systemd { }; @@ -60,7 +49,6 @@ nixfmt-rfc-style squashfs-tools-ng self.packages.${system}.qemu-uefi-tpm - self.packages.${system}.mkinitrd ]; }; diff --git a/image/default.nix b/image/default.nix new file mode 100644 index 0000000..b4394c2 --- /dev/null +++ b/image/default.nix @@ -0,0 +1,27 @@ +{ + pkgs, + stdenvNoCC, + patosPkgs, + ... +}: +let + version = "0.0.1"; + pname = "patos-image"; +in +stdenvNoCC.mkDerivation (finalAttrs: { + inherit version; + inherit pname; + + buildInputs = with pkgs; [ + erofs-utils + dosfstools + mtools + ]; + + systemd = patosPkgs.systemd.out; + kernel = patosPkgs.kernel.kernel; + initrd = patosPkgs.initrd.out; + rootfs = patosPkgs.rootfs.out; + + builder = ./mkimage.sh; +}) diff --git a/image/mkimage.sh b/image/mkimage.sh new file mode 100644 index 0000000..c7473d7 --- /dev/null +++ b/image/mkimage.sh @@ -0,0 +1,52 @@ +set -ex -o pipefail + +mkdir -p $out/repart.d $out/boot +pushd $out + +# Don't seem to work just to create a symlink to rootfs derivation? +# ln -sf $rootfs rootfs +mkdir rootfs +cp -prP $rootfs/* rootfs/ +find rootfs/ -type d -exec chmod 755 {} \; + +$systemd/usr/bin/ukify build \ + --os-release rootfs/etc/os-release \ + --linux $kernel/bzImage \ + --initrd $initrd/initrd.xz \ + --cmdline "console=ttyS0" \ + -o boot/patos-x64.efi + +cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ + +cat <<EOF > repart.d/10-esp.conf +[Partition] +Type=esp +Format=vfat +SizeMinBytes=96M +SizeMaxBytes=96M +SplitName=- +CopyFiles=/boot/patos-x64.efi:/EFI/Linux/patos-x64.efi +CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI +EOF + +cat <<EOF > repart.d/10-root.conf +[Partition] +Type=root +Format=erofs +CopyFiles=/rootfs:/ +Minimize=best +SplitName=root +EOF + +$systemd/usr/bin/systemd-repart \ + --no-pager \ + --empty=create \ + --size=1G \ + --definitions=./repart.d \ + --root=$out \ + patos-$version.raw + +rm -rf rootfs +rm -rf boot + +popd diff --git a/utils/qemu-uefi-tpm.nix b/utils/qemu-uefi-tpm.nix index e6a27f9..d05fbb2 100644 --- a/utils/qemu-uefi-tpm.nix +++ b/utils/qemu-uefi-tpm.nix @@ -19,7 +19,7 @@ pkgs.writeShellApplication { state="/tmp/patos-qemu-$USER" rm -rf "$state" mkdir -m 700 "$state" - truncate -s 1G "$state/disk.raw" + qemu-img create -f qcow2 -F raw -b "$(readlink -e "$1")" "$state/disk.qcow2" 2G swtpm socket -d --tpmstate dir="$state" \ --ctrl type=unixio,path="$state/swtpm-sock" \ @@ -44,7 +44,6 @@ pkgs.writeShellApplication { -device tpm-tis,tpmdev=tpm0 \ -netdev id=net00,type=user,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=net00 \ - -drive "file=fat:rw:patos/,format=raw" \ - -drive "format=raw,file=$state/disk.raw" + -drive "format=qcow2,file=$state/disk.qcow2" ''; } From 6899203860db2e2f24724089d74adde6a341aa74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 24 Feb 2025 23:51:46 +0100 Subject: [PATCH 05/67] feat(systemd-repart): fix ESP. now its booting --- image/default.nix | 4 ++++ image/mkimage.sh | 10 +++++++--- utils/qemu-uefi-tpm.nix | 1 - 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/image/default.nix b/image/default.nix index b4394c2..3d7049b 100644 --- a/image/default.nix +++ b/image/default.nix @@ -18,6 +18,10 @@ stdenvNoCC.mkDerivation (finalAttrs: { mtools ]; + env = { + SYSTEMD_REPART_MKFS_OPTIONS_VFAT = "-S 512 -c"; + }; + systemd = patosPkgs.systemd.out; kernel = patosPkgs.kernel.kernel; initrd = patosPkgs.initrd.out; diff --git a/image/mkimage.sh b/image/mkimage.sh index c7473d7..2ec259f 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -18,15 +18,19 @@ $systemd/usr/bin/ukify build \ cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ +echo "timeout 1" > boot/loader.conf +echo -e "title PatOS Platform\nefi /EFI/Linux/patos-linux.efi" > boot/patos.conf + cat <<EOF > repart.d/10-esp.conf [Partition] Type=esp Format=vfat SizeMinBytes=96M SizeMaxBytes=96M -SplitName=- -CopyFiles=/boot/patos-x64.efi:/EFI/Linux/patos-x64.efi CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI +CopyFiles=/boot/patos-x64.efi:/EFI/Linux/patos-linux.efi +CopyFiles=/boot/loader.conf:/loader/loader.conf +CopyFiles=/boot/patos.conf:/loader/entries/patos.conf EOF cat <<EOF > repart.d/10-root.conf @@ -41,7 +45,7 @@ EOF $systemd/usr/bin/systemd-repart \ --no-pager \ --empty=create \ - --size=1G \ + --size=auto \ --definitions=./repart.d \ --root=$out \ patos-$version.raw diff --git a/utils/qemu-uefi-tpm.nix b/utils/qemu-uefi-tpm.nix index d05fbb2..bb151c5 100644 --- a/utils/qemu-uefi-tpm.nix +++ b/utils/qemu-uefi-tpm.nix @@ -33,7 +33,6 @@ pkgs.writeShellApplication { -smp 8 \ -m 4G \ -display none \ - -nographic \ -chardev "stdio,id=char0,mux=on,logfile=$state/console.log,signal=off" \ -serial chardev:char0 \ -mon chardev=char0 \ From e196cf729c066b585e0c89d4b29ec49e5507c219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 25 Feb 2025 11:40:34 +0100 Subject: [PATCH 06/67] feat(image): switching root --- dbus-broker/default.nix | 1 + image/default.nix | 5 ++ image/mkimage.sh | 112 +++++++++++++++++++++++++++++++++++++--- rootfs/mkinitrd.sh | 50 +++++------------- rootfs/mkrootfs.sh | 12 ++++- 5 files changed, 135 insertions(+), 45 deletions(-) diff --git a/dbus-broker/default.nix b/dbus-broker/default.nix index cad66af..156c490 100644 --- a/dbus-broker/default.nix +++ b/dbus-broker/default.nix @@ -150,6 +150,7 @@ stdenv.mkDerivation (finalAttrs: { mkdir -p $out/usr/share cp -Pr ${pkgs.dbus.out}/share/* $out/usr/share/ cp ${pkgs.dbus.out}/etc/systemd/system/dbus.socket $out/usr/lib/systemd/system/ + mv $out/usr/lib/systemd/system/dbus-broker.service $out/usr/lib/systemd/system/dbus.service find $out/usr/share/ -type d -exec chmod 755 {} \; sed -i 's#/nix/store.*/share#/usr/share#' $out/usr/share/xml/dbus-1/catalog.xml sed -i 's#/nix/store.*/libexec#/usr/bin#' $out/usr/share/dbus-1/system.conf diff --git a/image/default.nix b/image/default.nix index 3d7049b..e116625 100644 --- a/image/default.nix +++ b/image/default.nix @@ -16,9 +16,11 @@ stdenvNoCC.mkDerivation (finalAttrs: { erofs-utils dosfstools mtools + e2fsprogs ]; env = { + # vfat options won't efi won't find the fs otherwise. SYSTEMD_REPART_MKFS_OPTIONS_VFAT = "-S 512 -c"; }; @@ -27,5 +29,8 @@ stdenvNoCC.mkDerivation (finalAttrs: { initrd = patosPkgs.initrd.out; rootfs = patosPkgs.rootfs.out; + #FIXME: use roothash instead of device. + kernelCmdLine = "root=/dev/sda2 console=ttyS0"; + builder = ./mkimage.sh; }) diff --git a/image/mkimage.sh b/image/mkimage.sh index 2ec259f..fc80f9d 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -9,17 +9,117 @@ mkdir rootfs cp -prP $rootfs/* rootfs/ find rootfs/ -type d -exec chmod 755 {} \; +# set default target to basic +mkdir rootfs/usr/lib/systemd/system/basic.target.wants +ln -sf basic.target rootfs/usr/lib/systemd/system/default.target + +# enable dbus +ln -sf ../dbus.service rootfs/usr/lib/systemd/system/basic.target.wants/dbus.service +ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket + +# generate machine-id +$systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ + +cat <<EOF > rootfs/etc/passwd +root::0:0:root:/root:/bin/sh +bin:x:1:1:bin:/bin:/usr/bin/nologin +daemon:x:2:2:daemon:/:/usr/bin/nologin +mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin +ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin +http:x:33:33:http:/srv/http:/usr/bin/nologin +uuidd:x:68:68:uuidd:/:/usr/bin/nologin +messagebus:x:81:81:messagebus:/:/usr/bin/nologin +nobody:x:99:99:nobody:/:/usr/bin/nologin +systemd-coredump:x:151:992::/var/empty:/usr/bin/nologin +systemd-network:x:152:152::/var/empty:/usr/bin/nologin +systemd-resolve:x:153:153::/var/empty:/usr/bin/nologin +systemd-timesync:x:154:154::/var/empty:/usr/bin/nologin +EOF +chmod 644 rootfs/etc/passwd + +cat <<EOF > rootfs/etc/group +root:x:0:root +bin:x:1:root,bin,daemon +daemon:x:2:root,bin,daemon +sys:x:3:root,bin +adm:x:4:root,daemon +tty:x:5: +disk:x:6:root +lp:x:7:daemon +mem:x:8: +kmem:x:9: +wheel:x:10:root +ftp:x:11: +mail:x:12: +uucp:x:14: +log:x:19:root +utmp:x:20: +locate:x:21: +rfkill:x:24: +smmsp:x:25: +proc:x:26: +http:x:33: +games:x:50: +lock:x:54: +uuidd:x:68: +messagebus:x:81: +systemd-journal:x:62: +systemd-network:x:152: +systemd-resolve:x:153: +systemd-timesync:x:154: +systemd-oom:x:991: +systemd-coredump:x:992: +network:x:90: +video:x:91: +audio:x:92: +optical:x:93: +floppy:x:94: +storage:x:95: +scanner:x:96: +input:x:97: +power:x:98: +nobody:x:99: +EOF +chmod 644 rootfs/etc/group + +# FIXME: remove this later (just to get a shell in the initramfs) +cat <<EOF > rootfs/usr/lib/systemd/system/demo.service +[Unit] +Description=Debug Shell (/bin/sulogin) +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStart=/bin/sulogin +Type=idle +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no +SendSIGHUP=yes +Restart=always + +[Install] +WantedBy=basic.target +EOF +ln -sf ../demo.service rootfs/usr/lib/systemd/system/basic.target.wants/demo.service + + $systemd/usr/bin/ukify build \ - --os-release rootfs/etc/os-release \ --linux $kernel/bzImage \ --initrd $initrd/initrd.xz \ - --cmdline "console=ttyS0" \ - -o boot/patos-x64.efi + --os-release rootfs/etc/os-release \ + --stub $systemd/usr/lib/systemd/boot/efi/linuxx64.efi.stub \ + --cmdline "$kernelCmdLine" \ + -o boot/patos.efi cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ echo "timeout 1" > boot/loader.conf -echo -e "title PatOS Platform\nefi /EFI/Linux/patos-linux.efi" > boot/patos.conf +echo -e "title PatOS Platform\nefi /EFI/Linux/patos.efi" > boot/patos.conf cat <<EOF > repart.d/10-esp.conf [Partition] @@ -28,7 +128,7 @@ Format=vfat SizeMinBytes=96M SizeMaxBytes=96M CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI -CopyFiles=/boot/patos-x64.efi:/EFI/Linux/patos-linux.efi +CopyFiles=/boot/patos.efi:/EFI/Linux/patos.efi CopyFiles=/boot/loader.conf:/loader/loader.conf CopyFiles=/boot/patos.conf:/loader/entries/patos.conf EOF @@ -37,8 +137,8 @@ cat <<EOF > repart.d/10-root.conf [Partition] Type=root Format=erofs -CopyFiles=/rootfs:/ Minimize=best +CopyFiles=/rootfs:/ SplitName=root EOF diff --git a/rootfs/mkinitrd.sh b/rootfs/mkinitrd.sh index 2fe7770..c634b73 100644 --- a/rootfs/mkinitrd.sh +++ b/rootfs/mkinitrd.sh @@ -10,21 +10,12 @@ find . -type d -exec chmod 755 {} \; ### create directories ln -sf ../usr/lib/systemd/systemd init -# set default target to basic -mkdir usr/lib/systemd/system/basic.target.wants -ln -sf basic.target usr/lib/systemd/system/default.target - -# enable dbus broker -ln -sf ../dbus-broker.service usr/lib/systemd/system/basic.target.wants/dbus-broker.service -ln -sf ../dbus.socket usr/lib/systemd/system/sockets.target.wants/dbus.socket +mkdir sysroot ### Create needed files echo patos > ./etc/hostname -cat <<EOF > ./etc/os-release -NAME="PatOS" -PRETTY_NAME="PatOS Platform" -ID=patos -EOF + +ln -sf /etc/os-release ./etc/initrd-release cat <<EOF > ./etc/passwd root::0:0:root:/root:/bin/sh @@ -36,6 +27,10 @@ http:x:33:33:http:/srv/http:/usr/bin/nologin uuidd:x:68:68:uuidd:/:/usr/bin/nologin messagebus:x:81:81:messagebus:/:/usr/bin/nologin nobody:x:99:99:nobody:/:/usr/bin/nologin +systemd-coredump:x:151:992::/var/empty:/usr/bin/nologin +systemd-network:x:152:152::/var/empty:/usr/bin/nologin +systemd-resolve:x:153:153::/var/empty:/usr/bin/nologin +systemd-timesync:x:154:154::/var/empty:/usr/bin/nologin EOF chmod 644 ./etc/passwd @@ -65,6 +60,12 @@ games:x:50: lock:x:54: uuidd:x:68: messagebus:x:81: +systemd-journal:x:62: +systemd-network:x:152: +systemd-resolve:x:153: +systemd-timesync:x:154: +systemd-oom:x:991: +systemd-coredump:x:992: network:x:90: video:x:91: audio:x:92: @@ -78,31 +79,6 @@ nobody:x:99: EOF chmod 644 ./etc/group -# FIXME: remove this later (just to get a shell in the initramfs) -cat <<EOF > usr/lib/systemd/system/demo.service -[Unit] -Description=Debug Shell (/bin/sulogin) -Conflicts=shutdown.target -Before=shutdown.target - -[Service] -Environment=HOME=/root -WorkingDirectory=/root -ExecStart=/bin/sulogin -Type=idle -StandardInput=tty-force -StandardOutput=inherit -StandardError=inherit -KillMode=process -IgnoreSIGPIPE=no -SendSIGHUP=yes -Restart=always - -[Install] -WantedBy=basic.target -EOF -ln -sf ../demo.service usr/lib/systemd/system/basic.target.wants/demo.service - # gen initrd find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index b850129..68b6d44 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -1,7 +1,7 @@ set -ex -o pipefail mkdir -p $out -mkdir -p $out/etc $out/dev $out/proc $out/sys $out/tmp $out/root +mkdir -p $out/etc $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot ln -sf ../usr/bin $out/bin ln -sf ../usr/bin $out/sbin ln -sf ../usr/lib $out/lib @@ -18,6 +18,15 @@ rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service # remove vconsole setup rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules +cat <<EOF > $out/etc/os-release +NAME="PatOS" +PRETTY_NAME="PatOS 0.0.1 (pre-alpha)" +ID=patos +VERSION="0.0.1 (pre-alpha)" +VERSION_CODENAME=pre-alpha +VERSION_ID="0.0.1" +EOF + ### install PatOS glibc cp -P $glibcPatos/lib/*.so* $out/usr/lib/ @@ -51,4 +60,3 @@ patchelf --remove-rpath $out/usr/lib/ld-linux-x86-64.so.2 # strip binaries find $out -type f -executable -exec strip {} \; find $out -type d -exec chmod 755 {} \; - From e4ebf7ea7ff4fbe4e0c0bef0d0cec2f661da3d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 25 Feb 2025 13:39:02 +0100 Subject: [PATCH 07/67] feat(image): make /var stateful --- image/mkimage.sh | 19 ++++++++++++++++++- rootfs/mkrootfs.sh | 27 ++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/image/mkimage.sh b/image/mkimage.sh index fc80f9d..019aed2 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -13,11 +13,28 @@ find rootfs/ -type d -exec chmod 755 {} \; mkdir rootfs/usr/lib/systemd/system/basic.target.wants ln -sf basic.target rootfs/usr/lib/systemd/system/default.target +# mount patos state +cat <<EOF > rootfs/usr/lib/systemd/system/var.mount +[Unit] +Description=Mount for /var +Before=local-fs.target + +[Mount] +What=/dev/disk/by-label/patos-state +Where=/var +Type=ext2 +Options=defaults + +[Install] +WantedBy=basic.target +EOF +ln -sf ../var.mount rootfs/usr/lib/systemd/system/basic.target.wants/var.mount + # enable dbus ln -sf ../dbus.service rootfs/usr/lib/systemd/system/basic.target.wants/dbus.service ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket -# generate machine-id +# generate a temporary machine id $systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ cat <<EOF > rootfs/etc/passwd diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index 68b6d44..3ee0ca3 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -1,7 +1,7 @@ set -ex -o pipefail mkdir -p $out -mkdir -p $out/etc $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot +mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot ln -sf ../usr/bin $out/bin ln -sf ../usr/bin $out/sbin ln -sf ../usr/lib $out/lib @@ -27,6 +27,31 @@ VERSION_CODENAME=pre-alpha VERSION_ID="0.0.1" EOF +sed -i 's#After=\(.*\)#After=sysroot.mount \1#' $out/usr/lib/systemd/system/systemd-repart.service +cat <<EOF > $out/etc/repart.d/10-esp.conf +[Partition] +Type=esp +Format=vfat +EOF + +cat <<EOF > $out/etc/repart.d/22-root.conf +[Partition] +Type=root +EOF + +#FIXME: use btrfs instead on ext2(busybox) but need the btrfs tools in rootfs. +cat <<EOF > $out/etc/repart.d/40-var.conf +[Partition] +Type=var +UUID=4d21b016-b534-45c2-a9fb-5c16e091fd2d +Format=ext2 +Label=patos-state +Minimize=off +FactoryReset=yes +SizeMinBytes=1G +SplitName=- +EOF + ### install PatOS glibc cp -P $glibcPatos/lib/*.so* $out/usr/lib/ From b3ad9f9962c53fde9303d62c6facb32102b92672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 25 Feb 2025 18:01:44 +0100 Subject: [PATCH 08/67] feat(image): fix osrel in uki --- image/mkimage.sh | 5 +---- rootfs/mkrootfs.sh | 12 +++++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/image/mkimage.sh b/image/mkimage.sh index 019aed2..4ad147b 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -128,15 +128,13 @@ ln -sf ../demo.service rootfs/usr/lib/systemd/system/basic.target.wants/demo.ser $systemd/usr/bin/ukify build \ --linux $kernel/bzImage \ --initrd $initrd/initrd.xz \ - --os-release rootfs/etc/os-release \ - --stub $systemd/usr/lib/systemd/boot/efi/linuxx64.efi.stub \ + --os-release @rootfs/etc/os-release \ --cmdline "$kernelCmdLine" \ -o boot/patos.efi cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ echo "timeout 1" > boot/loader.conf -echo -e "title PatOS Platform\nefi /EFI/Linux/patos.efi" > boot/patos.conf cat <<EOF > repart.d/10-esp.conf [Partition] @@ -147,7 +145,6 @@ SizeMaxBytes=96M CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI CopyFiles=/boot/patos.efi:/EFI/Linux/patos.efi CopyFiles=/boot/loader.conf:/loader/loader.conf -CopyFiles=/boot/patos.conf:/loader/entries/patos.conf EOF cat <<EOF > repart.d/10-root.conf diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index 3ee0ca3..e60e028 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -19,12 +19,14 @@ rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules cat <<EOF > $out/etc/os-release -NAME="PatOS" -PRETTY_NAME="PatOS 0.0.1 (pre-alpha)" +NAME=PatOS +PRETTY_NAME=PatOS 0.0.1 (pre-alpha) +IMAGE_ID=patos ID=patos -VERSION="0.0.1 (pre-alpha)" -VERSION_CODENAME=pre-alpha -VERSION_ID="0.0.1" +IMAGE_VERSION=0.0.1 +VERSION=0.0.1 +VERSION_ID=0.0.1 +BUILD_ID=0.0.1 EOF sed -i 's#After=\(.*\)#After=sysroot.mount \1#' $out/usr/lib/systemd/system/systemd-repart.service From 3374541b3a14baa03887c2db4b4f669ed77aec58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 25 Feb 2025 21:02:35 +0100 Subject: [PATCH 09/67] feat(image): switch to btrfs for patos-state --- image/mkimage.sh | 92 +++++------------------------------------- rootfs/default.nix | 1 + rootfs/mkinitrd.sh | 65 +----------------------------- rootfs/mkrootfs.sh | 99 ++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 102 insertions(+), 155 deletions(-) diff --git a/image/mkimage.sh b/image/mkimage.sh index 4ad147b..721c26e 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -9,96 +9,22 @@ mkdir rootfs cp -prP $rootfs/* rootfs/ find rootfs/ -type d -exec chmod 755 {} \; -# set default target to basic -mkdir rootfs/usr/lib/systemd/system/basic.target.wants -ln -sf basic.target rootfs/usr/lib/systemd/system/default.target +# set default target to multi-user +ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target # mount patos state -cat <<EOF > rootfs/usr/lib/systemd/system/var.mount -[Unit] -Description=Mount for /var -Before=local-fs.target - -[Mount] -What=/dev/disk/by-label/patos-state -Where=/var -Type=ext2 -Options=defaults - -[Install] -WantedBy=basic.target -EOF -ln -sf ../var.mount rootfs/usr/lib/systemd/system/basic.target.wants/var.mount +ln -sf ../var.mount rootfs/usr/lib/systemd/system/sysinit.target.wants/var.mount # enable dbus -ln -sf ../dbus.service rootfs/usr/lib/systemd/system/basic.target.wants/dbus.service +ln -sf ../dbus.service rootfs/usr/lib/systemd/system/multi-user.target.wants/dbus.service ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket +# enable systemd-networkd +ln -sf ../systemd-networkd.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-networkd.service + # generate a temporary machine id $systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ -cat <<EOF > rootfs/etc/passwd -root::0:0:root:/root:/bin/sh -bin:x:1:1:bin:/bin:/usr/bin/nologin -daemon:x:2:2:daemon:/:/usr/bin/nologin -mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin -ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin -http:x:33:33:http:/srv/http:/usr/bin/nologin -uuidd:x:68:68:uuidd:/:/usr/bin/nologin -messagebus:x:81:81:messagebus:/:/usr/bin/nologin -nobody:x:99:99:nobody:/:/usr/bin/nologin -systemd-coredump:x:151:992::/var/empty:/usr/bin/nologin -systemd-network:x:152:152::/var/empty:/usr/bin/nologin -systemd-resolve:x:153:153::/var/empty:/usr/bin/nologin -systemd-timesync:x:154:154::/var/empty:/usr/bin/nologin -EOF -chmod 644 rootfs/etc/passwd - -cat <<EOF > rootfs/etc/group -root:x:0:root -bin:x:1:root,bin,daemon -daemon:x:2:root,bin,daemon -sys:x:3:root,bin -adm:x:4:root,daemon -tty:x:5: -disk:x:6:root -lp:x:7:daemon -mem:x:8: -kmem:x:9: -wheel:x:10:root -ftp:x:11: -mail:x:12: -uucp:x:14: -log:x:19:root -utmp:x:20: -locate:x:21: -rfkill:x:24: -smmsp:x:25: -proc:x:26: -http:x:33: -games:x:50: -lock:x:54: -uuidd:x:68: -messagebus:x:81: -systemd-journal:x:62: -systemd-network:x:152: -systemd-resolve:x:153: -systemd-timesync:x:154: -systemd-oom:x:991: -systemd-coredump:x:992: -network:x:90: -video:x:91: -audio:x:92: -optical:x:93: -floppy:x:94: -storage:x:95: -scanner:x:96: -input:x:97: -power:x:98: -nobody:x:99: -EOF -chmod 644 rootfs/etc/group - # FIXME: remove this later (just to get a shell in the initramfs) cat <<EOF > rootfs/usr/lib/systemd/system/demo.service [Unit] @@ -120,9 +46,9 @@ SendSIGHUP=yes Restart=always [Install] -WantedBy=basic.target +WantedBy=multi-user.target EOF -ln -sf ../demo.service rootfs/usr/lib/systemd/system/basic.target.wants/demo.service +ln -sf ../demo.service rootfs/usr/lib/systemd/system/multi-user.target.wants/demo.service $systemd/usr/bin/ukify build \ diff --git a/rootfs/default.nix b/rootfs/default.nix index 755050f..a180f8e 100644 --- a/rootfs/default.nix +++ b/rootfs/default.nix @@ -25,6 +25,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { kmodLibs = pkgs.kmod.lib; kmodBin = pkgs.kmod.out; libbpf = pkgs.libbpf.out; + btrfs = pkgs.btrfs-progs.out; builder = ./mkrootfs.sh; }) diff --git a/rootfs/mkinitrd.sh b/rootfs/mkinitrd.sh index c634b73..c735448 100644 --- a/rootfs/mkinitrd.sh +++ b/rootfs/mkinitrd.sh @@ -6,79 +6,16 @@ pushd $out/root ### copy rootfs cp -prP $rootfs/* . find . -type d -exec chmod 755 {} \; +mkdir sysroot ### create directories ln -sf ../usr/lib/systemd/systemd init -mkdir sysroot - ### Create needed files echo patos > ./etc/hostname ln -sf /etc/os-release ./etc/initrd-release -cat <<EOF > ./etc/passwd -root::0:0:root:/root:/bin/sh -bin:x:1:1:bin:/bin:/usr/bin/nologin -daemon:x:2:2:daemon:/:/usr/bin/nologin -mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin -ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin -http:x:33:33:http:/srv/http:/usr/bin/nologin -uuidd:x:68:68:uuidd:/:/usr/bin/nologin -messagebus:x:81:81:messagebus:/:/usr/bin/nologin -nobody:x:99:99:nobody:/:/usr/bin/nologin -systemd-coredump:x:151:992::/var/empty:/usr/bin/nologin -systemd-network:x:152:152::/var/empty:/usr/bin/nologin -systemd-resolve:x:153:153::/var/empty:/usr/bin/nologin -systemd-timesync:x:154:154::/var/empty:/usr/bin/nologin -EOF -chmod 644 ./etc/passwd - -cat <<EOF > ./etc/group -root:x:0:root -bin:x:1:root,bin,daemon -daemon:x:2:root,bin,daemon -sys:x:3:root,bin -adm:x:4:root,daemon -tty:x:5: -disk:x:6:root -lp:x:7:daemon -mem:x:8: -kmem:x:9: -wheel:x:10:root -ftp:x:11: -mail:x:12: -uucp:x:14: -log:x:19:root -utmp:x:20: -locate:x:21: -rfkill:x:24: -smmsp:x:25: -proc:x:26: -http:x:33: -games:x:50: -lock:x:54: -uuidd:x:68: -messagebus:x:81: -systemd-journal:x:62: -systemd-network:x:152: -systemd-resolve:x:153: -systemd-timesync:x:154: -systemd-oom:x:991: -systemd-coredump:x:992: -network:x:90: -video:x:91: -audio:x:92: -optical:x:93: -floppy:x:94: -storage:x:95: -scanner:x:96: -input:x:97: -power:x:98: -nobody:x:99: -EOF -chmod 644 ./etc/group - # gen initrd find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index e60e028..c7460e6 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -1,7 +1,7 @@ set -ex -o pipefail mkdir -p $out -mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot +mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt ln -sf ../usr/bin $out/bin ln -sf ../usr/bin $out/sbin ln -sf ../usr/lib $out/lib @@ -20,13 +20,13 @@ rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules cat <<EOF > $out/etc/os-release NAME=PatOS -PRETTY_NAME=PatOS 0.0.1 (pre-alpha) +PRETTY_NAME=PatOS v${version} (Pre-Alpha) IMAGE_ID=patos ID=patos -IMAGE_VERSION=0.0.1 -VERSION=0.0.1 -VERSION_ID=0.0.1 -BUILD_ID=0.0.1 +IMAGE_VERSION=${version} +VERSION=${version} +VERSION_ID={version} +BUILD_ID={version} EOF sed -i 's#After=\(.*\)#After=sysroot.mount \1#' $out/usr/lib/systemd/system/systemd-repart.service @@ -41,12 +41,11 @@ cat <<EOF > $out/etc/repart.d/22-root.conf Type=root EOF -#FIXME: use btrfs instead on ext2(busybox) but need the btrfs tools in rootfs. cat <<EOF > $out/etc/repart.d/40-var.conf [Partition] Type=var UUID=4d21b016-b534-45c2-a9fb-5c16e091fd2d -Format=ext2 +Format=btrfs Label=patos-state Minimize=off FactoryReset=yes @@ -54,6 +53,21 @@ SizeMinBytes=1G SplitName=- EOF +cat <<EOF > $out/usr/lib/systemd/system/var.mount +[Unit] +Description=Mount for /var +Before=local-fs.target + +[Mount] +What=/dev/disk/by-label/patos-state +Where=/var +Type=btrfs +Options=defaults + +[Install] +WantedBy=multi-user.target +EOF + ### install PatOS glibc cp -P $glibcPatos/lib/*.so* $out/usr/lib/ @@ -68,6 +82,10 @@ $out/usr/bin/busybox --list | xargs -I {} ln -sf busybox $out/usr/bin/{} ### install dbus broker cp -r $dbusBroker/* $out/ +### install btrfs progs +cp -Pr ${btrfs}/bin/* $out/usr/bin/ +cp -Pr ${btrfs}/lib/* $out/usr/lib/ + ### install lib kmod cp -P $kmodLibs/lib/* $out/usr/lib cp -P $kmodBin/bin/* $out/usr/bin @@ -75,6 +93,71 @@ cp -P $kmodBin/bin/* $out/usr/bin ### install libbpf cp -P $libbpf/lib/libbpf* $out/usr/lib +# remove pkgconfig +rm -rf $out/usr/lib/pkgconfig + +cat <<EOF > $out/etc/passwd +root::0:0:root:/root:/bin/sh +bin:x:1:1:bin:/bin:/usr/bin/nologin +daemon:x:2:2:daemon:/:/usr/bin/nologin +mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin +ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin +http:x:33:33:http:/srv/http:/usr/bin/nologin +uuidd:x:68:68:uuidd:/:/usr/bin/nologin +messagebus:x:81:81:messagebus:/:/usr/bin/nologin +nobody:x:99:99:nobody:/:/usr/bin/nologin +systemd-coredump:x:151:992::/var/empty:/usr/bin/nologin +systemd-network:x:152:152::/var/empty:/usr/bin/nologin +systemd-resolve:x:153:153::/var/empty:/usr/bin/nologin +systemd-timesync:x:154:154::/var/empty:/usr/bin/nologin +EOF +chmod 644 $out/etc/passwd + +cat <<EOF > $out/etc/group +root:x:0:root +bin:x:1:root,bin,daemon +daemon:x:2:root,bin,daemon +sys:x:3:root,bin +adm:x:4:root,daemon +tty:x:5: +disk:x:6:root +lp:x:7:daemon +mem:x:8: +kmem:x:9: +wheel:x:10:root +ftp:x:11: +mail:x:12: +uucp:x:14: +log:x:19:root +utmp:x:20: +locate:x:21: +rfkill:x:24: +smmsp:x:25: +proc:x:26: +http:x:33: +games:x:50: +lock:x:54: +uuidd:x:68: +messagebus:x:81: +systemd-journal:x:62: +systemd-network:x:152: +systemd-resolve:x:153: +systemd-timesync:x:154: +systemd-oom:x:991: +systemd-coredump:x:992: +network:x:90: +video:x:91: +audio:x:92: +optical:x:93: +floppy:x:94: +storage:x:95: +scanner:x:96: +input:x:97: +power:x:98: +nobody:x:99: +EOF +chmod 644 $out/etc/group + ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | sort -u | xargs cp -t $out/usr/lib find $out -type f -executable -exec chmod 755 {} \; From 0ed83a6d27d8aae1142a9814d0ae303825b079b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 25 Feb 2025 21:54:42 +0100 Subject: [PATCH 10/67] feat(image): add overlay to /etc and use busybox getty for login prompt --- image/mkimage.sh | 27 +-------------------------- rootfs/mkrootfs.sh | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/image/mkimage.sh b/image/mkimage.sh index 721c26e..7a76dd9 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -13,6 +13,7 @@ find rootfs/ -type d -exec chmod 755 {} \; ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target # mount patos state +ln -sf ../etc.mount rootfs/usr/lib/systemd/system/local-fs.target.wants/etc.mount ln -sf ../var.mount rootfs/usr/lib/systemd/system/sysinit.target.wants/var.mount # enable dbus @@ -25,32 +26,6 @@ ln -sf ../systemd-networkd.service rootfs/usr/lib/systemd/system/sysinit.target. # generate a temporary machine id $systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ -# FIXME: remove this later (just to get a shell in the initramfs) -cat <<EOF > rootfs/usr/lib/systemd/system/demo.service -[Unit] -Description=Debug Shell (/bin/sulogin) -Conflicts=shutdown.target -Before=shutdown.target - -[Service] -Environment=HOME=/root -WorkingDirectory=/root -ExecStart=/bin/sulogin -Type=idle -StandardInput=tty-force -StandardOutput=inherit -StandardError=inherit -KillMode=process -IgnoreSIGPIPE=no -SendSIGHUP=yes -Restart=always - -[Install] -WantedBy=multi-user.target -EOF -ln -sf ../demo.service rootfs/usr/lib/systemd/system/multi-user.target.wants/demo.service - - $systemd/usr/bin/ukify build \ --linux $kernel/bzImage \ --initrd $initrd/initrd.xz \ diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index c7460e6..75ba2a6 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -1,7 +1,7 @@ set -ex -o pipefail mkdir -p $out -mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt +mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv ln -sf ../usr/bin $out/bin ln -sf ../usr/bin $out/sbin ln -sf ../usr/lib $out/lib @@ -29,6 +29,9 @@ VERSION_ID={version} BUILD_ID={version} EOF +# replace agetty with busybox getty +sed -i 's#ExecStart=.*#ExecStart=-/sbin/getty -L %I 115200 vt100#' $out/usr/lib/systemd/system/serial-getty@.service + sed -i 's#After=\(.*\)#After=sysroot.mount \1#' $out/usr/lib/systemd/system/systemd-repart.service cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] @@ -68,6 +71,21 @@ Options=defaults WantedBy=multi-user.target EOF +cat <<EOF > $out/usr/lib/systemd/system/etc.mount +[Unit] +Description=Overlay mount for /etc +Before=local-fs.target + +[Mount] +What=overlay +Where=/etc +Type=overlay +Options=lowerdir=/etc,upperdir=/run/.rw-etc/upper,workdir=/run/.rw-etc/work + +[Install] +WantedBy=local-fs.target +EOF + ### install PatOS glibc cp -P $glibcPatos/lib/*.so* $out/usr/lib/ From a3aab1ea5cb98dfcf0093a2df1f6290e6aa34faa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 25 Feb 2025 23:08:42 +0100 Subject: [PATCH 11/67] chore: flake nix cleanup --- flake.nix | 22 +++++++++++++++------- image/default.nix | 2 +- rootfs/default.nix | 2 +- rootfs/mkinitrd.nix | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/flake.nix b/flake.nix index 2e4eafa..9e612b4 100644 --- a/flake.nix +++ b/flake.nix @@ -17,17 +17,27 @@ let pkgs = import nixpkgs { inherit system; }; patosPkgs = self.packages.${system}; + version = "0.0.1"; in { packages = { - default = self.packages.${system}.image; - image = pkgs.callPackage ./image { inherit patosPkgs; }; + default = patosPkgs.image; + image = pkgs.callPackage ./image { + inherit patosPkgs; + inherit version; + }; + rootfs = pkgs.callPackage ./rootfs { + inherit patosPkgs; + inherit version; + }; + initrd = pkgs.callPackage ./rootfs/mkinitrd.nix { + inherit patosPkgs; + inherit version; + }; kernel = pkgs.callPackage ./kernel { }; glibc = pkgs.callPackage ./glibc { }; systemd = pkgs.callPackage ./systemd { }; dbus-broker = pkgs.callPackage ./dbus-broker { }; - rootfs = pkgs.callPackage ./rootfs { inherit patosPkgs; }; - initrd = pkgs.callPackage ./rootfs/mkinitrd.nix { inherit patosPkgs; }; qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { }; }; @@ -43,12 +53,10 @@ devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ - erofs-utils just nixd nixfmt-rfc-style - squashfs-tools-ng - self.packages.${system}.qemu-uefi-tpm + patosPkgs.qemu-uefi-tpm ]; }; diff --git a/image/default.nix b/image/default.nix index e116625..553d87f 100644 --- a/image/default.nix +++ b/image/default.nix @@ -2,10 +2,10 @@ pkgs, stdenvNoCC, patosPkgs, + version, ... }: let - version = "0.0.1"; pname = "patos-image"; in stdenvNoCC.mkDerivation (finalAttrs: { diff --git a/rootfs/default.nix b/rootfs/default.nix index a180f8e..b206a0c 100644 --- a/rootfs/default.nix +++ b/rootfs/default.nix @@ -2,10 +2,10 @@ pkgs, stdenvNoCC, patosPkgs, + version, ... }: let - version = "0.0.1"; pname = "patos-rootfs"; in stdenvNoCC.mkDerivation (finalAttrs: { diff --git a/rootfs/mkinitrd.nix b/rootfs/mkinitrd.nix index f564813..3708483 100644 --- a/rootfs/mkinitrd.nix +++ b/rootfs/mkinitrd.nix @@ -2,10 +2,10 @@ pkgs, stdenvNoCC, patosPkgs, + version, ... }: let - version = "0.0.1"; pname = "patos-ramdisk"; in stdenvNoCC.mkDerivation (finalAttrs: { From ca54cefe36dae77b60cdc4c49569f573d6eb32f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Feb 2025 10:21:56 +0100 Subject: [PATCH 12/67] fix: mount race condition of patos-state --- image/mkimage.sh | 8 +++++--- rootfs/mkrootfs.sh | 16 +++++++++++----- systemd/default.nix | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/image/mkimage.sh b/image/mkimage.sh index 7a76dd9..0a7ca0b 100644 --- a/image/mkimage.sh +++ b/image/mkimage.sh @@ -12,7 +12,7 @@ find rootfs/ -type d -exec chmod 755 {} \; # set default target to multi-user ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target -# mount patos state +# mount /etc overlay and patos state ln -sf ../etc.mount rootfs/usr/lib/systemd/system/local-fs.target.wants/etc.mount ln -sf ../var.mount rootfs/usr/lib/systemd/system/sysinit.target.wants/var.mount @@ -20,10 +20,12 @@ ln -sf ../var.mount rootfs/usr/lib/systemd/system/sysinit.target.wants/var.mount ln -sf ../dbus.service rootfs/usr/lib/systemd/system/multi-user.target.wants/dbus.service ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket -# enable systemd-networkd +# enable network services ln -sf ../systemd-networkd.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-networkd.service +ln -sf ../systemd-resolved.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-resolved.service +ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.target.wants/systemd-timesyncd.service -# generate a temporary machine id +# generate a temporary machine id (replace with overlay later) $systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ $systemd/usr/bin/ukify build \ diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index 75ba2a6..5fba8c5 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -1,11 +1,11 @@ set -ex -o pipefail mkdir -p $out -mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv -ln -sf ../usr/bin $out/bin -ln -sf ../usr/bin $out/sbin -ln -sf ../usr/lib $out/lib -ln -sf ../usr/lib $out/lib64 +mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var/tmp +ln -sf /usr/bin $out/bin +ln -sf /usr/bin $out/sbin +ln -sf /usr/lib $out/lib +ln -sf /usr/lib $out/lib64 ln -sf ../proc/self/mounts $out/etc/mtab ### install systemd @@ -29,6 +29,11 @@ VERSION_ID={version} BUILD_ID={version} EOF +cat <<EOF > $out/etc/issue +<<< Welcome to PatOS v${version} (Pre-Alpha) (\m) - \l >>> + +EOF + # replace agetty with busybox getty sed -i 's#ExecStart=.*#ExecStart=-/sbin/getty -L %I 115200 vt100#' $out/usr/lib/systemd/system/serial-getty@.service @@ -60,6 +65,7 @@ cat <<EOF > $out/usr/lib/systemd/system/var.mount [Unit] Description=Mount for /var Before=local-fs.target +After=systemd-repart.service [Mount] What=/dev/disk/by-label/patos-state diff --git a/systemd/default.nix b/systemd/default.nix index 4daf9ed..130cf42 100644 --- a/systemd/default.nix +++ b/systemd/default.nix @@ -305,7 +305,7 @@ stdenv.mkDerivation (finalAttrs: { (lib.mesonBool "utmp" true) (lib.mesonBool "log-trace" true) - (lib.mesonBool "kernel-install" true) + (lib.mesonBool "kernel-install" false) (lib.mesonBool "quotacheck" false) (lib.mesonBool "ldconfig" false) (lib.mesonBool "install-sysconfdir" true) From 0a0e9127e0b60bfe59c39159f20790e7d277cdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Feb 2025 10:44:36 +0100 Subject: [PATCH 13/67] fix(systemd): set path to kexec --- rootfs/mkrootfs.sh | 5 +++-- systemd/default.nix | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rootfs/mkrootfs.sh b/rootfs/mkrootfs.sh index 5fba8c5..ff19902 100644 --- a/rootfs/mkrootfs.sh +++ b/rootfs/mkrootfs.sh @@ -1,6 +1,6 @@ set -ex -o pipefail -mkdir -p $out +### create directory structure mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var/tmp ln -sf /usr/bin $out/bin ln -sf /usr/bin $out/sbin @@ -15,7 +15,8 @@ find $out -type d -exec chmod 755 {} \; rm -rf $out/usr/include rm -rf $out/usr/sbin rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service -# remove vconsole setup +rm -f $out/usr/lib/systemd/ukify +rm -f $out/usr/bin/ukify rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules cat <<EOF > $out/etc/os-release diff --git a/systemd/default.nix b/systemd/default.nix index 130cf42..6f5c6c9 100644 --- a/systemd/default.nix +++ b/systemd/default.nix @@ -184,6 +184,7 @@ stdenv.mkDerivation (finalAttrs: { (lib.mesonOption "tty-gid" "3") # tty in NixOS has gid 3 (lib.mesonOption "kmod-path" "/usr/bin/kmod") + (lib.mesonOption "kexec-path" "/usr/bin/kexec") (lib.mesonOption "debug-shell" "/usr/bin/sh") (lib.mesonOption "pamconfdir" "/etc/pam.d") (lib.mesonOption "shellprofiledir" "/etc/profile.d") From 7365ef8918dacc9c26f9d94bd71078cf62652d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Feb 2025 14:35:58 +0100 Subject: [PATCH 14/67] feat(image): install upstream kexec which now have support for UKIs --- flake.nix | 15 ++--- {dbus-broker => pkgs/dbus-broker}/default.nix | 0 {glibc => pkgs/glibc}/default.nix | 0 {image => pkgs/image}/default.nix | 0 {image => pkgs/image}/mkimage.sh | 0 {kernel => pkgs/kernel}/default.nix | 0 {kernel => pkgs/kernel}/generic.config | 0 pkgs/kexec-tools/default.nix | 62 +++++++++++++++++++ {rootfs => pkgs/rootfs}/default.nix | 1 + {rootfs => pkgs/rootfs}/mkinitrd.nix | 0 {rootfs => pkgs/rootfs}/mkinitrd.sh | 0 {rootfs => pkgs/rootfs}/mkrootfs.sh | 3 + {systemd => pkgs/systemd}/default.nix | 0 13 files changed, 74 insertions(+), 7 deletions(-) rename {dbus-broker => pkgs/dbus-broker}/default.nix (100%) rename {glibc => pkgs/glibc}/default.nix (100%) rename {image => pkgs/image}/default.nix (100%) rename {image => pkgs/image}/mkimage.sh (100%) rename {kernel => pkgs/kernel}/default.nix (100%) rename {kernel => pkgs/kernel}/generic.config (100%) create mode 100644 pkgs/kexec-tools/default.nix rename {rootfs => pkgs/rootfs}/default.nix (94%) rename {rootfs => pkgs/rootfs}/mkinitrd.nix (100%) rename {rootfs => pkgs/rootfs}/mkinitrd.sh (100%) rename {rootfs => pkgs/rootfs}/mkrootfs.sh (98%) rename {systemd => pkgs/systemd}/default.nix (100%) diff --git a/flake.nix b/flake.nix index 9e612b4..32097ba 100644 --- a/flake.nix +++ b/flake.nix @@ -22,22 +22,23 @@ { packages = { default = patosPkgs.image; - image = pkgs.callPackage ./image { + image = pkgs.callPackage ./pkgs/image { inherit patosPkgs; inherit version; }; - rootfs = pkgs.callPackage ./rootfs { + rootfs = pkgs.callPackage ./pkgs/rootfs { inherit patosPkgs; inherit version; }; - initrd = pkgs.callPackage ./rootfs/mkinitrd.nix { + initrd = pkgs.callPackage ./pkgs/rootfs/mkinitrd.nix { inherit patosPkgs; inherit version; }; - kernel = pkgs.callPackage ./kernel { }; - glibc = pkgs.callPackage ./glibc { }; - systemd = pkgs.callPackage ./systemd { }; - dbus-broker = pkgs.callPackage ./dbus-broker { }; + kernel = pkgs.callPackage ./pkgs/kernel { }; + glibc = pkgs.callPackage ./pkgs/glibc { }; + kexec = pkgs.callPackage ./pkgs/kexec-tools { }; + systemd = pkgs.callPackage ./pkgs/systemd { }; + dbus-broker = pkgs.callPackage ./pkgs/dbus-broker { }; qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { }; }; diff --git a/dbus-broker/default.nix b/pkgs/dbus-broker/default.nix similarity index 100% rename from dbus-broker/default.nix rename to pkgs/dbus-broker/default.nix diff --git a/glibc/default.nix b/pkgs/glibc/default.nix similarity index 100% rename from glibc/default.nix rename to pkgs/glibc/default.nix diff --git a/image/default.nix b/pkgs/image/default.nix similarity index 100% rename from image/default.nix rename to pkgs/image/default.nix diff --git a/image/mkimage.sh b/pkgs/image/mkimage.sh similarity index 100% rename from image/mkimage.sh rename to pkgs/image/mkimage.sh diff --git a/kernel/default.nix b/pkgs/kernel/default.nix similarity index 100% rename from kernel/default.nix rename to pkgs/kernel/default.nix diff --git a/kernel/generic.config b/pkgs/kernel/generic.config similarity index 100% rename from kernel/generic.config rename to pkgs/kernel/generic.config diff --git a/pkgs/kexec-tools/default.nix b/pkgs/kexec-tools/default.nix new file mode 100644 index 0000000..4ba15ba --- /dev/null +++ b/pkgs/kexec-tools/default.nix @@ -0,0 +1,62 @@ +{ + lib, + stdenv, + buildPackages, + fetchFromGitHub, + autoconf, + zlib, +}: + +stdenv.mkDerivation { + pname = "kexec-tools"; + version = "main"; + + src = fetchFromGitHub { + owner = "horms"; + repo = "kexec-tools"; + rev = "a7fcd424c4c80dea5a2fd5ffa274ffeb8129c790"; + hash = "sha256-QKE+KCkueA21zNunTMidP9OuZaw0IG5tFDF4UJITTTQ="; + }; + + dontPatchShebangs = true; + + hardeningDisable = [ + "format" + "pic" + "relro" + "pie" + ]; + + buildCommand = '' + unpackPhase + mkdir -p $out + cd source + ./bootstrap + ./configure --prefix=/ + make DESTDIR=$out install + ''; + + depsBuildBuild = [ buildPackages.stdenv.cc ]; + + buildInputs = [ + zlib + autoconf + ]; + + enableParallelBuilding = true; + + meta = with lib; { + homepage = "http://horms.net/projects/kexec/kexec-tools"; + description = "Tools related to the kexec Linux feature"; + platforms = platforms.linux; + badPlatforms = [ + "microblaze-linux" + "microblazeel-linux" + "riscv64-linux" + "riscv32-linux" + "sparc-linux" + "sparc64-linux" + ]; + license = licenses.gpl2Only; + }; +} diff --git a/rootfs/default.nix b/pkgs/rootfs/default.nix similarity index 94% rename from rootfs/default.nix rename to pkgs/rootfs/default.nix index b206a0c..c6f6fa1 100644 --- a/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -26,6 +26,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { kmodBin = pkgs.kmod.out; libbpf = pkgs.libbpf.out; btrfs = pkgs.btrfs-progs.out; + kexec = patosPkgs.kexec.out; builder = ./mkrootfs.sh; }) diff --git a/rootfs/mkinitrd.nix b/pkgs/rootfs/mkinitrd.nix similarity index 100% rename from rootfs/mkinitrd.nix rename to pkgs/rootfs/mkinitrd.nix diff --git a/rootfs/mkinitrd.sh b/pkgs/rootfs/mkinitrd.sh similarity index 100% rename from rootfs/mkinitrd.sh rename to pkgs/rootfs/mkinitrd.sh diff --git a/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh similarity index 98% rename from rootfs/mkrootfs.sh rename to pkgs/rootfs/mkrootfs.sh index ff19902..fb9efe8 100644 --- a/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -107,6 +107,9 @@ $out/usr/bin/busybox --list | xargs -I {} ln -sf busybox $out/usr/bin/{} ### install dbus broker cp -r $dbusBroker/* $out/ +### install kexec +cp -Pr ${kexec}/sbin/kexec $out/usr/bin/ + ### install btrfs progs cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ diff --git a/systemd/default.nix b/pkgs/systemd/default.nix similarity index 100% rename from systemd/default.nix rename to pkgs/systemd/default.nix From 57f83bd4ac0c951e0b432de07e14031bf5c41d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 27 Feb 2025 00:02:22 +0100 Subject: [PATCH 15/67] chore: make erofs with --all-root flag --- pkgs/image/default.nix | 1 + pkgs/rootfs/mkrootfs.sh | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 553d87f..8348db4 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -22,6 +22,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { env = { # vfat options won't efi won't find the fs otherwise. SYSTEMD_REPART_MKFS_OPTIONS_VFAT = "-S 512 -c"; + SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; }; systemd = patosPkgs.systemd.out; diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index fb9efe8..078c011 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -1,7 +1,8 @@ set -ex -o pipefail ### create directory structure -mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var/tmp +mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys \ + $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var/tmp ln -sf /usr/bin $out/bin ln -sf /usr/bin $out/sbin ln -sf /usr/lib $out/lib @@ -18,6 +19,7 @@ rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service rm -f $out/usr/lib/systemd/ukify rm -f $out/usr/bin/ukify rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules +ln -s /run/systemd/resolve/stub-resolv.conf $out/etc/resolv.conf cat <<EOF > $out/etc/os-release NAME=PatOS From aa4f69d8919d94fa304d6fc20011a07f00c39c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 27 Feb 2025 08:59:01 +0100 Subject: [PATCH 16/67] fix: we need to roll our own versions of tpm2-tools and tpm2-tss --- flake.nix | 2 + pkgs/kernel/default.nix | 4 +- pkgs/kernel/generic.config | 1 + pkgs/rootfs/default.nix | 2 + pkgs/rootfs/mkrootfs.sh | 6 ++- pkgs/tpm2-tools/default.nix | 48 +++++++++++++++++++ pkgs/tpm2-tss/default.nix | 86 +++++++++++++++++++++++++++++++++++ pkgs/tpm2-tss/no-shadow.patch | 16 +++++++ 8 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 pkgs/tpm2-tools/default.nix create mode 100644 pkgs/tpm2-tss/default.nix create mode 100644 pkgs/tpm2-tss/no-shadow.patch diff --git a/flake.nix b/flake.nix index 32097ba..071ae56 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,8 @@ kernel = pkgs.callPackage ./pkgs/kernel { }; glibc = pkgs.callPackage ./pkgs/glibc { }; kexec = pkgs.callPackage ./pkgs/kexec-tools { }; + tpm2-tools = pkgs.callPackage ./pkgs/tpm2-tools { inherit patosPkgs; }; + tpm2-tss = pkgs.callPackage ./pkgs/tpm2-tss { }; systemd = pkgs.callPackage ./pkgs/systemd { }; dbus-broker = pkgs.callPackage ./pkgs/dbus-broker { }; diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix index e10d25b..73ecd1f 100644 --- a/pkgs/kernel/default.nix +++ b/pkgs/kernel/default.nix @@ -1,6 +1,6 @@ { pkgs, ... }: let - version = "6.13.2"; + version = "6.13.4"; in pkgs.linuxPackagesFor ( pkgs.linuxManualConfig { @@ -8,7 +8,7 @@ pkgs.linuxPackagesFor ( modDirVersion = version; src = pkgs.fetchurl { url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz"; - hash = "sha256-zfYpgZBru+lwGutzxPn8yAegmEbCiHMWY9YnF+0a5wU="; + hash = "sha256-uA4LyO+8MenOWoTRCE3Mz6QOAb6ozCWv0GZIuT1hM54="; }; configfile = ./generic.config; allowImportFromDerivation = true; diff --git a/pkgs/kernel/generic.config b/pkgs/kernel/generic.config index 7e0325c..c717915 100644 --- a/pkgs/kernel/generic.config +++ b/pkgs/kernel/generic.config @@ -2213,6 +2213,7 @@ CONFIG_TCG_CRB=y CONFIG_TCG_TIS_CORE=y CONFIG_TCG_TIS=y CONFIG_TCG_TPM=y +CONFIG_TCG_TPM2_HMAC=y CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_BBR=y CONFIG_TCP_CONG_CUBIC=y diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index c6f6fa1..4d7768b 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -26,6 +26,8 @@ stdenvNoCC.mkDerivation (finalAttrs: { kmodBin = pkgs.kmod.out; libbpf = pkgs.libbpf.out; btrfs = pkgs.btrfs-progs.out; + tpm2Libs = patosPkgs.tpm2-tss.out; + tpm2Tools = patosPkgs.tpm2-tools.out; kexec = patosPkgs.kexec.out; builder = ./mkrootfs.sh; diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 078c011..7d94052 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -116,6 +116,10 @@ cp -Pr ${kexec}/sbin/kexec $out/usr/bin/ cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ +### install tpm2 tools +cp -P ${tpm2Tools}/bin/* $out/usr/bin/ +cp -P ${tpm2Libs}/lib/*.so* $out/usr/lib/ + ### install lib kmod cp -P $kmodLibs/lib/* $out/usr/lib cp -P $kmodBin/bin/* $out/usr/bin @@ -189,7 +193,7 @@ EOF chmod 644 $out/etc/group ### Find and install all shared libs -find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | sort -u | xargs cp -t $out/usr/lib +find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | grep -v tpm2 | sort -u | xargs cp -t $out/usr/lib find $out -type f -executable -exec chmod 755 {} \; # FIXME: ELF patching. Is there a better way? diff --git a/pkgs/tpm2-tools/default.nix b/pkgs/tpm2-tools/default.nix new file mode 100644 index 0000000..f447fe6 --- /dev/null +++ b/pkgs/tpm2-tools/default.nix @@ -0,0 +1,48 @@ +{ + stdenv, + fetchurl, + lib, + pandoc, + pkg-config, + curl, + openssl, + patosPkgs, + libuuid, +}: + +stdenv.mkDerivation rec { + pname = "tpm2-tools"; + version = "5.7"; + + src = fetchurl { + url = "https://github.com/tpm2-software/${pname}/releases/download/${version}/${pname}-${version}.tar.gz"; + sha256 = "sha256-OBDTa1B5JW9PL3zlUuIiE9Q7EDHBMVON+KLbw8VwmDo="; + }; + + nativeBuildInputs = [ + pandoc + pkg-config + ]; + buildInputs = [ + curl + openssl + patosPkgs.tpm2-tss + libuuid + ]; + + # Unit tests disabled, as they rely on a dbus session + configureFlags = [ "--prefix=/" ]; + preInstall = '' + mkdir -p $out + export DESTDIR=$out + ''; + doCheck = false; + + meta = with lib; { + description = "Command line tools that provide access to a TPM 2.0 compatible device"; + homepage = "https://github.com/tpm2-software/tpm2-tools"; + license = licenses.bsd3; + platforms = platforms.linux; + maintainers = with maintainers; [ tomfitzhenry ]; + }; +} diff --git a/pkgs/tpm2-tss/default.nix b/pkgs/tpm2-tss/default.nix new file mode 100644 index 0000000..5e23100 --- /dev/null +++ b/pkgs/tpm2-tss/default.nix @@ -0,0 +1,86 @@ +{ + stdenv, + lib, + fetchFromGitHub, + autoreconfHook, + autoconf-archive, + pkg-config, + doxygen, + perl, + openssl, + json_c, + curl, + libgcrypt, + uthash, + git, + libuuid, + libtpms, +}: + +stdenv.mkDerivation rec { + pname = "tpm2-tss"; + version = "4.1.3"; + + src = fetchFromGitHub { + owner = "tpm2-software"; + repo = pname; + rev = version; + hash = "sha256-BP28utEUI9g1VNv3lCXuiKrDtEImFQxxZfIjLiE3Wr8="; + }; + + patches = [ + ./no-shadow.patch + ]; + + postPatch = '' + substituteInPlace ./bootstrap \ + --replace-fail 'git describe --tags --always --dirty' 'echo "${version}"' + ''; + + outputs = [ + "out" + ]; + + nativeBuildInputs = [ + autoreconfHook + autoconf-archive + pkg-config + doxygen + perl + git + ]; + + buildInputs = [ + openssl + json_c + curl + libgcrypt + uthash + libuuid + libtpms + ]; + + strictDeps = true; + preAutoreconf = "./bootstrap"; + + enableParallelBuilding = true; + + configureFlags = [ + "--prefix=/" + ]; + + preInstall = '' + mkdir -p $out + export DESTDIR=$out + ''; + + doCheck = false; + + meta = with lib; { + description = "OSS implementation of the TCG TPM2 Software Stack (TSS2)"; + homepage = "https://github.com/tpm2-software/tpm2-tss"; + license = licenses.bsd2; + platforms = platforms.unix; + maintainers = with maintainers; [ baloo ]; + }; +} diff --git a/pkgs/tpm2-tss/no-shadow.patch b/pkgs/tpm2-tss/no-shadow.patch new file mode 100644 index 0000000..a42bf06 --- /dev/null +++ b/pkgs/tpm2-tss/no-shadow.patch @@ -0,0 +1,16 @@ +diff --git a/configure.ac b/configure.ac +index e2d579b8..0eac4ff3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -672,9 +672,9 @@ AS_IF([test "$HOSTOS" = "Linux" && test "x$systemd_sysusers" != "xyes"], + AC_CHECK_PROG(adduser, adduser, yes) + AC_CHECK_PROG(addgroup, addgroup, yes) + AS_IF([test "x$addgroup" != "xyes" && test "x$groupadd" != "xyes" ], +- [AC_MSG_ERROR([addgroup or groupadd are needed.])]) ++ [AC_MSG_WARN([addgroup or groupadd are needed.])]) + AS_IF([test "x$adduser" != "xyes" && test "x$useradd" != "xyes" ], +- [AC_MSG_ERROR([adduser or useradd are needed.])])]) ++ [AC_MSG_WARN([adduser or useradd are needed.])])]) + + AC_SUBST([PATH]) + From 0a6fc3af49b1d05134a9bfd5c1941f7de71826b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 27 Feb 2025 08:59:01 +0100 Subject: [PATCH 17/67] chore: enable default networking and make root own erofs files --- pkgs/image/default.nix | 2 +- pkgs/image/mkimage.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 8348db4..c8b7749 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -22,7 +22,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { env = { # vfat options won't efi won't find the fs otherwise. SYSTEMD_REPART_MKFS_OPTIONS_VFAT = "-S 512 -c"; - SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; + SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; # -zlz4hc,level=12 -Efragments,dedupe,ztailpacking"; }; systemd = patosPkgs.systemd.out; diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 0a7ca0b..21dbe5f 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -24,6 +24,8 @@ ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.so ln -sf ../systemd-networkd.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-networkd.service ln -sf ../systemd-resolved.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-resolved.service ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.target.wants/systemd-timesyncd.service +# enable default network config +mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network # generate a temporary machine id (replace with overlay later) $systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ From adb2e90c13b98c6709066ac4ff2aa020a5e9774f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 3 Mar 2025 13:52:52 +0100 Subject: [PATCH 18/67] fix(image): image need to include devicemapper setup tools and udev rules --- flake.nix | 1 + pkgs/kernel/generic.config | 2 +- pkgs/lvm2/default.nix | 66 ++++++++++++++++++++++++++++++++++++++ pkgs/rootfs/default.nix | 2 ++ pkgs/rootfs/mkrootfs.sh | 52 ++++++++++++++++++++---------- utils/qemu-uefi-tpm.nix | 2 +- 6 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 pkgs/lvm2/default.nix diff --git a/flake.nix b/flake.nix index 071ae56..5c76b2f 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,7 @@ kernel = pkgs.callPackage ./pkgs/kernel { }; glibc = pkgs.callPackage ./pkgs/glibc { }; kexec = pkgs.callPackage ./pkgs/kexec-tools { }; + lvm2 = pkgs.callPackage ./pkgs/lvm2 { }; tpm2-tools = pkgs.callPackage ./pkgs/tpm2-tools { inherit patosPkgs; }; tpm2-tss = pkgs.callPackage ./pkgs/tpm2-tss { }; systemd = pkgs.callPackage ./pkgs/systemd { }; diff --git a/pkgs/kernel/generic.config b/pkgs/kernel/generic.config index c717915..0220e23 100644 --- a/pkgs/kernel/generic.config +++ b/pkgs/kernel/generic.config @@ -2213,7 +2213,7 @@ CONFIG_TCG_CRB=y CONFIG_TCG_TIS_CORE=y CONFIG_TCG_TIS=y CONFIG_TCG_TPM=y -CONFIG_TCG_TPM2_HMAC=y +CONFIG_TCG_TPM2_HMAC=n CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_BBR=y CONFIG_TCP_CONG_CUBIC=y diff --git a/pkgs/lvm2/default.nix b/pkgs/lvm2/default.nix new file mode 100644 index 0000000..f211e26 --- /dev/null +++ b/pkgs/lvm2/default.nix @@ -0,0 +1,66 @@ +{ + stdenv, + fetchurl, + lib, + pkg-config, + libaio, + udev, +}: + +stdenv.mkDerivation rec { + pname = "lvm2"; + version = "2.03.30"; + + src = fetchurl { + urls = [ + "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${version}.tgz" + "ftp://sourceware.org/pub/lvm2/LVM2.${version}.tgz" + ]; + hash = "sha256-rXar7LjciHcz4GxEnLmt0Eo1BvnweAwSiBem4aF87AU="; + }; + + nativeBuildInputs = [ + pkg-config + ]; + buildInputs = [ + libaio + udev + ]; + + configureFlags = [ + "--prefix=/" + "--sbindir=/usr/bin" + "--sysconfdir=/etc" + "--localstatedir=/var" + "--enable-cmdlib" + "--enable-dmeventd" + "--enable-lvmpolld" + "--enable-pkgconfig" + "--enable-udev_rules" + "--enable-udev_sync" + "--enable-write_install" + "--with-cache=internal" + "--with-thin=internal" + ]; + + preInstall = '' + mkdir -p $out + export DESTDIR=$out + ''; + doCheck = false; + + meta = with lib; { + homepage = "http://sourceware.org/lvm2/"; + description = "Tools to support Logical Volume Management (LVM) on Linux"; + platforms = platforms.linux; + license = with licenses; [ + gpl2Only + bsd2 + lgpl21 + ]; + maintainers = with maintainers; [ + raskin + ajs124 + ]; + }; +} diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index 4d7768b..20fe642 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -29,6 +29,8 @@ stdenvNoCC.mkDerivation (finalAttrs: { tpm2Libs = patosPkgs.tpm2-tss.out; tpm2Tools = patosPkgs.tpm2-tools.out; kexec = patosPkgs.kexec.out; + lvm2 = patosPkgs.lvm2.out; + cryptsetup = pkgs.cryptsetup.bin; builder = ./mkrootfs.sh; }) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 7d94052..538a7c9 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -15,6 +15,7 @@ cp -Pr $systemd/* $out/ find $out -type d -exec chmod 755 {} \; rm -rf $out/usr/include rm -rf $out/usr/sbin +ln -sf /usr/bin $out/usr/sbin rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service rm -f $out/usr/lib/systemd/ukify rm -f $out/usr/bin/ukify @@ -52,6 +53,13 @@ cat <<EOF > $out/etc/repart.d/22-root.conf Type=root EOF +mkdir $out/usr/lib/systemd/system/systemd-repart.service.d +cat <<EOF > $out/usr/lib/systemd/system/systemd-repart.service.d/override.conf +[Service] +ExecStart= +ExecStart=systemd-repart --dry-run=no --generate-crypttab=/etc/crypttab +EOF + cat <<EOF > $out/etc/repart.d/40-var.conf [Partition] Type=var @@ -59,26 +67,28 @@ UUID=4d21b016-b534-45c2-a9fb-5c16e091fd2d Format=btrfs Label=patos-state Minimize=off +Encrypt=tpm2 +EncryptedVolume=patos-state:none:tpm2-device=auto,luks,discard FactoryReset=yes SizeMinBytes=1G SplitName=- EOF -cat <<EOF > $out/usr/lib/systemd/system/var.mount -[Unit] -Description=Mount for /var -Before=local-fs.target -After=systemd-repart.service - -[Mount] -What=/dev/disk/by-label/patos-state -Where=/var -Type=btrfs -Options=defaults - -[Install] -WantedBy=multi-user.target -EOF +# cat <<EOF > $out/usr/lib/systemd/system/var.mount +# [Unit] +# Description=Mount for /var +# Before=local-fs.target +# After=systemd-repart.service +# +# [Mount] +# What=/dev/mapper/patos-state +# Where=/var +# Type=btrfs +# Options=defaults +# +# [Install] +# WantedBy=multi-user.target +# EOF cat <<EOF > $out/usr/lib/systemd/system/etc.mount [Unit] @@ -112,6 +122,11 @@ cp -r $dbusBroker/* $out/ ### install kexec cp -Pr ${kexec}/sbin/kexec $out/usr/bin/ +### install dmsetup udev rules +cp -P ${lvm2}/usr/bin/dmsetup $out/usr/bin/ +cp -P ${lvm2}/lib/libdevmapper.so* $out/usr/lib/ +cp -P ${lvm2}/lib/udev/rules.d/* $out/usr/lib/udev/rules.d/ + ### install btrfs progs cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ @@ -120,6 +135,9 @@ cp -Pr ${btrfs}/lib/* $out/usr/lib/ cp -P ${tpm2Tools}/bin/* $out/usr/bin/ cp -P ${tpm2Libs}/lib/*.so* $out/usr/lib/ +### install cryptsetup tools +cp -P $cryptsetup/bin/* $out/usr/bin/ + ### install lib kmod cp -P $kmodLibs/lib/* $out/usr/lib cp -P $kmodBin/bin/* $out/usr/bin @@ -193,11 +211,11 @@ EOF chmod 644 $out/etc/group ### Find and install all shared libs -find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | grep -v tpm2 | sort -u | xargs cp -t $out/usr/lib +find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | sort -u | xargs -I {} cp {} $out/usr/lib/ find $out -type f -executable -exec chmod 755 {} \; # FIXME: ELF patching. Is there a better way? -find $out -type f -executable -exec patchelf --set-rpath /lib:/usr/lib:/usr/lib/systemd {} \; +find $out -type f -executable -exec patchelf --set-rpath /lib:/usr/lib:/usr/lib/systemd:/usr/lib/cryptsetup {} \; find $out -type f -executable -exec patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 {} \; patchelf --remove-rpath $out/usr/lib/ld-linux-x86-64.so.2 diff --git a/utils/qemu-uefi-tpm.nix b/utils/qemu-uefi-tpm.nix index bb151c5..0193a27 100644 --- a/utils/qemu-uefi-tpm.nix +++ b/utils/qemu-uefi-tpm.nix @@ -24,7 +24,7 @@ pkgs.writeShellApplication { swtpm socket -d --tpmstate dir="$state" \ --ctrl type=unixio,path="$state/swtpm-sock" \ --tpm2 \ - --log level=20 + --log file="$state/swtpm.log",level=20 qemu-system-x86_64 \ -enable-kvm \ From 10090a75b0f5d7fd116a6656562c22879448f090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 4 Mar 2025 12:09:03 +0100 Subject: [PATCH 19/67] fix(image): finally have working mount of encrypted volumes! --- pkgs/image/mkimage.sh | 1 - pkgs/rootfs/mkinitrd.sh | 23 +++++++++++++++++++++++ pkgs/rootfs/mkrootfs.sh | 29 +++++++---------------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 21dbe5f..ce33fb7 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -14,7 +14,6 @@ ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target # mount /etc overlay and patos state ln -sf ../etc.mount rootfs/usr/lib/systemd/system/local-fs.target.wants/etc.mount -ln -sf ../var.mount rootfs/usr/lib/systemd/system/sysinit.target.wants/var.mount # enable dbus ln -sf ../dbus.service rootfs/usr/lib/systemd/system/multi-user.target.wants/dbus.service diff --git a/pkgs/rootfs/mkinitrd.sh b/pkgs/rootfs/mkinitrd.sh index c735448..e707f25 100644 --- a/pkgs/rootfs/mkinitrd.sh +++ b/pkgs/rootfs/mkinitrd.sh @@ -16,6 +16,29 @@ echo patos > ./etc/hostname ln -sf /etc/os-release ./etc/initrd-release +# set default target to initrd inside initrd +ln -sf initrd.target ./usr/lib/systemd/system/default.target + +mkdir ./usr/lib/systemd/system/systemd-repart.service.d +cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf +[Service] +ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab +EOF + +cat <<EOF > ./usr/lib/systemd/system/sysroot-run.mount +[Unit] +Before=initrd-fs.target +DefaultDependencies=false + +[Mount] +Options=bind +What=/run +Where=/sysroot/run +EOF +# bind mount /run to /sysroot/run +mkdir ./usr/lib/systemd/system/initrd-fs.target.requires/ +ln -sf ../sysroot-run.mount ./usr/lib/systemd/system/initrd-fs.target.requires/sysroot-run.mount + # gen initrd find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 538a7c9..8429cf0 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -53,13 +53,6 @@ cat <<EOF > $out/etc/repart.d/22-root.conf Type=root EOF -mkdir $out/usr/lib/systemd/system/systemd-repart.service.d -cat <<EOF > $out/usr/lib/systemd/system/systemd-repart.service.d/override.conf -[Service] -ExecStart= -ExecStart=systemd-repart --dry-run=no --generate-crypttab=/etc/crypttab -EOF - cat <<EOF > $out/etc/repart.d/40-var.conf [Partition] Type=var @@ -69,26 +62,18 @@ Label=patos-state Minimize=off Encrypt=tpm2 EncryptedVolume=patos-state:none:tpm2-device=auto,luks,discard +MountPoint=/var FactoryReset=yes SizeMinBytes=1G SplitName=- EOF -# cat <<EOF > $out/usr/lib/systemd/system/var.mount -# [Unit] -# Description=Mount for /var -# Before=local-fs.target -# After=systemd-repart.service -# -# [Mount] -# What=/dev/mapper/patos-state -# Where=/var -# Type=btrfs -# Options=defaults -# -# [Install] -# WantedBy=multi-user.target -# EOF +rm -f $out/etc/systemd/system.conf +cat <<EOF > $out/etc/systemd/system.conf +[Manager] +DefaultEnvironment=PATH=/bin:/sbin:/usr/bin +ManagerEnvironment=PATH=/bin:/sbin:/usr/bin SYSTEMD_CRYPTTAB=/run/crypttab SYSTEMD_SYSROOT_FSTAB=/run/fstab SYSTEMD_FSTAB=/run/fstab +EOF cat <<EOF > $out/usr/lib/systemd/system/etc.mount [Unit] From 83bb3599a4e8d3bbb7b443d6d69cab6d38dfb4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 4 Mar 2025 12:16:49 +0100 Subject: [PATCH 20/67] fix(repart): depend on sysroot-run mount --- pkgs/image/mkimage.sh | 2 +- pkgs/rootfs/mkinitrd.sh | 4 ++++ pkgs/rootfs/mkrootfs.sh | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index ce33fb7..0c6fad0 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -12,7 +12,7 @@ find rootfs/ -type d -exec chmod 755 {} \; # set default target to multi-user ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target -# mount /etc overlay and patos state +# mount /etc overlay ln -sf ../etc.mount rootfs/usr/lib/systemd/system/local-fs.target.wants/etc.mount # enable dbus diff --git a/pkgs/rootfs/mkinitrd.sh b/pkgs/rootfs/mkinitrd.sh index e707f25..c35b516 100644 --- a/pkgs/rootfs/mkinitrd.sh +++ b/pkgs/rootfs/mkinitrd.sh @@ -21,6 +21,10 @@ ln -sf initrd.target ./usr/lib/systemd/system/default.target mkdir ./usr/lib/systemd/system/systemd-repart.service.d cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf +[Unit] +After=sysroot-run.mount +Requires=sysroot-run.mount + [Service] ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab EOF diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 8429cf0..cdc43d5 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -39,9 +39,13 @@ cat <<EOF > $out/etc/issue EOF # replace agetty with busybox getty -sed -i 's#ExecStart=.*#ExecStart=-/sbin/getty -L %I 115200 vt100#' $out/usr/lib/systemd/system/serial-getty@.service +mkdir $out/usr/lib/systemd/system/serial-getty@.service.d +cat <<EOF > $out/usr/lib/systemd/system/serial-getty@.service.d/override.conf +[Service] +ExecStart= +ExecStart=-/sbin/getty -L %I 115200 vt100 +EOF -sed -i 's#After=\(.*\)#After=sysroot.mount \1#' $out/usr/lib/systemd/system/systemd-repart.service cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] Type=esp From 529061df5eb80f1451d9672dacf3d1a7bec480c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 4 Mar 2025 14:08:13 +0100 Subject: [PATCH 21/67] chore: clean up comments --- pkgs/rootfs/mkinitrd.sh | 3 ++- pkgs/rootfs/mkrootfs.sh | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/rootfs/mkinitrd.sh b/pkgs/rootfs/mkinitrd.sh index c35b516..7f948f7 100644 --- a/pkgs/rootfs/mkinitrd.sh +++ b/pkgs/rootfs/mkinitrd.sh @@ -19,6 +19,7 @@ ln -sf /etc/os-release ./etc/initrd-release # set default target to initrd inside initrd ln -sf initrd.target ./usr/lib/systemd/system/default.target +# generate crypttab and fstab under /run mkdir ./usr/lib/systemd/system/systemd-repart.service.d cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf [Unit] @@ -29,6 +30,7 @@ Requires=sysroot-run.mount ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab EOF +# bind mount /run to /sysroot/run cat <<EOF > ./usr/lib/systemd/system/sysroot-run.mount [Unit] Before=initrd-fs.target @@ -39,7 +41,6 @@ Options=bind What=/run Where=/sysroot/run EOF -# bind mount /run to /sysroot/run mkdir ./usr/lib/systemd/system/initrd-fs.target.requires/ ln -sf ../sysroot-run.mount ./usr/lib/systemd/system/initrd-fs.target.requires/sysroot-run.mount diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index cdc43d5..aedcf6a 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -72,6 +72,8 @@ SizeMinBytes=1G SplitName=- EOF +# as rootfs is read-only we need to configure the fstab and cryptsetup generators to look +# for config under /run (which are generated by systemd-repart) rm -f $out/etc/systemd/system.conf cat <<EOF > $out/etc/systemd/system.conf [Manager] From e5367bac84f0a5535761d8d581c783aab5b2fdca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 4 Mar 2025 14:20:13 +0100 Subject: [PATCH 22/67] chore: more clean up --- pkgs/rootfs/mkinitrd.sh | 24 +++++++++++++----------- pkgs/rootfs/mkrootfs.sh | 4 +++- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/pkgs/rootfs/mkinitrd.sh b/pkgs/rootfs/mkinitrd.sh index 7f948f7..43708d0 100644 --- a/pkgs/rootfs/mkinitrd.sh +++ b/pkgs/rootfs/mkinitrd.sh @@ -19,17 +19,6 @@ ln -sf /etc/os-release ./etc/initrd-release # set default target to initrd inside initrd ln -sf initrd.target ./usr/lib/systemd/system/default.target -# generate crypttab and fstab under /run -mkdir ./usr/lib/systemd/system/systemd-repart.service.d -cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf -[Unit] -After=sysroot-run.mount -Requires=sysroot-run.mount - -[Service] -ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab -EOF - # bind mount /run to /sysroot/run cat <<EOF > ./usr/lib/systemd/system/sysroot-run.mount [Unit] @@ -44,6 +33,19 @@ EOF mkdir ./usr/lib/systemd/system/initrd-fs.target.requires/ ln -sf ../sysroot-run.mount ./usr/lib/systemd/system/initrd-fs.target.requires/sysroot-run.mount +# repart: generate crypttab and fstab under /run +mkdir ./usr/lib/systemd/system/systemd-repart.service.d +cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf +[Unit] +After=sysroot-run.mount +Requires=sysroot-run.mount + +[Service] +Environment=SYSTEMD_REPART_MKFS_OPTIONS_BTRFS=--nodiscard +ExecStart= +ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab +EOF + # gen initrd find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index aedcf6a..8fdda39 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -46,6 +46,7 @@ ExecStart= ExecStart=-/sbin/getty -L %I 115200 vt100 EOF +# Configure systemd-repart cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] Type=esp @@ -73,7 +74,7 @@ SplitName=- EOF # as rootfs is read-only we need to configure the fstab and cryptsetup generators to look -# for config under /run (which are generated by systemd-repart) +# for config under /run (which are generated by systemd-repart in initrd) rm -f $out/etc/systemd/system.conf cat <<EOF > $out/etc/systemd/system.conf [Manager] @@ -81,6 +82,7 @@ DefaultEnvironment=PATH=/bin:/sbin:/usr/bin ManagerEnvironment=PATH=/bin:/sbin:/usr/bin SYSTEMD_CRYPTTAB=/run/crypttab SYSTEMD_SYSROOT_FSTAB=/run/fstab SYSTEMD_FSTAB=/run/fstab EOF +# Overlay mount for /etc which makes it read-write in runtime cat <<EOF > $out/usr/lib/systemd/system/etc.mount [Unit] Description=Overlay mount for /etc From 8e61f85f725985a7f5ef278a51fc9d6c0989f340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 4 Mar 2025 15:31:03 +0100 Subject: [PATCH 23/67] chore: clean up var-repart config --- pkgs/rootfs/mkrootfs.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 8fdda39..31fc347 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -61,16 +61,14 @@ EOF cat <<EOF > $out/etc/repart.d/40-var.conf [Partition] Type=var -UUID=4d21b016-b534-45c2-a9fb-5c16e091fd2d Format=btrfs +MountPoint=/var Label=patos-state -Minimize=off Encrypt=tpm2 EncryptedVolume=patos-state:none:tpm2-device=auto,luks,discard -MountPoint=/var -FactoryReset=yes SizeMinBytes=1G -SplitName=- +Minimize=off +FactoryReset=yes EOF # as rootfs is read-only we need to configure the fstab and cryptsetup generators to look From 12bacf271db414e1f94de8e9dcda8b497df3f9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Tue, 4 Mar 2025 21:47:19 +0100 Subject: [PATCH 24/67] feat: generate passwd/group with systemd-sysusers --- flake.nix | 1 + pkgs/busybox/clang-cross.patch | 37 ++++++ pkgs/busybox/default.nix | 219 +++++++++++++++++++++++++++++++++ pkgs/rootfs/default.nix | 2 +- pkgs/rootfs/mkrootfs.sh | 65 +--------- 5 files changed, 262 insertions(+), 62 deletions(-) create mode 100644 pkgs/busybox/clang-cross.patch create mode 100644 pkgs/busybox/default.nix diff --git a/flake.nix b/flake.nix index 5c76b2f..97a1f97 100644 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,7 @@ }; kernel = pkgs.callPackage ./pkgs/kernel { }; glibc = pkgs.callPackage ./pkgs/glibc { }; + busybox = pkgs.callPackage ./pkgs/busybox { }; kexec = pkgs.callPackage ./pkgs/kexec-tools { }; lvm2 = pkgs.callPackage ./pkgs/lvm2 { }; tpm2-tools = pkgs.callPackage ./pkgs/tpm2-tools { inherit patosPkgs; }; diff --git a/pkgs/busybox/clang-cross.patch b/pkgs/busybox/clang-cross.patch new file mode 100644 index 0000000..b2d696b --- /dev/null +++ b/pkgs/busybox/clang-cross.patch @@ -0,0 +1,37 @@ +diff --git a/Makefile b/Makefile +index 6fedcffba..3385836c4 100644 +--- a/Makefile ++++ b/Makefile +@@ -271,8 +271,8 @@ export quiet Q KBUILD_VERBOSE + # Look for make include files relative to root of kernel src + MAKEFLAGS += --include-dir=$(srctree) + +-HOSTCC = gcc +-HOSTCXX = g++ ++HOSTCC = cc ++HOSTCXX = c++ + HOSTCFLAGS := + HOSTCXXFLAGS := + # We need some generic definitions +@@ -289,7 +289,7 @@ MAKEFLAGS += -rR + # Make variables (CC, etc...) + + AS = $(CROSS_COMPILE)as +-CC = $(CROSS_COMPILE)gcc ++CC = $(CROSS_COMPILE)cc + LD = $(CC) -nostdlib + CPP = $(CC) -E + AR = $(CROSS_COMPILE)ar +diff --git a/scripts/Makefile.IMA b/scripts/Makefile.IMA +index f155108d7..185257064 100644 +--- a/scripts/Makefile.IMA ++++ b/scripts/Makefile.IMA +@@ -39,7 +39,7 @@ ifndef HOSTCC + HOSTCC = cc + endif + AS = $(CROSS_COMPILE)as +-CC = $(CROSS_COMPILE)gcc ++CC = $(CROSS_COMPILE)cc + LD = $(CC) -nostdlib + CPP = $(CC) -E + AR = $(CROSS_COMPILE)ar diff --git a/pkgs/busybox/default.nix b/pkgs/busybox/default.nix new file mode 100644 index 0000000..571d0cf --- /dev/null +++ b/pkgs/busybox/default.nix @@ -0,0 +1,219 @@ +{ + stdenv, + lib, + buildPackages, + fetchurl, + fetchpatch, + fetchFromGitLab, + enableStatic ? stdenv.hostPlatform.isStatic, + enableMinimal ? false, + enableAppletSymlinks ? true, + # Allow forcing musl without switching stdenv itself, e.g. for our bootstrapping: + # nix build -f pkgs/top-level/release.nix stdenvBootstrapTools.x86_64-linux.dist + useMusl ? stdenv.hostPlatform.libc == "musl", + musl, + extraConfig ? "", +}: + +assert stdenv.hostPlatform.libc == "musl" -> useMusl; + +let + configParser = '' + function parseconfig { + while read LINE; do + NAME=`echo "$LINE" | cut -d \ -f 1` + OPTION=`echo "$LINE" | cut -d \ -f 2` + + if ! [[ "$NAME" =~ ^CONFIG_ ]]; then continue; fi + + echo "parseconfig: removing $NAME" + sed -i /$NAME'\(=\| \)'/d .config + + echo "parseconfig: setting $NAME=$OPTION" + echo "$NAME=$OPTION" >> .config + done + } + ''; + + libcConfig = lib.optionalString useMusl '' + CONFIG_FEATURE_UTMP n + CONFIG_FEATURE_WTMP n + ''; + + # The debian version lags behind the upstream version and also contains + # a debian-specific suffix. We only fetch the debian repository to get the + # default.script + debianVersion = "1.30.1-6"; + debianSource = fetchFromGitLab { + domain = "salsa.debian.org"; + owner = "installer-team"; + repo = "busybox"; + rev = "debian/1%${debianVersion}"; + sha256 = "sha256-6r0RXtmqGXtJbvLSD1Ma1xpqR8oXL2bBKaUE/cSENL8="; + }; + debianDispatcherScript = "${debianSource}/debian/tree/udhcpc/etc/udhcpc/default.script"; + outDispatchPath = "$out/default.script"; +in + +stdenv.mkDerivation rec { + pname = "busybox"; + version = "1.36.1"; + + # Note to whoever is updating busybox: please verify that: + # nix-build pkgs/stdenv/linux/make-bootstrap-tools.nix -A test + # still builds after the update. + src = fetchurl { + url = "https://busybox.net/downloads/${pname}-${version}.tar.bz2"; + sha256 = "sha256-uMwkyVdNgJ5yecO+NJeVxdXOtv3xnKcJ+AzeUOR94xQ="; + }; + + hardeningDisable = [ + "format" + "pie" + ] ++ lib.optionals enableStatic [ "fortify" ]; + + patches = [ + (fetchurl { + name = "CVE-2022-28391.patch"; + url = "https://git.alpinelinux.org/aports/plain/main/busybox/0001-libbb-sockaddr2str-ensure-only-printable-characters-.patch?id=ed92963eb55bbc8d938097b9ccb3e221a94653f4"; + sha256 = "sha256-yviw1GV+t9tbHbY7YNxEqPi7xEreiXVqbeRyf8c6Awo="; + }) + (fetchurl { + name = "CVE-2022-28391.patch"; + url = "https://git.alpinelinux.org/aports/plain/main/busybox/0002-nslookup-sanitize-all-printed-strings-with-printable.patch?id=ed92963eb55bbc8d938097b9ccb3e221a94653f4"; + sha256 = "sha256-vl1wPbsHtXY9naajjnTicQ7Uj3N+EQ8pRNnrdsiow+w="; + }) + (fetchpatch { + name = "CVE-2022-48174.patch"; # https://bugs.busybox.net/show_bug.cgi?id=15216 + url = "https://git.busybox.net/busybox/patch/?id=d417193cf37ca1005830d7e16f5fa7e1d8a44209"; + hash = "sha256-mpDEwYncpU6X6tmtj9xM2KCrB/v2ys5bYxmPPrhm6es="; + }) + (fetchpatch { + name = "CVE-2023-42366.patch"; # https://bugs.busybox.net/show_bug.cgi?id=15874 + # This patch is also used by Alpine, see https://git.alpinelinux.org/aports/tree/main/busybox/0037-awk.c-fix-CVE-2023-42366-bug-15874.patch + url = "https://bugs.busybox.net/attachment.cgi?id=9697"; + hash = "sha256-2eYfLZLjStea9apKXogff6sCAdG9yHx0ZsgUBaGfQIA="; + }) + (fetchpatch { + name = "CVE-2023-42363.patch"; # https://bugs.busybox.net/show_bug.cgi?id=15865 + url = "https://git.launchpad.net/ubuntu/+source/busybox/plain/debian/patches/CVE-2023-42363.patch?id=c9d8a323b337d58e302717d41796aa0242963d5a"; + hash = "sha256-1W9Q8+yFkYQKzNTrvndie8QuaEbyAFL1ZASG2fPF+Z4="; + }) + (fetchpatch { + name = "CVE-2023-42364_CVE-2023-42365.patch"; # https://bugs.busybox.net/show_bug.cgi?id=15871 https://bugs.busybox.net/show_bug.cgi?id=15868 + url = "https://git.alpinelinux.org/aports/plain/main/busybox/CVE-2023-42364-CVE-2023-42365.patch?id=8a4bf5971168bf48201c05afda7bee0fbb188e13"; + hash = "sha256-nQPgT9eA1asCo38Z9X7LR9My0+Vz5YBPba3ARV3fWcc="; + }) + ] ++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) ./clang-cross.patch; + + separateDebugInfo = true; + + # postPatch = "patchShebangs ."; + + configurePhase = '' + export KCONFIG_NOTIMESTAMP=1 + make ${if enableMinimal then "allnoconfig" else "defconfig"} + + ${configParser} + + cat << EOF | parseconfig + + CONFIG_PREFIX "$out" + CONFIG_INSTALL_NO_USR y + + CONFIG_LFS y + + # More features for modprobe. + ${lib.optionalString (!enableMinimal) '' + CONFIG_FEATURE_MODPROBE_BLACKLIST y + CONFIG_FEATURE_MODUTILS_ALIAS y + CONFIG_FEATURE_MODUTILS_SYMBOLS y + CONFIG_MODPROBE_SMALL n + ''} + + ${lib.optionalString enableStatic '' + CONFIG_STATIC y + ''} + + ${lib.optionalString (!enableAppletSymlinks) '' + CONFIG_INSTALL_APPLET_DONT y + CONFIG_INSTALL_APPLET_SYMLINKS n + ''} + + # Use the external mount.cifs program. + CONFIG_FEATURE_MOUNT_CIFS n + CONFIG_FEATURE_MOUNT_HELPERS y + + # BB_SHADOW + FEATURE_SHADOWPASSWDS y + CONFIG_USE_BB_PWD_GRP y + CONFIG_USE_BB_SHADOW y + CONFIG_USE_BB_CRYPT y + USE_BB_CRYPT_SHA y + CONFIG_FEATURE_DEFAULT_PASSWD_ALGO "sha512" + + # Set paths for console fonts. + CONFIG_DEFAULT_SETFONT_DIR "/etc/kbd" + + # Bump from 4KB, much faster I/O + CONFIG_FEATURE_COPYBUF_KB 64 + + # Doesn't build with current kernel headers. + # https://bugs.busybox.net/show_bug.cgi?id=15934 + CONFIG_TC n + + # Set the path for the udhcpc script + CONFIG_UDHCPC_DEFAULT_SCRIPT "${outDispatchPath}" + + ${extraConfig} + CONFIG_CROSS_COMPILER_PREFIX "${stdenv.cc.targetPrefix}" + ${libcConfig} + EOF + + make oldconfig + + runHook postConfigure + ''; + + postConfigure = lib.optionalString (useMusl && stdenv.hostPlatform.libc != "musl") '' + makeFlagsArray+=("CC=${stdenv.cc.targetPrefix}cc -isystem ${musl.dev}/include -B${musl}/lib -L${musl}/lib") + ''; + + makeFlags = [ "SKIP_STRIP=y" ]; + + postInstall = '' + sed -e ' + 1 a busybox() { '$out'/bin/busybox "$@"; }\ + logger() { '$out'/bin/logger "$@"; }\ + ' ${debianDispatcherScript} > ${outDispatchPath} + chmod 555 ${outDispatchPath} + HOST_PATH=$out/bin patchShebangs --host ${outDispatchPath} + ''; + + strictDeps = true; + + depsBuildBuild = [ buildPackages.stdenv.cc ]; + + buildInputs = lib.optionals (enableStatic && !useMusl && stdenv.cc.libc ? static) [ + stdenv.cc.libc + stdenv.cc.libc.static + ]; + + enableParallelBuilding = true; + + doCheck = false; # tries to access the net + + passthru.shellPath = "/bin/ash"; + + meta = with lib; { + description = "Tiny versions of common UNIX utilities in a single small executable"; + homepage = "https://busybox.net/"; + license = licenses.gpl2Only; + maintainers = with maintainers; [ + TethysSvensson + qyliss + ]; + platforms = platforms.linux; + priority = 15; # below systemd (halt, init, poweroff, reboot) and coreutils + }; +} diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index 20fe642..dd0e2a7 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -21,7 +21,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { systemd = patosPkgs.systemd.out; dbusBroker = patosPkgs.dbus-broker.out; kernel = patosPkgs.kernel.kernel; - busybox = pkgs.busybox.out; + busybox = patosPkgs.busybox.out; kmodLibs = pkgs.kmod.lib; kmodBin = pkgs.kmod.out; libbpf = pkgs.libbpf.out; diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 31fc347..d86ae78 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -139,67 +139,10 @@ cp -P $libbpf/lib/libbpf* $out/usr/lib # remove pkgconfig rm -rf $out/usr/lib/pkgconfig -cat <<EOF > $out/etc/passwd -root::0:0:root:/root:/bin/sh -bin:x:1:1:bin:/bin:/usr/bin/nologin -daemon:x:2:2:daemon:/:/usr/bin/nologin -mail:x:8:12:mail:/var/spool/mail:/usr/bin/nologin -ftp:x:14:11:ftp:/srv/ftp:/usr/bin/nologin -http:x:33:33:http:/srv/http:/usr/bin/nologin -uuidd:x:68:68:uuidd:/:/usr/bin/nologin -messagebus:x:81:81:messagebus:/:/usr/bin/nologin -nobody:x:99:99:nobody:/:/usr/bin/nologin -systemd-coredump:x:151:992::/var/empty:/usr/bin/nologin -systemd-network:x:152:152::/var/empty:/usr/bin/nologin -systemd-resolve:x:153:153::/var/empty:/usr/bin/nologin -systemd-timesync:x:154:154::/var/empty:/usr/bin/nologin -EOF -chmod 644 $out/etc/passwd - -cat <<EOF > $out/etc/group -root:x:0:root -bin:x:1:root,bin,daemon -daemon:x:2:root,bin,daemon -sys:x:3:root,bin -adm:x:4:root,daemon -tty:x:5: -disk:x:6:root -lp:x:7:daemon -mem:x:8: -kmem:x:9: -wheel:x:10:root -ftp:x:11: -mail:x:12: -uucp:x:14: -log:x:19:root -utmp:x:20: -locate:x:21: -rfkill:x:24: -smmsp:x:25: -proc:x:26: -http:x:33: -games:x:50: -lock:x:54: -uuidd:x:68: -messagebus:x:81: -systemd-journal:x:62: -systemd-network:x:152: -systemd-resolve:x:153: -systemd-timesync:x:154: -systemd-oom:x:991: -systemd-coredump:x:992: -network:x:90: -video:x:91: -audio:x:92: -optical:x:93: -floppy:x:94: -storage:x:95: -scanner:x:96: -input:x:97: -power:x:98: -nobody:x:99: -EOF -chmod 644 $out/etc/group +### install sys users (default password is patos) +mkdir creds +echo -n patos > creds/passwd.plaintext-password.root +CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=$out $out/usr/lib/sysusers.d/*.conf ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | sort -u | xargs -I {} cp {} $out/usr/lib/ From 879f74befab0a2517b0d9586636967cf84b3cab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 5 Mar 2025 08:24:54 +0100 Subject: [PATCH 25/67] chore: remove unused logind and sysuser for dbus svc --- pkgs/dbus-broker/default.nix | 3 +++ pkgs/image/mkimage.sh | 7 +++++++ pkgs/rootfs/mkrootfs.sh | 5 ----- pkgs/systemd/default.nix | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pkgs/dbus-broker/default.nix b/pkgs/dbus-broker/default.nix index 156c490..809f3ce 100644 --- a/pkgs/dbus-broker/default.nix +++ b/pkgs/dbus-broker/default.nix @@ -154,6 +154,9 @@ stdenv.mkDerivation (finalAttrs: { find $out/usr/share/ -type d -exec chmod 755 {} \; sed -i 's#/nix/store.*/share#/usr/share#' $out/usr/share/xml/dbus-1/catalog.xml sed -i 's#/nix/store.*/libexec#/usr/bin#' $out/usr/share/dbus-1/system.conf + + mkdir -p $out/usr/lib/sysusers.d/ + echo 'u! messagebus - "DBus broker"' > $out/usr/lib/sysusers.d/dbus-broker.conf ''; doCheck = false; diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 0c6fad0..b104525 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -26,6 +26,13 @@ ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.tar # enable default network config mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network +### install sys users (default password is patos) +mkdir creds +echo -n patos > creds/passwd.plaintext-password.root +CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=rootfs rootfs/usr/lib/sysusers.d/*.conf +chmod 600 rootfs/etc/shadow +cat rootfs/etc/shadow + # generate a temporary machine id (replace with overlay later) $systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index d86ae78..62bfe56 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -139,11 +139,6 @@ cp -P $libbpf/lib/libbpf* $out/usr/lib # remove pkgconfig rm -rf $out/usr/lib/pkgconfig -### install sys users (default password is patos) -mkdir creds -echo -n patos > creds/passwd.plaintext-password.root -CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=$out $out/usr/lib/sysusers.d/*.conf - ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | sort -u | xargs -I {} cp {} $out/usr/lib/ find $out -type f -executable -exec chmod 755 {} \; diff --git a/pkgs/systemd/default.nix b/pkgs/systemd/default.nix index 6f5c6c9..db53c60 100644 --- a/pkgs/systemd/default.nix +++ b/pkgs/systemd/default.nix @@ -287,7 +287,7 @@ stdenv.mkDerivation (finalAttrs: { (lib.mesonEnable "man" false) (lib.mesonBool "analyze" true) - (lib.mesonBool "logind" true) + (lib.mesonBool "logind" false) (lib.mesonBool "localed" false) (lib.mesonBool "hostnamed" true) (lib.mesonBool "machined" true) From 0a129b548927958925fe7f4aec962874c2ec573f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 5 Mar 2025 08:45:34 +0100 Subject: [PATCH 26/67] chore: clean up --- pkgs/image/default.nix | 2 ++ pkgs/image/mkimage.sh | 20 +++++++++++++++++--- pkgs/rootfs/mkrootfs.sh | 23 +++-------------------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index c8b7749..ba783f7 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -7,10 +7,12 @@ }: let pname = "patos-image"; + defaultPassword = "patos"; in stdenvNoCC.mkDerivation (finalAttrs: { inherit version; inherit pname; + inherit defaultPassword; buildInputs = with pkgs; [ erofs-utils diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index b104525..d4975ab 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -12,7 +12,21 @@ find rootfs/ -type d -exec chmod 755 {} \; # set default target to multi-user ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target -# mount /etc overlay +# Overlay mount for /etc which makes it read-write in runtime +cat <<EOF > rootfs/usr/lib/systemd/system/etc.mount +[Unit] +Description=Overlay mount for /etc +Before=local-fs.target + +[Mount] +What=overlay +Where=/etc +Type=overlay +Options=lowerdir=/etc,upperdir=/run/.rw-etc/upper,workdir=/run/.rw-etc/work + +[Install] +WantedBy=local-fs.target +EOF ln -sf ../etc.mount rootfs/usr/lib/systemd/system/local-fs.target.wants/etc.mount # enable dbus @@ -26,9 +40,9 @@ ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.tar # enable default network config mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network -### install sys users (default password is patos) +# install sys users mkdir creds -echo -n patos > creds/passwd.plaintext-password.root +echo -n $defaultPassword > creds/passwd.plaintext-password.root CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=rootfs rootfs/usr/lib/sysusers.d/*.conf chmod 600 rootfs/etc/shadow cat rootfs/etc/shadow diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 62bfe56..110b1e4 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -80,22 +80,6 @@ DefaultEnvironment=PATH=/bin:/sbin:/usr/bin ManagerEnvironment=PATH=/bin:/sbin:/usr/bin SYSTEMD_CRYPTTAB=/run/crypttab SYSTEMD_SYSROOT_FSTAB=/run/fstab SYSTEMD_FSTAB=/run/fstab EOF -# Overlay mount for /etc which makes it read-write in runtime -cat <<EOF > $out/usr/lib/systemd/system/etc.mount -[Unit] -Description=Overlay mount for /etc -Before=local-fs.target - -[Mount] -What=overlay -Where=/etc -Type=overlay -Options=lowerdir=/etc,upperdir=/run/.rw-etc/upper,workdir=/run/.rw-etc/work - -[Install] -WantedBy=local-fs.target -EOF - ### install PatOS glibc cp -P $glibcPatos/lib/*.so* $out/usr/lib/ @@ -123,12 +107,11 @@ cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ ### install tpm2 tools -cp -P ${tpm2Tools}/bin/* $out/usr/bin/ +# For TPM debugging +# cp -P ${tpm2Tools}/bin/* $out/usr/bin/ +# cp -P $cryptsetup/bin/* $out/usr/bin/ cp -P ${tpm2Libs}/lib/*.so* $out/usr/lib/ -### install cryptsetup tools -cp -P $cryptsetup/bin/* $out/usr/bin/ - ### install lib kmod cp -P $kmodLibs/lib/* $out/usr/lib cp -P $kmodBin/bin/* $out/usr/bin From be4efca9a55ce89447c9e75bb134be5b37899637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 5 Mar 2025 09:46:28 +0100 Subject: [PATCH 27/67] chore: temporary generate machine-id on boot until we have a confext --- pkgs/image/mkimage.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index d4975ab..52a3b60 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -40,15 +40,23 @@ ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.tar # enable default network config mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network +# FIXME: remove this! machine id should be setup by a confext instead? +mkdir rootfs/usr/lib/systemd/system/systemd-machine-id-commit.service.d +cat <<EOF > rootfs/usr/lib/systemd/system/systemd-machine-id-commit.service.d/override.conf +[Unit] +After=local-fs.target sysroot-etc.mount +ConditionPathIsMountPoint= +[Service] +ExecStart= +ExecStart=systemd-machine-id-setup +EOF + # install sys users mkdir creds echo -n $defaultPassword > creds/passwd.plaintext-password.root CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=rootfs rootfs/usr/lib/sysusers.d/*.conf chmod 600 rootfs/etc/shadow -cat rootfs/etc/shadow - -# generate a temporary machine id (replace with overlay later) -$systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ +rm -rf creds $systemd/usr/bin/ukify build \ --linux $kernel/bzImage \ From 18c8e76850d44c5218f24427b1a0c18ceb56079b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 5 Mar 2025 10:08:12 +0100 Subject: [PATCH 28/67] revert to static machine id for now --- pkgs/image/mkimage.sh | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 52a3b60..ad7d57d 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -40,16 +40,8 @@ ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.tar # enable default network config mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network -# FIXME: remove this! machine id should be setup by a confext instead? -mkdir rootfs/usr/lib/systemd/system/systemd-machine-id-commit.service.d -cat <<EOF > rootfs/usr/lib/systemd/system/systemd-machine-id-commit.service.d/override.conf -[Unit] -After=local-fs.target sysroot-etc.mount -ConditionPathIsMountPoint= -[Service] -ExecStart= -ExecStart=systemd-machine-id-setup -EOF +#FIXME: generate a temporary machine id (replace with overlay/confext later?) +$systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ # install sys users mkdir creds From 62dd1ca5bfcee730f0e8738513cdf89bb8790ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 5 Mar 2025 16:24:34 +0100 Subject: [PATCH 29/67] feat: enable conf/sys ext services and make /etc read-only without overlay --- pkgs/image/mkimage.sh | 22 +++------------------- pkgs/kernel/generic.config | 3 ++- pkgs/rootfs/default.nix | 4 +++- pkgs/rootfs/mkrootfs.sh | 21 ++++++++++++++++++--- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index ad7d57d..c08f0d8 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -12,23 +12,6 @@ find rootfs/ -type d -exec chmod 755 {} \; # set default target to multi-user ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target -# Overlay mount for /etc which makes it read-write in runtime -cat <<EOF > rootfs/usr/lib/systemd/system/etc.mount -[Unit] -Description=Overlay mount for /etc -Before=local-fs.target - -[Mount] -What=overlay -Where=/etc -Type=overlay -Options=lowerdir=/etc,upperdir=/run/.rw-etc/upper,workdir=/run/.rw-etc/work - -[Install] -WantedBy=local-fs.target -EOF -ln -sf ../etc.mount rootfs/usr/lib/systemd/system/local-fs.target.wants/etc.mount - # enable dbus ln -sf ../dbus.service rootfs/usr/lib/systemd/system/multi-user.target.wants/dbus.service ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket @@ -40,8 +23,9 @@ ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.tar # enable default network config mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network -#FIXME: generate a temporary machine id (replace with overlay/confext later?) -$systemd/usr/bin/systemd-machine-id-setup --root=rootfs/ +# enable confext/sysext services +ln -sf ../systemd-confext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-confext.service +ln -sf ../systemd-sysext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-sysext.service # install sys users mkdir creds diff --git a/pkgs/kernel/generic.config b/pkgs/kernel/generic.config index 0220e23..209e026 100644 --- a/pkgs/kernel/generic.config +++ b/pkgs/kernel/generic.config @@ -591,7 +591,8 @@ CONFIG_DM_SWITCH=m CONFIG_DM_THIN_PROVISIONING=m CONFIG_DM_UNSTRIPED=m CONFIG_DM_VDO=m -CONFIG_DM_VERITY=m +CONFIG_DM_VERITY=y +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y CONFIG_DM_WRITECACHE=m CONFIG_DM_ZERO=y CONFIG_DM_ZONED=m diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index dd0e2a7..5ac9c6a 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -27,10 +27,12 @@ stdenvNoCC.mkDerivation (finalAttrs: { libbpf = pkgs.libbpf.out; btrfs = pkgs.btrfs-progs.out; tpm2Libs = patosPkgs.tpm2-tss.out; - tpm2Tools = patosPkgs.tpm2-tools.out; kexec = patosPkgs.kexec.out; lvm2 = patosPkgs.lvm2.out; + # FIXME: remove later: + tpm2Tools = patosPkgs.tpm2-tools.out; cryptsetup = pkgs.cryptsetup.bin; + erofsUtils = pkgs.erofs-utils.out; builder = ./mkrootfs.sh; }) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 110b1e4..78d14d3 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -29,8 +29,8 @@ IMAGE_ID=patos ID=patos IMAGE_VERSION=${version} VERSION=${version} -VERSION_ID={version} -BUILD_ID={version} +VERSION_ID=patos +BUILD_ID=somehash EOF cat <<EOF > $out/etc/issue @@ -106,6 +106,9 @@ cp -P ${lvm2}/lib/udev/rules.d/* $out/usr/lib/udev/rules.d/ cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ +##FIXME(remove later): install mkfs.erofs bin +cp -P ${erofsUtils}/bin/mkfs.erofs $out/usr/bin/ + ### install tpm2 tools # For TPM debugging # cp -P ${tpm2Tools}/bin/* $out/usr/bin/ @@ -119,11 +122,23 @@ cp -P $kmodBin/bin/* $out/usr/bin ### install libbpf cp -P $libbpf/lib/libbpf* $out/usr/lib +# setup default files +$systemd/usr/bin/systemd-hwdb --root=$out --usr update +$systemd/usr/bin/systemd-tmpfiles --root=$out $out/usr/lib/tmpfiles.d/etc.conf --create +cp $out/usr/share/factory/etc/nsswitch.conf $out/etc/ +cp $out/usr/share/factory/etc/locale.conf $out/etc/ +cp $out/usr/share/factory/etc/vconsole.conf $out/etc/ +#Ephemeral machine-id until registration +ln -sf /run/machine-id $out/etc/machine-id + + # remove pkgconfig rm -rf $out/usr/lib/pkgconfig ### Find and install all shared libs -find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | sort -u | xargs -I {} cp {} $out/usr/lib/ +find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ + grep -v util-linux-2 | grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | \ + sort -u | xargs -I {} cp {} $out/usr/lib/ find $out -type f -executable -exec chmod 755 {} \; # FIXME: ELF patching. Is there a better way? From 658b5af153d4d64369a3fcb4877598380cb8f4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 6 Mar 2025 16:15:29 +0100 Subject: [PATCH 30/67] chore: even better erofs compression --- pkgs/image/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index ba783f7..4da5187 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -24,7 +24,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { env = { # vfat options won't efi won't find the fs otherwise. SYSTEMD_REPART_MKFS_OPTIONS_VFAT = "-S 512 -c"; - SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; # -zlz4hc,level=12 -Efragments,dedupe,ztailpacking"; + SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; # -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; }; systemd = patosPkgs.systemd.out; From d1e25bdddf5ea012ffa94e5fbc84151583cb9edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 6 Mar 2025 16:26:13 +0100 Subject: [PATCH 31/67] chore: upgrade systemd to latest stable --- pkgs/systemd/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/systemd/default.nix b/pkgs/systemd/default.nix index db53c60..b22d243 100644 --- a/pkgs/systemd/default.nix +++ b/pkgs/systemd/default.nix @@ -7,7 +7,7 @@ ... }: let - version = "257.3"; + version = "257.4"; # Use the command below to update `releaseTimestamp` on every (major) version # change. More details in the commentary at mesonFlags. @@ -27,7 +27,7 @@ stdenv.mkDerivation (finalAttrs: { owner = "systemd"; repo = "systemd"; rev = "v${version}"; - hash = "sha256-GvRn55grHWR6M+tA86RMzqinuXNpPZzRB4ApuGN/ZvU="; + hash = "sha256-6rxJUYRq785U6aik5VhQRqG+Ss67lBB6T3eQF+tkyhk="; }; dontCheckForBrokenSymlinks = true; From 3f443a9e9bd1c801d31d896b59dcd718e11a0ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 6 Mar 2025 17:17:53 +0100 Subject: [PATCH 32/67] chore: autologin as root for now --- pkgs/rootfs/mkrootfs.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 78d14d3..a9f16d9 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -38,13 +38,14 @@ cat <<EOF > $out/etc/issue EOF -# replace agetty with busybox getty +# replace agetty with busybox getty (optionally autologin) mkdir $out/usr/lib/systemd/system/serial-getty@.service.d cat <<EOF > $out/usr/lib/systemd/system/serial-getty@.service.d/override.conf [Service] ExecStart= -ExecStart=-/sbin/getty -L %I 115200 vt100 +ExecStart=-/bin/login -f root EOF +# ExecStart=-/sbin/getty -L %I 115200 vt100 # Configure systemd-repart cat <<EOF > $out/etc/repart.d/10-esp.conf From e907d0d3d35c08b4ba4353f1f3a788feddd2ad99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Fri, 7 Mar 2025 15:18:51 +0100 Subject: [PATCH 33/67] fix: rootfs now with verity and A/B prep --- pkgs/image/default.nix | 4 +- pkgs/image/mkimage.sh | 84 ++++++++++++++++++++++++++++++++++------- pkgs/rootfs/mkrootfs.sh | 29 +++++++++++++- 3 files changed, 100 insertions(+), 17 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 4da5187..0fcaf3f 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -19,6 +19,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { dosfstools mtools e2fsprogs + jq ]; env = { @@ -32,8 +33,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { initrd = patosPkgs.initrd.out; rootfs = patosPkgs.rootfs.out; - #FIXME: use roothash instead of device. - kernelCmdLine = "root=/dev/sda2 console=ttyS0"; + kernelCmdLine = "console=ttyS0"; builder = ./mkimage.sh; }) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index c08f0d8..78e55f8 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -1,6 +1,6 @@ set -ex -o pipefail -mkdir -p $out/repart.d $out/boot +mkdir -p $out/init.repart.d $out/final.repart.d $out/boot pushd $out # Don't seem to work just to create a symlink to rootfs derivation? @@ -34,46 +34,102 @@ CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/sys chmod 600 rootfs/etc/shadow rm -rf creds +# Initial partitioning +cat <<EOF > init.repart.d/10-root.conf +[Partition] +Type=root +Format=erofs +Minimize=best +CopyFiles=/rootfs:/ +Verity=data +VerityMatchKey=root +SplitName=root +EOF + +cat <<EOF > init.repart.d/20-root-verity.conf +[Partition] +Type=root-verity +Verity=hash +VerityMatchKey=root +Minimize=best +SplitName=verity +EOF + +#TODO: Add verity signature partition + +$systemd/usr/bin/systemd-repart \ + --no-pager \ + --empty=create \ + --size=auto \ + --definitions=./init.repart.d \ + --split=true \ + --json=pretty \ + --root=$out \ + patos-$version.raw > init-repart-output.json +rm -f patos-$version.raw + +roothash=$(jq -r '.[0].roothash' init-repart-output.json) +rootPart=$(jq -r '.[0].split_path' init-repart-output.json) +rootUuid=$(jq -r '.[0].uuid' init-repart-output.json) + +verityPart=$(jq -r '.[1].split_path' init-repart-output.json) +verityUuid=$(jq -r '.[1].uuid' init-repart-output.json) + $systemd/usr/bin/ukify build \ --linux $kernel/bzImage \ --initrd $initrd/initrd.xz \ --os-release @rootfs/etc/os-release \ - --cmdline "$kernelCmdLine" \ - -o boot/patos.efi + --cmdline "$kernelCmdLine roothash=$roothash" \ + -o patos_${version}.efi +rm -rf rootfs +cp patos_${version}.efi boot/ cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ - echo "timeout 1" > boot/loader.conf -cat <<EOF > repart.d/10-esp.conf +# Final partitioning +cat <<EOF > final.repart.d/10-esp.conf [Partition] Type=esp Format=vfat SizeMinBytes=96M SizeMaxBytes=96M CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI -CopyFiles=/boot/patos.efi:/EFI/Linux/patos.efi +CopyFiles=/boot/patos_${version}.efi:/EFI/Linux/patos_${version}.efi CopyFiles=/boot/loader.conf:/loader/loader.conf EOF -cat <<EOF > repart.d/10-root.conf +cat <<EOF > final.repart.d/20-root.conf [Partition] Type=root -Format=erofs -Minimize=best -CopyFiles=/rootfs:/ -SplitName=root +Label=root-${version} +CopyBlocks=/${rootPart} +UUID=${rootUuid} +SizeMinBytes=256M +SizeMaxBytes=256M +ReadOnly=1 EOF +cat <<EOF > final.repart.d/22-root-verity.conf +[Partition] +Type=root-verity +Label=verity-${version} +CopyBlocks=/${verityPart} +UUID=${verityUuid} +SizeMinBytes=10M +SizeMaxBytes=10M +ReadOnly=1 +EOF + +# finalize image ready for boot $systemd/usr/bin/systemd-repart \ --no-pager \ --empty=create \ --size=auto \ - --definitions=./repart.d \ + --definitions=./final.repart.d \ --root=$out \ - patos-$version.raw + patos-$version.raw > final-repart-output.json -rm -rf rootfs rm -rf boot popd diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index a9f16d9..05a613b 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -52,11 +52,38 @@ cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] Type=esp Format=vfat +SizeMaxBytes=96M +SizeMinBytes=96M EOF -cat <<EOF > $out/etc/repart.d/22-root.conf +cat <<EOF > $out/etc/repart.d/20-root-a.conf [Partition] Type=root +SizeMaxBytes=256M +SizeMinBytes=256M +EOF +cat <<EOF > $out/etc/repart.d/22-root-verify-a.conf +[Partition] +Type=root-verity +SizeMaxBytes=10M +SizeMinBytes=10M +EOF + +cat <<EOF > $out/etc/repart.d/30-root-b.conf +[Partition] +Type=root +Label=_empty +SizeMaxBytes=256M +SizeMinBytes=256M +ReadOnly=1 +EOF +cat <<EOF > $out/etc/repart.d/32-root-verity-b.conf +[Partition] +Type=root-verity +Label=_empty +SizeMaxBytes=10M +SizeMinBytes=10M +ReadOnly=1 EOF cat <<EOF > $out/etc/repart.d/40-var.conf From 55ac59e2b3a9aa89ed497dd6eae6626d58a0582c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Sun, 9 Mar 2025 14:42:28 +0100 Subject: [PATCH 34/67] chore: add subvolumes state partition --- pkgs/rootfs/mkrootfs.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 05a613b..9d1e621 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -90,10 +90,14 @@ cat <<EOF > $out/etc/repart.d/40-var.conf [Partition] Type=var Format=btrfs +MakeDirectories=/var/lib/confexts /var/.snapshots MountPoint=/var Label=patos-state Encrypt=tpm2 EncryptedVolume=patos-state:none:tpm2-device=auto,luks,discard +Subvolumes=/var/lib/confexts /var/.snapshots +MountPoint=/var/lib/confexts:subvol=/var/lib/confexts +MountPoint=/var/.snapshots:subvol=/var/.snapshots SizeMinBytes=1G Minimize=off FactoryReset=yes @@ -134,9 +138,6 @@ cp -P ${lvm2}/lib/udev/rules.d/* $out/usr/lib/udev/rules.d/ cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ -##FIXME(remove later): install mkfs.erofs bin -cp -P ${erofsUtils}/bin/mkfs.erofs $out/usr/bin/ - ### install tpm2 tools # For TPM debugging # cp -P ${tpm2Tools}/bin/* $out/usr/bin/ @@ -159,13 +160,12 @@ cp $out/usr/share/factory/etc/vconsole.conf $out/etc/ #Ephemeral machine-id until registration ln -sf /run/machine-id $out/etc/machine-id - # remove pkgconfig rm -rf $out/usr/lib/pkgconfig ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ - grep -v util-linux-2 | grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | \ + grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | \ sort -u | xargs -I {} cp {} $out/usr/lib/ find $out -type f -executable -exec chmod 755 {} \; From e49c2b22b54bd8c7c25ae9635944c4139ca70494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Sun, 9 Mar 2025 21:10:05 +0100 Subject: [PATCH 35/67] chore: install ca cert bundle --- pkgs/busybox/default.nix | 11 +---------- pkgs/rootfs/default.nix | 5 +---- pkgs/rootfs/mkrootfs.sh | 14 ++++++++------ 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/pkgs/busybox/default.nix b/pkgs/busybox/default.nix index 571d0cf..e318d8a 100644 --- a/pkgs/busybox/default.nix +++ b/pkgs/busybox/default.nix @@ -163,7 +163,7 @@ stdenv.mkDerivation rec { CONFIG_TC n # Set the path for the udhcpc script - CONFIG_UDHCPC_DEFAULT_SCRIPT "${outDispatchPath}" + CONFIG_UDHCPC_DEFAULT_SCRIPT "/usr/share/busybox/" ${extraConfig} CONFIG_CROSS_COMPILER_PREFIX "${stdenv.cc.targetPrefix}" @@ -181,15 +181,6 @@ stdenv.mkDerivation rec { makeFlags = [ "SKIP_STRIP=y" ]; - postInstall = '' - sed -e ' - 1 a busybox() { '$out'/bin/busybox "$@"; }\ - logger() { '$out'/bin/logger "$@"; }\ - ' ${debianDispatcherScript} > ${outDispatchPath} - chmod 555 ${outDispatchPath} - HOST_PATH=$out/bin patchShebangs --host ${outDispatchPath} - ''; - strictDeps = true; depsBuildBuild = [ buildPackages.stdenv.cc ]; diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index 5ac9c6a..4e64ddd 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -24,15 +24,12 @@ stdenvNoCC.mkDerivation (finalAttrs: { busybox = patosPkgs.busybox.out; kmodLibs = pkgs.kmod.lib; kmodBin = pkgs.kmod.out; + cacert = pkgs.cacert.out; libbpf = pkgs.libbpf.out; btrfs = pkgs.btrfs-progs.out; tpm2Libs = patosPkgs.tpm2-tss.out; kexec = patosPkgs.kexec.out; lvm2 = patosPkgs.lvm2.out; - # FIXME: remove later: - tpm2Tools = patosPkgs.tpm2-tools.out; - cryptsetup = pkgs.cryptsetup.bin; - erofsUtils = pkgs.erofs-utils.out; builder = ./mkrootfs.sh; }) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 9d1e621..ad227ad 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -138,26 +138,27 @@ cp -P ${lvm2}/lib/udev/rules.d/* $out/usr/lib/udev/rules.d/ cp -Pr ${btrfs}/bin/* $out/usr/bin/ cp -Pr ${btrfs}/lib/* $out/usr/lib/ -### install tpm2 tools -# For TPM debugging -# cp -P ${tpm2Tools}/bin/* $out/usr/bin/ -# cp -P $cryptsetup/bin/* $out/usr/bin/ +### install tpm2 libs cp -P ${tpm2Libs}/lib/*.so* $out/usr/lib/ ### install lib kmod -cp -P $kmodLibs/lib/* $out/usr/lib +cp -P $kmodLibs/lib/*.so* $out/usr/lib/ cp -P $kmodBin/bin/* $out/usr/bin ### install libbpf cp -P $libbpf/lib/libbpf* $out/usr/lib +### install ca cert bundle +cp -Pr $cacert/etc/ssl $out/etc/ + # setup default files $systemd/usr/bin/systemd-hwdb --root=$out --usr update $systemd/usr/bin/systemd-tmpfiles --root=$out $out/usr/lib/tmpfiles.d/etc.conf --create cp $out/usr/share/factory/etc/nsswitch.conf $out/etc/ cp $out/usr/share/factory/etc/locale.conf $out/etc/ cp $out/usr/share/factory/etc/vconsole.conf $out/etc/ -#Ephemeral machine-id until registration + +# Ephemeral machine-id until registration ln -sf /run/machine-id $out/etc/machine-id # remove pkgconfig @@ -167,6 +168,7 @@ rm -rf $out/usr/lib/pkgconfig find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | \ sort -u | xargs -I {} cp {} $out/usr/lib/ + find $out -type f -executable -exec chmod 755 {} \; # FIXME: ELF patching. Is there a better way? From 4ecf8ead2addd9568154ca979d8c465439125113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 12 Mar 2025 10:39:39 +0100 Subject: [PATCH 36/67] chore: add lib for making systemd sysexts --- flake.nix | 15 ++++++++ lib/make-sysext.nix | 87 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 lib/make-sysext.nix diff --git a/flake.nix b/flake.nix index 97a1f97..ed6a3e5 100644 --- a/flake.nix +++ b/flake.nix @@ -45,6 +45,21 @@ dbus-broker = pkgs.callPackage ./pkgs/dbus-broker { }; qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { }; + + debug-tools-sysext = pkgs.callPackage ./lib/make-sysext.nix { + name = "debug-tools"; + version = "0.0.1"; + packages = [ + { drv = pkgs.curl; path = "bin/curl"; } + { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } + { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } + { drv = pkgs.cryptsetup; path = "bin/veritysetup"; } + # shared lib required for cryptsetup + { drv = pkgs.popt; path = "lib/libpopt.so.0.0.2"; } + { drv = pkgs.popt; path = "lib/libpopt.so.0"; } + { drv = pkgs.popt; path = "lib/libpopt.so"; } + ]; + }; }; checks = { diff --git a/lib/make-sysext.nix b/lib/make-sysext.nix new file mode 100644 index 0000000..fb1a8f0 --- /dev/null +++ b/lib/make-sysext.nix @@ -0,0 +1,87 @@ +{ + lib, + runCommand, + pkgs, + + name, + packages, + osId ? "patos", + version ? null, +}: + + +let + metadata = { + ID = osId; + VERSION_ID = osId; + IMAGE_ID = name; + IMAGE_VERSION = version; + }; + + metadataFile = lib.concatStringsSep "\n" ( + lib.mapAttrsToList (k: v: "${k}=${v}") (lib.filterAttrs (_: v: v != null) metadata) + ); + + doCopy = + { + drv, + prefix ? "usr", + path, + destpath ? null, + }: + "do_copy ${prefix} ${drv} ${path}" + lib.optionalString (destpath != null) " ${destpath}"; + +in + +runCommand name + { + passthru.name = name; + inherit metadataFile; + passAsFile = [ "metadataFile" ]; + + buildInputs = [ + pkgs.erofs-utils + pkgs.cryptsetup + ]; + + } + '' + do_copy () { + local prefix="$1" + local drv="$2" + local path="$3" + local destpath="''${4:-$path}" + + local srcfile + local destdir + local destfile + srcfile="$drv/$path" + destfile="$out/tree/$prefix/$destpath" + destdir="$(dirname -- "$destfile")" + + mkdir -pv "$destdir" + cp -Pv "$srcfile" "$destfile" + + chmod 755 "$destfile" + patchelf --set-rpath /lib:/usr/lib:/ $destfile + patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 $destfile || true + } + + mkdir -p $out/tree + + ${lib.concatStringsSep "\n" (map doCopy packages)} + + # bake metadata into the structure + if ! [ -f $out/tree/usr/lib/extension-release.d/extension-release."${name}" ]; then + mkdir -p $out/tree/usr/lib/extension-release.d + cat "$metadataFilePath" > $out/tree/usr/lib/extension-release.d/extension-release."${name}" + fi + + pushd $out + find tree -type d -exec chmod 0755 {} \; + mkfs.erofs --all-root $name.raw tree/ + veritysetup format --root-hash-file $name.roothash $name.raw $name.verity + #TODO: pcks7 signature? + rm -rf tree + popd + '' From 5ecfd546f66d4a68bd68537cc7efa9f174a24470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 12 Mar 2025 12:47:56 +0100 Subject: [PATCH 37/67] fix: we have to build our own openssl to use standard paths --- flake.nix | 1 + lib/make-sysext.nix | 2 +- pkgs/openssl/default.nix | 166 +++++++++++++++++++++++++++++++++++++++ pkgs/rootfs/default.nix | 1 + pkgs/rootfs/mkrootfs.sh | 9 ++- 5 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 pkgs/openssl/default.nix diff --git a/flake.nix b/flake.nix index ed6a3e5..fc453e8 100644 --- a/flake.nix +++ b/flake.nix @@ -37,6 +37,7 @@ kernel = pkgs.callPackage ./pkgs/kernel { }; glibc = pkgs.callPackage ./pkgs/glibc { }; busybox = pkgs.callPackage ./pkgs/busybox { }; + openssl = pkgs.callPackage ./pkgs/openssl { }; kexec = pkgs.callPackage ./pkgs/kexec-tools { }; lvm2 = pkgs.callPackage ./pkgs/lvm2 { }; tpm2-tools = pkgs.callPackage ./pkgs/tpm2-tools { inherit patosPkgs; }; diff --git a/lib/make-sysext.nix b/lib/make-sysext.nix index fb1a8f0..2541e3d 100644 --- a/lib/make-sysext.nix +++ b/lib/make-sysext.nix @@ -63,7 +63,7 @@ runCommand name cp -Pv "$srcfile" "$destfile" chmod 755 "$destfile" - patchelf --set-rpath /lib:/usr/lib:/ $destfile + patchelf --set-rpath /usr/lib $destfile patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 $destfile || true } diff --git a/pkgs/openssl/default.nix b/pkgs/openssl/default.nix new file mode 100644 index 0000000..137176d --- /dev/null +++ b/pkgs/openssl/default.nix @@ -0,0 +1,166 @@ +{ + lib, + stdenv, + fetchurl, + perl, + makeBinaryWrapper, + withCryptodev ? false, + cryptodev, + withZlib ? false, + zlib, + enableSSL2 ? false, + enableSSL3 ? false, + enableMD2 ? false, + enableKTLS ? stdenv.hostPlatform.isLinux, + static ? stdenv.hostPlatform.isStatic, + removeReferencesTo, +}: + +stdenv.mkDerivation rec { + pname = "openssl"; + version = "3.4.1"; + hash = "sha256-ACotazC1i/S+pGxDvdljZar42qbEKHgqpP7uBtoZffM="; + + src = fetchurl { + url = "https://github.com/openssl/openssl/releases/download/openssl-${version}/openssl-${version}.tar.gz"; + hash = hash; + }; + + outputs = [ "out" ]; + + nativeBuildInputs = + lib.optional (!stdenv.hostPlatform.isWindows) makeBinaryWrapper + ++ [ perl ] + ++ lib.optionals static [ removeReferencesTo ]; + buildInputs = lib.optional withCryptodev cryptodev ++ lib.optional withZlib zlib; + + # TODO(@Ericson2314): Improve with mass rebuild + configurePlatforms = [ ]; + configureScript = + { + armv5tel-linux = "./Configure linux-armv4 -march=armv5te"; + armv6l-linux = "./Configure linux-armv4 -march=armv6"; + armv7l-linux = "./Configure linux-armv4 -march=armv7-a"; + x86_64-darwin = "./Configure darwin64-x86_64-cc"; + aarch64-darwin = "./Configure darwin64-arm64-cc"; + x86_64-linux = "./Configure linux-x86_64"; + x86_64-solaris = "./Configure solaris64-x86_64-gcc"; + powerpc64-linux = "./Configure linux-ppc64"; + riscv32-linux = "./Configure ${ + if lib.versionAtLeast version "3.2" then "linux32-riscv32" else "linux-latomic" + }"; + riscv64-linux = "./Configure linux64-riscv64"; + } + .${stdenv.hostPlatform.system} or ( + if stdenv.hostPlatform == stdenv.buildPlatform then + "./config" + else if stdenv.hostPlatform.isBSD then + if stdenv.hostPlatform.isx86_64 then + "./Configure BSD-x86_64" + else if stdenv.hostPlatform.isx86_32 then + "./Configure BSD-x86" + lib.optionalString stdenv.hostPlatform.isElf "-elf" + else + "./Configure BSD-generic${toString stdenv.hostPlatform.parsed.cpu.bits}" + else if stdenv.hostPlatform.isMinGW then + "./Configure mingw${ + lib.optionalString (stdenv.hostPlatform.parsed.cpu.bits != 32) ( + toString stdenv.hostPlatform.parsed.cpu.bits + ) + }" + else if stdenv.hostPlatform.isLinux then + if stdenv.hostPlatform.isx86_64 then + "./Configure linux-x86_64" + else if stdenv.hostPlatform.isMicroBlaze then + "./Configure linux-latomic" + else if stdenv.hostPlatform.isMips32 then + "./Configure linux-mips32" + else if stdenv.hostPlatform.isMips64n32 then + "./Configure linux-mips64" + else if stdenv.hostPlatform.isMips64n64 then + "./Configure linux64-mips64" + else + "./Configure linux-generic${toString stdenv.hostPlatform.parsed.cpu.bits}" + else if stdenv.hostPlatform.isiOS then + "./Configure ios${toString stdenv.hostPlatform.parsed.cpu.bits}-cross" + else + throw "Not sure what configuration to use for ${stdenv.hostPlatform.config}" + ); + + # OpenSSL doesn't like the `--enable-static` / `--disable-shared` flags. + dontAddStaticConfigureFlags = true; + + configureFlags = + [ + "shared" # "shared" builds both shared and static libraries + "--prefix=/usr" + "--libdir=lib" + "--openssldir=/etc/ssl" + ] + ++ lib.optionals withCryptodev [ + "-DHAVE_CRYPTODEV" + "-DUSE_CRYPTODEV_DIGESTS" + ] + ++ lib.optional enableMD2 "enable-md2" + ++ lib.optional enableSSL2 "enable-ssl2" + ++ lib.optional enableSSL3 "enable-ssl3" + # We select KTLS here instead of the configure-time detection (which we patch out). + # KTLS should work on FreeBSD 13+ as well, so we could enable it if someone tests it. + ++ lib.optional (lib.versionAtLeast version "3.0.0" && enableKTLS) "enable-ktls" + ++ lib.optional (lib.versionAtLeast version "1.1.1" && stdenv.hostPlatform.isAarch64) "no-afalgeng" + # OpenSSL needs a specific `no-shared` configure flag. + # See https://wiki.openssl.org/index.php/Compilation_and_Installation#Configure_Options + # for a comprehensive list of configuration options. + ++ lib.optional (lib.versionAtLeast version "1.1.1" && static) "no-shared" + ++ lib.optional (lib.versionAtLeast version "3.0.0" && static) "no-module" + # This introduces a reference to the CTLOG_FILE which is undesired when + # trying to build binaries statically. + ++ lib.optional static "no-ct" + ++ lib.optional withZlib "zlib" + # /dev/crypto support has been dropped in OpenBSD 5.7. + # + # OpenBSD's ports does this too, + # https://github.com/openbsd/ports/blob/a1147500c76970fea22947648fb92a093a529d7c/security/openssl/3.3/Makefile#L25. + # + # https://github.com/openssl/openssl/pull/10565 indicated the + # intent was that this would be configured properly automatically, + # but that doesn't appear to be the case. + ++ lib.optional stdenv.hostPlatform.isOpenBSD "no-devcryptoeng" + ++ lib.optionals (stdenv.hostPlatform.isMips && stdenv.hostPlatform ? gcc.arch) [ + # This is necessary in order to avoid openssl adding -march + # flags which ultimately conflict with those added by + # cc-wrapper. Openssl assumes that it can scan CFLAGS to + # detect any -march flags, using this perl code: + # + # && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}}) + # + # The following bogus CFLAGS environment variable triggers the + # the code above, inhibiting `./Configure` from adding the + # conflicting flags. + "CFLAGS=-march=${stdenv.hostPlatform.gcc.arch}" + ]; + + postPatch = '' + patchShebangs Configure + ''; + + installPhase = '' + make DESTDIR=$out install + ''; + + enableParallelBuilding = true; + + meta = { + homepage = "https://www.openssl.org/"; + changelog = "https://github.com/openssl/openssl/blob/openssl-${version}/CHANGES.md"; + description = "Cryptographic library that implements the SSL and TLS protocols"; + license = lib.licenses.openssl; + mainProgram = "openssl"; + maintainers = with lib.maintainers; [ thillux ] ++ lib.teams.stridtech.members; + pkgConfigModules = [ + "libcrypto" + "libssl" + "openssl" + ]; + platforms = lib.platforms.all; + }; +} diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index 4e64ddd..c7f0dba 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -30,6 +30,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { tpm2Libs = patosPkgs.tpm2-tss.out; kexec = patosPkgs.kexec.out; lvm2 = patosPkgs.lvm2.out; + openssl = patosPkgs.openssl.out; builder = ./mkrootfs.sh; }) diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index ad227ad..14f4dac 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -115,6 +115,10 @@ EOF ### install PatOS glibc cp -P $glibcPatos/lib/*.so* $out/usr/lib/ +### install openssl +cp -P $openssl/usr/lib/*.so* $out/usr/lib/ +cp -Pr $openssl/etc/ssl $out/etc/ + ### install kernel modules cp -r $kernel/lib/modules $out/usr/lib/ find $out/usr/lib/modules -type d -exec chmod 755 {} \; @@ -149,7 +153,8 @@ cp -P $kmodBin/bin/* $out/usr/bin cp -P $libbpf/lib/libbpf* $out/usr/lib ### install ca cert bundle -cp -Pr $cacert/etc/ssl $out/etc/ +chmod 755 $out/etc/ssl +cp -P $cacert/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/cert.pem # setup default files $systemd/usr/bin/systemd-hwdb --root=$out --usr update @@ -166,7 +171,7 @@ rm -rf $out/usr/lib/pkgconfig ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ - grep -v systemd | grep -v glibc | grep -v tpm2 | grep -v devmapper | \ + grep -v systemd | grep -v glibc | grep -v openssl | grep -v tpm2 | grep -v devmapper | grep -v not | \ sort -u | xargs -I {} cp {} $out/usr/lib/ find $out -type f -executable -exec chmod 755 {} \; From 4c0ae9086ba93aec9985c85df9d689c2350270b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 12 Mar 2025 13:37:59 +0100 Subject: [PATCH 38/67] chore(openssl): remove dist files from ssldir --- lib/make-sysext.nix | 6 +++++- pkgs/openssl/default.nix | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/make-sysext.nix b/lib/make-sysext.nix index 2541e3d..c94227b 100644 --- a/lib/make-sysext.nix +++ b/lib/make-sysext.nix @@ -81,7 +81,11 @@ runCommand name find tree -type d -exec chmod 0755 {} \; mkfs.erofs --all-root $name.raw tree/ veritysetup format --root-hash-file $name.roothash $name.raw $name.verity - #TODO: pcks7 signature? + # TODO: pcks7 signature + # openssl smime -sign -nocerts -noattr -binary -in ${name}.roothash \ + # -inkey key.pem -signer cert.pem -outform der -out ${name}.roothash.p7s rm -rf tree + sha256sum * > SHA256SUMS + # TODO: add gpg signature popd '' diff --git a/pkgs/openssl/default.nix b/pkgs/openssl/default.nix index 137176d..0e1f742 100644 --- a/pkgs/openssl/default.nix +++ b/pkgs/openssl/default.nix @@ -145,6 +145,7 @@ stdenv.mkDerivation rec { installPhase = '' make DESTDIR=$out install + rm -rf $out/etc/ssl/*.dist $out/etc/ssl/misc ''; enableParallelBuilding = true; From 865d73abab7b0c8d6ad44f890351ff1ff158dc13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 12 Mar 2025 14:12:38 +0100 Subject: [PATCH 39/67] chore(debug-tools): add a couple of useful tools --- flake.nix | 4 ++++ lib/make-sysext.nix | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index fc453e8..1276c0c 100644 --- a/flake.nix +++ b/flake.nix @@ -52,6 +52,10 @@ version = "0.0.1"; packages = [ { drv = pkgs.curl; path = "bin/curl"; } + { drv = pkgs.bash; path = "bin/bash"; } + { drv = patosPkgs.glibc; path = "bin/ldd"; } + { drv = pkgs.keyutils; path = "bin/keyctl"; } + { drv = pkgs.gnutar; path = "bin/tar"; } { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } { drv = pkgs.cryptsetup; path = "bin/veritysetup"; } diff --git a/lib/make-sysext.nix b/lib/make-sysext.nix index c94227b..6de1e63 100644 --- a/lib/make-sysext.nix +++ b/lib/make-sysext.nix @@ -63,7 +63,7 @@ runCommand name cp -Pv "$srcfile" "$destfile" chmod 755 "$destfile" - patchelf --set-rpath /usr/lib $destfile + patchelf --set-rpath /usr/lib $destfile || true patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 $destfile || true } From 723c7efa327dbaeece28a7e001034f76bc50d5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 12 Mar 2025 14:38:01 +0100 Subject: [PATCH 40/67] chore(debug-tools): more tools for the people :rocket: --- flake.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/flake.nix b/flake.nix index 1276c0c..ed21385 100644 --- a/flake.nix +++ b/flake.nix @@ -57,12 +57,18 @@ { drv = pkgs.keyutils; path = "bin/keyctl"; } { drv = pkgs.gnutar; path = "bin/tar"; } { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } + { drv = patosPkgs.openssl; path = "usr/bin/openssl"; destpath = "bin/openssl"; } { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } { drv = pkgs.cryptsetup; path = "bin/veritysetup"; } + { drv = pkgs.erofs-utils; path = "bin/mkfs.erofs"; } # shared lib required for cryptsetup { drv = pkgs.popt; path = "lib/libpopt.so.0.0.2"; } { drv = pkgs.popt; path = "lib/libpopt.so.0"; } { drv = pkgs.popt; path = "lib/libpopt.so"; } + # shared lib required for mkfs.erofs + { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1.10.0"; } + { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1"; } + { drv = pkgs.lz4.lib; path = "lib/liblz4.so"; } ]; }; }; From 1fcccfcd7c3837bdb2aa4cd846e58e295b803b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 12 Mar 2025 15:38:40 +0100 Subject: [PATCH 41/67] chore(debug-tools): add strace and binutils --- flake.nix | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/flake.nix b/flake.nix index ed21385..f1005dc 100644 --- a/flake.nix +++ b/flake.nix @@ -56,6 +56,8 @@ { drv = patosPkgs.glibc; path = "bin/ldd"; } { drv = pkgs.keyutils; path = "bin/keyctl"; } { drv = pkgs.gnutar; path = "bin/tar"; } + { drv = pkgs.binutils-unwrapped; path = "bin/strings"; } + { drv = pkgs.strace; path = "bin/strace"; } { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } { drv = patosPkgs.openssl; path = "usr/bin/openssl"; destpath = "bin/openssl"; } { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } @@ -69,6 +71,18 @@ { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1.10.0"; } { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1"; } { drv = pkgs.lz4.lib; path = "lib/liblz4.so"; } + # shared lib required for binutils + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libsframe.so.1.0.0"; } + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libsframe.so.1"; } + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libbfd-2.43.1.so"; } + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libbfd.so"; } + # shared lib required for strace + { drv = pkgs.elfutils.out; path = "lib/libdw-0.192.so"; } + { drv = pkgs.elfutils.out; path = "lib/libdw.so.1"; } + { drv = pkgs.elfutils.out; path = "lib/libdw.so"; } + { drv = pkgs.elfutils.out; path = "lib/libelf-0.192.so"; } + { drv = pkgs.elfutils.out; path = "lib/libelf.so.1"; } + { drv = pkgs.elfutils.out; path = "lib/libelf.so"; } ]; }; }; From 3dec49b2e4205eddd53475cf4047ba74393aa3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 13 Mar 2025 09:36:42 +0100 Subject: [PATCH 42/67] chore(qemu): enable secure boot --- utils/qemu-uefi-tpm.nix | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/utils/qemu-uefi-tpm.nix b/utils/qemu-uefi-tpm.nix index 0193a27..4fcadfd 100644 --- a/utils/qemu-uefi-tpm.nix +++ b/utils/qemu-uefi-tpm.nix @@ -12,7 +12,7 @@ pkgs.writeShellApplication { text = let - tpmOVMF = pkgs.OVMF.override { tpmSupport = true; }; + tpmOVMF = pkgs.OVMF.override { tpmSupport = true; secureBoot = true; }; in '' set -ex @@ -26,6 +26,9 @@ pkgs.writeShellApplication { --tpm2 \ --log file="$state/swtpm.log",level=20 + cp ${tpmOVMF.variables} "$state" + chmod 700 "$state/OVMF_VARS.fd" + qemu-system-x86_64 \ -enable-kvm \ -machine q35,accel=kvm \ @@ -37,7 +40,7 @@ pkgs.writeShellApplication { -serial chardev:char0 \ -mon chardev=char0 \ -drive "if=pflash,format=raw,unit=0,readonly=on,file=${tpmOVMF.firmware}" \ - -drive "if=pflash,format=raw,unit=1,readonly=on,file=${tpmOVMF.variables}" \ + -drive "if=pflash,format=raw,unit=1,file=$state/OVMF_VARS.fd" \ -chardev socket,id=chrtpm,path="$state/swtpm-sock" \ -tpmdev emulator,id=tpm0,chardev=chrtpm \ -device tpm-tis,tpmdev=tpm0 \ From 2c2d212e250eceed41f3fbd5b7b14898d4a89540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 13 Mar 2025 09:36:42 +0100 Subject: [PATCH 43/67] fix: our own derivation for the kernel in order to be able to sign modules --- flake.nix | 2 +- pkgs/image/default.nix | 4 +- pkgs/image/mkimage.sh | 7 - pkgs/kernel/default.nix | 7 +- pkgs/kernel/generic.config | 14 +- pkgs/kernel/manual-config.nix | 465 ++++++++++++++++++++++++++++++++++ pkgs/kernel/result | 1 + pkgs/openssl/default.nix | 2 +- pkgs/rootfs/default.nix | 4 +- pkgs/rootfs/mkrootfs.sh | 34 ++- 10 files changed, 508 insertions(+), 32 deletions(-) create mode 100644 pkgs/kernel/manual-config.nix create mode 120000 pkgs/kernel/result diff --git a/flake.nix b/flake.nix index f1005dc..5b1774f 100644 --- a/flake.nix +++ b/flake.nix @@ -59,7 +59,7 @@ { drv = pkgs.binutils-unwrapped; path = "bin/strings"; } { drv = pkgs.strace; path = "bin/strace"; } { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } - { drv = patosPkgs.openssl; path = "usr/bin/openssl"; destpath = "bin/openssl"; } + { drv = patosPkgs.openssl; path = "bin/openssl"; } { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } { drv = pkgs.cryptsetup; path = "bin/veritysetup"; } { drv = pkgs.erofs-utils; path = "bin/mkfs.erofs"; } diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 0fcaf3f..74e0931 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -7,12 +7,10 @@ }: let pname = "patos-image"; - defaultPassword = "patos"; in stdenvNoCC.mkDerivation (finalAttrs: { inherit version; inherit pname; - inherit defaultPassword; buildInputs = with pkgs; [ erofs-utils @@ -29,7 +27,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { }; systemd = patosPkgs.systemd.out; - kernel = patosPkgs.kernel.kernel; + kernel = patosPkgs.kernel; initrd = patosPkgs.initrd.out; rootfs = patosPkgs.rootfs.out; diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 78e55f8..df56849 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -27,13 +27,6 @@ mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/sys ln -sf ../systemd-confext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-confext.service ln -sf ../systemd-sysext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-sysext.service -# install sys users -mkdir creds -echo -n $defaultPassword > creds/passwd.plaintext-password.root -CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=rootfs rootfs/usr/lib/sysusers.d/*.conf -chmod 600 rootfs/etc/shadow -rm -rf creds - # Initial partitioning cat <<EOF > init.repart.d/10-root.conf [Partition] diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix index 73ecd1f..c5dabce 100644 --- a/pkgs/kernel/default.nix +++ b/pkgs/kernel/default.nix @@ -1,9 +1,9 @@ -{ pkgs, ... }: +{ pkgs, lib, stdenv, ... }: let version = "6.13.4"; in -pkgs.linuxPackagesFor ( - pkgs.linuxManualConfig { + (pkgs.callPackage ./manual-config.nix { }) { + inherit lib stdenv; version = "${version}-patos1"; modDirVersion = version; src = pkgs.fetchurl { @@ -13,4 +13,3 @@ pkgs.linuxPackagesFor ( configfile = ./generic.config; allowImportFromDerivation = true; } -) diff --git a/pkgs/kernel/generic.config b/pkgs/kernel/generic.config index 209e026..647bf91 100644 --- a/pkgs/kernel/generic.config +++ b/pkgs/kernel/generic.config @@ -522,11 +522,11 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_ENTRY=y CONFIG_DEBUG_FS_ALLOW_ALL=y CONFIG_DEBUG_FS=y -CONFIG_DEBUG_INFO_BTF_MODULES=y -CONFIG_DEBUG_INFO_BTF=y -CONFIG_DEBUG_INFO_COMPRESSED_NONE=y -CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y -CONFIG_DEBUG_INFO=y +#CONFIG_DEBUG_INFO_BTF_MODULES=y +#CONFIG_DEBUG_INFO_BTF=y +#CONFIG_DEBUG_INFO_COMPRESSED_NONE=y +#CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y +CONFIG_DEBUG_INFO=n CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_MISC=y @@ -1400,6 +1400,10 @@ CONFIG_MODULE_COMPRESS_ZSTD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_SIG=y +CONFIG_MODULE_SIG_FORCE=n +CONFIG_MODULE_SIG_ALL=y +CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_MODULES=y diff --git a/pkgs/kernel/manual-config.nix b/pkgs/kernel/manual-config.nix new file mode 100644 index 0000000..ffcf758 --- /dev/null +++ b/pkgs/kernel/manual-config.nix @@ -0,0 +1,465 @@ +{ lib, stdenv, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl +, cpio, elfutils, hexdump, zstd, python3Minimal, zlib, pahole, kmod, ubootTools +, fetchpatch +, rustc, rust-bindgen, rustPlatform +}: + +let + lib_ = lib; + stdenv_ = stdenv; + + readConfig = configfile: import (runCommand "config.nix" {} '' + echo "{" > "$out" + while IFS='=' read key val; do + [ "x''${key#CONFIG_}" != "x$key" ] || continue + no_firstquote="''${val#\"}"; + echo ' "'"$key"'" = "'"''${no_firstquote%\"}"'";' >> "$out" + done < "${configfile}" + echo "}" >> $out + '').outPath; +in lib.makeOverridable ({ + # The kernel version + version, + # The kernel pname (should be set for variants) + pname ? "linux", + # Position of the Linux build expression + pos ? null, + # Additional kernel make flags + extraMakeFlags ? [], + # The name of the kernel module directory + # Needs to be X.Y.Z[-extra], so pad with zeros if needed. + modDirVersion ? null /* derive from version */, + # The kernel source (tarball, git checkout, etc.) + src, + # a list of { name=..., patch=..., extraConfig=...} patches + kernelPatches ? [], + # The kernel .config file + configfile, + # Manually specified nixexpr representing the config + # If unspecified, this will be autodetected from the .config + config ? lib.optionalAttrs allowImportFromDerivation (readConfig configfile), + # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is + # automatically extended with extra per-version and per-config values. + randstructSeed ? "", + # Extra meta attributes + extraMeta ? {}, + + # for module compatibility + isZen ? false, + isLibre ? false, + isHardened ? false, + + # Whether to utilize the controversial import-from-derivation feature to parse the config + allowImportFromDerivation ? false, + # ignored + features ? null, lib ? lib_, stdenv ? stdenv_, +}: + +let + # Provide defaults. Note that we support `null` so that callers don't need to use optionalAttrs, + # which can lead to unnecessary strictness and infinite recursions. + modDirVersion_ = if modDirVersion == null then lib.versions.pad 3 version else modDirVersion; +in +let + # Shadow the un-defaulted parameter; don't want null. + modDirVersion = modDirVersion_; + inherit (lib) + hasAttr getAttr optional optionals optionalString optionalAttrs maintainers platforms; + + drvAttrs = config_: kernelConf: kernelPatches: configfile: + let + # Folding in `ubootTools` in the default nativeBuildInputs is problematic, as + # it makes updating U-Boot cumbersome, since it will go above the current + # threshold of rebuilds + # + # To prevent these needless rounds of staging for U-Boot builds, we can + # limit the inclusion of ubootTools to target platforms where uImage *may* + # be produced. + # + # This command lists those (kernel-named) platforms: + # .../linux $ grep -l uImage ./arch/*/Makefile | cut -d'/' -f3 | sort + # + # This is still a guesstimation, but since none of our cached platforms + # coincide in that list, this gives us "perfect" decoupling here. + linuxPlatformsUsingUImage = [ + "arc" + "arm" + "csky" + "mips" + "powerpc" + "sh" + "sparc" + "xtensa" + ]; + needsUbootTools = + lib.elem stdenv.hostPlatform.linuxArch linuxPlatformsUsingUImage + ; + + config = let attrName = attr: "CONFIG_" + attr; in { + isSet = attr: hasAttr (attrName attr) config; + + getValue = attr: if config.isSet attr then getAttr (attrName attr) config else null; + + isYes = attr: (config.getValue attr) == "y"; + + isNo = attr: (config.getValue attr) == "n"; + + isModule = attr: (config.getValue attr) == "m"; + + isEnabled = attr: (config.isModule attr) || (config.isYes attr); + + isDisabled = attr: (!(config.isSet attr)) || (config.isNo attr); + } // config_; + + isModular = config.isYes "MODULES"; + withRust = config.isYes "RUST"; + + buildDTBs = kernelConf.DTB or false; + + # Dependencies that are required to build kernel modules + moduleBuildDependencies = [ + pahole + perl + elfutils + # module makefiles often run uname commands to find out the kernel version + (buildPackages.deterministic-uname.override { inherit modDirVersion; }) + ] + ++ optional (lib.versionAtLeast version "5.13") zstd + ++ optionals withRust [ rustc rust-bindgen ] + ; + + in (optionalAttrs isModular { outputs = [ "out" "dev" ]; }) // { + passthru = rec { + inherit version modDirVersion config kernelPatches configfile + moduleBuildDependencies stdenv; + inherit isZen isHardened isLibre withRust; + isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true; + baseVersion = lib.head (lib.splitString "-rc" version); + kernelOlder = lib.versionOlder baseVersion; + kernelAtLeast = lib.versionAtLeast baseVersion; + }; + + inherit src; + + depsBuildBuild = [ buildPackages.stdenv.cc ]; + nativeBuildInputs = [ + bison + flex + perl + bc + nettools + openssl + rsync + gmp + libmpc + mpfr + elfutils + zstd + python3Minimal + kmod + hexdump + ] ++ optional needsUbootTools ubootTools + ++ optionals (lib.versionAtLeast version "5.2") [ cpio pahole zlib ] + ++ optionals withRust [ rustc rust-bindgen ]; + + RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc; + + # avoid leaking Rust source file names into the final binary, which adds + # a false dependency on rust-lib-src on targets with uncompressed kernels + KRUSTFLAGS = lib.optionalString withRust "--remap-path-prefix ${rustPlatform.rustLibSrc}=/"; + + # patches = + # map (p: p.patch) kernelPatches + # # Required for deterministic builds along with some postPatch magic. + # ++ optional (lib.versionOlder version "5.19") ./randstruct-provide-seed.patch + # ++ optional (lib.versionAtLeast version "5.19") ./randstruct-provide-seed-5.19.patch + # # Linux 5.12 marked certain PowerPC-only symbols as GPL, which breaks + # # OpenZFS; this was fixed in Linux 5.19 so we backport the fix + # # https://github.com/openzfs/zfs/pull/13367 + # ++ optional (lib.versionAtLeast version "5.12" && + # lib.versionOlder version "5.19" && + # stdenv.hostPlatform.isPower) + # (fetchpatch { + # url = "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/patch/?id=d9e5c3e9e75162f845880535957b7fd0b4637d23"; + # hash = "sha256-bBOyJcP6jUvozFJU0SPTOf3cmnTQ6ZZ4PlHjiniHXLU="; + # }); + + postPatch = '' + # Ensure that depmod gets resolved through PATH + sed -i Makefile -e 's|= /sbin/depmod|= depmod|' + + # Some linux-hardened patches now remove certain files in the scripts directory, so the file may not exist. + [[ -f scripts/ld-version.sh ]] && patchShebangs scripts/ld-version.sh + + # Set randstruct seed to a deterministic but diversified value. Note: + # we could have instead patched gen-random-seed.sh to take input from + # the buildFlags, but that would require also patching the kernel's + # toplevel Makefile to add a variable export. This would be likely to + # cause future patch conflicts. + for file in scripts/gen-randstruct-seed.sh scripts/gcc-plugins/gen-random-seed.sh; do + if [ -f "$file" ]; then + substituteInPlace "$file" \ + --replace NIXOS_RANDSTRUCT_SEED \ + $(echo ${randstructSeed}${src} ${placeholder "configfile"} | sha256sum | cut -d ' ' -f 1 | tr -d '\n') + break + fi + done + + patchShebangs scripts + + # also patch arch-specific install scripts + for i in $(find arch -name install.sh); do + patchShebangs "$i" + done + + # unset $src because the build system tries to use it and spams a bunch of warnings + # see: https://github.com/torvalds/linux/commit/b1992c3772e69a6fd0e3fc81cd4d2820c8b6eca0 + unset src + ''; + + configurePhase = '' + runHook preConfigure + + mkdir build + export buildRoot="$(pwd)/build" + + echo "manual-config configurePhase buildRoot=$buildRoot pwd=$PWD" + + if [ -f "$buildRoot/.config" ]; then + echo "Could not link $buildRoot/.config : file exists" + exit 1 + fi + ln -sv ${configfile} $buildRoot/.config + + # reads the existing .config file and prompts the user for options in + # the current kernel source that are not found in the file. + make $makeFlags "''${makeFlagsArray[@]}" oldconfig + runHook postConfigure + + make $makeFlags "''${makeFlagsArray[@]}" prepare + actualModDirVersion="$(cat $buildRoot/include/config/kernel.release)" + if [ "$actualModDirVersion" != "${modDirVersion}" ]; then + echo "Error: modDirVersion ${modDirVersion} specified in the Nix expression is wrong, it should be: $actualModDirVersion" + exit 1 + fi + + buildFlagsArray+=("KBUILD_BUILD_TIMESTAMP=$(date -u -d @$SOURCE_DATE_EPOCH)") + + cd $buildRoot + ''; + + buildFlags = [ + "KBUILD_BUILD_VERSION=1-PatOS" + kernelConf.target + "vmlinux" # for "perf" and things like that + ] ++ optional isModular "modules" + ++ optionals buildDTBs ["dtbs" "DTC_FLAGS=-@"] + ++ extraMakeFlags; + + installFlags = [ + "INSTALL_PATH=$(out)" + ] ++ (optional isModular "INSTALL_MOD_PATH=$(out)") + ++ optionals buildDTBs ["dtbs_install" "INSTALL_DTBS_PATH=$(out)/dtbs"]; + + dontStrip = true; + + preInstall = let + # All we really need to do here is copy the final image and System.map to $out, + # and use the kernel's modules_install, firmware_install, dtbs_install, etc. targets + # for the rest. Easy, right? + # + # Unfortunately for us, the obvious way of getting the built image path, + # make -s image_name, does not work correctly, because some architectures + # (*cough* aarch64 *cough*) change KBUILD_IMAGE on the fly in their install targets, + # so we end up attempting to install the thing we didn't actually build. + # + # Thankfully, there's a way out that doesn't involve just hardcoding everything. + # + # The kernel has an install target, which runs a pretty simple shell script + # (located at scripts/install.sh or arch/$arch/boot/install.sh, depending on + # which kernel version you're looking at) that tries to do something sensible. + # + # (it would be great to hijack this script immediately, as it has all the + # information we need passed to it and we don't need it to try and be smart, + # but unfortunately, the exact location of the scripts differs between kernel + # versions, and they're seemingly not considered to be public API at all) + # + # One of the ways it tries to discover what "something sensible" actually is + # is by delegating to what's supposed to be a user-provided install script + # located at ~/bin/installkernel. + # + # (the other options are: + # - a distribution-specific script at /sbin/installkernel, + # which we can't really create in the sandbox easily + # - an architecture-specific script at arch/$arch/boot/install.sh, + # which attempts to guess _something_ and usually guesses very wrong) + # + # More specifically, the install script exec's into ~/bin/installkernel, if one + # exists, with the following arguments: + # + # $1: $KERNELRELEASE - full kernel version string + # $2: $KBUILD_IMAGE - the final image path + # $3: System.map - path to System.map file, seemingly hardcoded everywhere + # $4: $INSTALL_PATH - path to the destination directory as specified in installFlags + # + # $2 is exactly what we want, so hijack the script and use the knowledge given to it + # by the makefile overlords for our own nefarious ends. + # + # Note that the makefiles specifically look in ~/bin/installkernel, and + # writeShellScriptBin writes the script to <store path>/bin/installkernel, + # so HOME needs to be set to just the store path. + # + # FIXME: figure out a less roundabout way of doing this. + installkernel = buildPackages.writeShellScriptBin "installkernel" '' + cp -av $2 $4 + cp -av $3 $4 + ''; + in '' + installFlagsArray+=("-j$NIX_BUILD_CORES") + export HOME=${installkernel} + ''; + + # Some image types need special install targets (e.g. uImage is installed with make uinstall on arm) + installTargets = [ + (kernelConf.installTarget or ( + /**/ if kernelConf.target == "uImage" && stdenv.hostPlatform.linuxArch == "arm" then "uinstall" + else if kernelConf.target == "zImage" || kernelConf.target == "Image.gz" || kernelConf.target == "vmlinuz.efi" then "zinstall" + else "install")) + ]; + + # We remove a bunch of stuff that is symlinked from other places to save space, + # which trips the broken symlink check. So, just skip it. We'll know if it explodes. + dontCheckForBrokenSymlinks = true; + + postInstall = optionalString isModular '' + mkdir -p $dev + cp vmlinux $dev/ + if [ -z "''${dontStrip-}" ]; then + installFlagsArray+=("INSTALL_MOD_STRIP=1") + fi + make modules_install $makeFlags "''${makeFlagsArray[@]}" \ + $installFlags "''${installFlagsArray[@]}" + unlink $out/lib/modules/${modDirVersion}/build + rm -f $out/lib/modules/${modDirVersion}/source + + mkdir -p $dev/lib/modules/${modDirVersion}/{build,source} + + # To save space, exclude a bunch of unneeded stuff when copying. + (cd .. && rsync --archive --prune-empty-dirs \ + --exclude='/build/' \ + * $dev/lib/modules/${modDirVersion}/source/) + + cd $dev/lib/modules/${modDirVersion}/source + + cp $buildRoot/{.config,Module.symvers} $dev/lib/modules/${modDirVersion}/build + make modules_prepare $makeFlags "''${makeFlagsArray[@]}" O=$dev/lib/modules/${modDirVersion}/build + + # For reproducibility, removes accidental leftovers from a `cc1` call + # from a `try-run` call from the Makefile + rm -f $dev/lib/modules/${modDirVersion}/build/.[0-9]*.d + + # Keep some extra files on some arches (powerpc, aarch64) + for f in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o; do + if [ -f "$buildRoot/$f" ]; then + cp $buildRoot/$f $dev/lib/modules/${modDirVersion}/build/$f + fi + done + + # !!! No documentation on how much of the source tree must be kept + # If/when kernel builds fail due to missing files, you can add + # them here. Note that we may see packages requiring headers + # from drivers/ in the future; it adds 50M to keep all of its + # headers on 3.10 though. + + chmod u+w -R .. + arch=$(cd $dev/lib/modules/${modDirVersion}/build/arch; ls) + + # Remove unused arches + for d in $(cd arch/; ls); do + if [ "$d" = "$arch" ]; then continue; fi + if [ "$arch" = arm64 ] && [ "$d" = arm ]; then continue; fi + rm -rf arch/$d + done + + # Remove all driver-specific code (50M of which is headers) + rm -fR drivers + + # Keep all headers + find . -type f -name '*.h' -print0 | xargs -0 -r chmod u-w + + # Keep linker scripts (they are required for out-of-tree modules on aarch64) + find . -type f -name '*.lds' -print0 | xargs -0 -r chmod u-w + + # Keep root and arch-specific Makefiles + chmod u-w Makefile arch/"$arch"/Makefile* + + # Keep whole scripts dir + chmod u-w -R scripts + + # Delete everything not kept + find . -type f -perm -u=w -print0 | xargs -0 -r rm + + # Delete empty directories + find -empty -type d -delete + ''; + + requiredSystemFeatures = [ "big-parallel" ]; + + meta = { + # https://github.com/NixOS/nixpkgs/pull/345534#issuecomment-2391238381 + broken = withRust && lib.versionOlder version "6.12"; + + description = + "The Linux kernel" + + (if kernelPatches == [] then "" else + " (with patches: " + + lib.concatStringsSep ", " (map (x: x.name) kernelPatches) + + ")"); + license = lib.licenses.gpl2Only; + homepage = "https://www.kernel.org/"; + maintainers = lib.teams.linux-kernel.members ++ [ + maintainers.thoughtpolice + ]; + platforms = platforms.linux; + badPlatforms = + lib.optionals (lib.versionOlder version "4.15") [ "riscv32-linux" "riscv64-linux" ] ++ + lib.optional (lib.versionOlder version "5.19") "loongarch64-linux"; + timeout = 14400; # 4 hours + } // extraMeta; + }; + + # Absolute paths for compilers avoid any PATH-clobbering issues. + commonMakeFlags = [ + "ARCH=${stdenv.hostPlatform.linuxArch}" + "CROSS_COMPILE=${stdenv.cc.targetPrefix}" + ] ++ lib.optionals (stdenv.isx86_64 && stdenv.cc.bintools.isLLVM) [ + # The wrapper for ld.lld breaks linking the kernel. We use the + # unwrapped linker as workaround. See: + # + # https://github.com/NixOS/nixpkgs/issues/321667 + "LD=${stdenv.cc.bintools.bintools}/bin/${stdenv.cc.targetPrefix}ld" + ] ++ (stdenv.hostPlatform.linux-kernel.makeFlags or []) + ++ extraMakeFlags; +in + +stdenv.mkDerivation ( + builtins.foldl' lib.recursiveUpdate {} [ + (drvAttrs config stdenv.hostPlatform.linux-kernel kernelPatches configfile) + { + inherit pname version; + + enableParallelBuilding = true; + + hardeningDisable = [ "bindnow" "format" "fortify" "stackprotector" "pic" "pie" ]; + + makeFlags = [ + "O=$(buildRoot)" + ] ++ commonMakeFlags; + + passthru = { inherit commonMakeFlags; }; + + karch = stdenv.hostPlatform.linuxArch; + } + (optionalAttrs (pos != null) { inherit pos; }) + ] +)) diff --git a/pkgs/kernel/result b/pkgs/kernel/result new file mode 120000 index 0000000..adacbb4 --- /dev/null +++ b/pkgs/kernel/result @@ -0,0 +1 @@ +/nix/store/kwigngi2rkbhd5qmhjaxla2wh3adm4ph-linux-6.13.4-patos1 \ No newline at end of file diff --git a/pkgs/openssl/default.nix b/pkgs/openssl/default.nix index 0e1f742..bc833cc 100644 --- a/pkgs/openssl/default.nix +++ b/pkgs/openssl/default.nix @@ -92,7 +92,7 @@ stdenv.mkDerivation rec { configureFlags = [ "shared" # "shared" builds both shared and static libraries - "--prefix=/usr" + "--prefix=/" "--libdir=lib" "--openssldir=/etc/ssl" ] diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix index c7f0dba..d3c39c3 100644 --- a/pkgs/rootfs/default.nix +++ b/pkgs/rootfs/default.nix @@ -7,10 +7,12 @@ }: let pname = "patos-rootfs"; + defaultPassword = "patos"; in stdenvNoCC.mkDerivation (finalAttrs: { inherit version; inherit pname; + inherit defaultPassword; buildInputs = with pkgs; [ glibc @@ -20,7 +22,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { glibcPatos = patosPkgs.glibc.out; systemd = patosPkgs.systemd.out; dbusBroker = patosPkgs.dbus-broker.out; - kernel = patosPkgs.kernel.kernel; + kernel = patosPkgs.kernel; busybox = patosPkgs.busybox.out; kmodLibs = pkgs.kmod.lib; kmodBin = pkgs.kmod.out; diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 14f4dac..7e8df9e 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -62,6 +62,7 @@ Type=root SizeMaxBytes=256M SizeMinBytes=256M EOF + cat <<EOF > $out/etc/repart.d/22-root-verify-a.conf [Partition] Type=root-verity @@ -77,6 +78,7 @@ SizeMaxBytes=256M SizeMinBytes=256M ReadOnly=1 EOF + cat <<EOF > $out/etc/repart.d/32-root-verity-b.conf [Partition] Type=root-verity @@ -90,13 +92,15 @@ cat <<EOF > $out/etc/repart.d/40-var.conf [Partition] Type=var Format=btrfs -MakeDirectories=/var/lib/confexts /var/.snapshots +MakeDirectories=/var/lib/confexts /var/lib/extensions /var/lib/portables /var/.snapshots MountPoint=/var Label=patos-state Encrypt=tpm2 EncryptedVolume=patos-state:none:tpm2-device=auto,luks,discard -Subvolumes=/var/lib/confexts /var/.snapshots +Subvolumes=/var/lib/confexts /var/lib/extensions /var/lib/portables /var/.snapshots MountPoint=/var/lib/confexts:subvol=/var/lib/confexts +MountPoint=/var/lib/extensions:subvol=/var/lib/extensions +MountPoint=/var/lib/portables:subvol=/var/lib/portables MountPoint=/var/.snapshots:subvol=/var/.snapshots SizeMinBytes=1G Minimize=off @@ -116,13 +120,9 @@ EOF cp -P $glibcPatos/lib/*.so* $out/usr/lib/ ### install openssl -cp -P $openssl/usr/lib/*.so* $out/usr/lib/ +cp -P $openssl/lib/*.so* $out/usr/lib/ cp -Pr $openssl/etc/ssl $out/etc/ -### install kernel modules -cp -r $kernel/lib/modules $out/usr/lib/ -find $out/usr/lib/modules -type d -exec chmod 755 {} \; - ### install busybox cp $busybox/bin/busybox $out/usr/bin/ $out/usr/bin/busybox --list | xargs -I {} ln -sf busybox $out/usr/bin/{} @@ -150,11 +150,13 @@ cp -P $kmodLibs/lib/*.so* $out/usr/lib/ cp -P $kmodBin/bin/* $out/usr/bin ### install libbpf -cp -P $libbpf/lib/libbpf* $out/usr/lib +cp -P $libbpf/lib/libbpf*.so* $out/usr/lib ### install ca cert bundle -chmod 755 $out/etc/ssl +chmod 755 $out/etc/ssl $out/etc/ssl/certs cp -P $cacert/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/cert.pem +ln -sf ../cert.pem $out/etc/ssl/certs/ca-certificates.crt +ln -sf ../cert.pem $out/etc/ssl/certs/ca-bundle.crt # setup default files $systemd/usr/bin/systemd-hwdb --root=$out --usr update @@ -162,6 +164,13 @@ $systemd/usr/bin/systemd-tmpfiles --root=$out $out/usr/lib/tmpfiles.d/etc.conf - cp $out/usr/share/factory/etc/nsswitch.conf $out/etc/ cp $out/usr/share/factory/etc/locale.conf $out/etc/ cp $out/usr/share/factory/etc/vconsole.conf $out/etc/ +# install sys users +mkdir creds +echo -n $defaultPassword > creds/passwd.plaintext-password.root +CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=$out rootfs/usr/lib/sysusers.d/*.conf +chmod 600 $out/etc/shadow +rm -rf creds + # Ephemeral machine-id until registration ln -sf /run/machine-id $out/etc/machine-id @@ -171,7 +180,7 @@ rm -rf $out/usr/lib/pkgconfig ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ - grep -v systemd | grep -v glibc | grep -v openssl | grep -v tpm2 | grep -v devmapper | grep -v not | \ + grep -vE "(systemd|glibc|openssl|tpm2|devmapper)" | \ sort -u | xargs -I {} cp {} $out/usr/lib/ find $out -type f -executable -exec chmod 755 {} \; @@ -184,3 +193,8 @@ patchelf --remove-rpath $out/usr/lib/ld-linux-x86-64.so.2 # strip binaries find $out -type f -executable -exec strip {} \; find $out -type d -exec chmod 755 {} \; + +### install kernel modules +cp -r $kernel/lib/modules $out/usr/lib/ +find $out/usr/lib/modules -type d -exec chmod 755 {} \; + From 1fcc45dd321e75e130a6048f1cacaad33d94890c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Fri, 14 Mar 2025 07:52:35 +0100 Subject: [PATCH 44/67] feat: add factory reset UKI --- pkgs/image/mkimage.sh | 25 ++++++++++++++++++++++--- pkgs/rootfs/mkrootfs.sh | 4 ++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index df56849..8c94348 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -74,21 +74,40 @@ $systemd/usr/bin/ukify build \ --os-release @rootfs/etc/os-release \ --cmdline "$kernelCmdLine roothash=$roothash" \ -o patos_${version}.efi + +cat <<EOF > reset-os-release +NAME=PatOS +PRETTY_NAME=PatOS Factory Reset +IMAGE_ID=patos +ID=patos +IMAGE_VERSION=${version} +VERSION=${version} +VERSION_ID=patos +EOF + +$systemd/usr/bin/ukify build \ + --linux $kernel/bzImage \ + --initrd $initrd/initrd.xz \ + --os-release @./reset-os-release \ + --cmdline "$kernelCmdLine roothash=$roothash systemd.factory_reset=yes" \ + -o patos_factory_reset.efi rm -rf rootfs cp patos_${version}.efi boot/ +cp patos_factory_reset.efi boot/ cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ -echo "timeout 1" > boot/loader.conf +echo "timeout 2" > boot/loader.conf # Final partitioning cat <<EOF > final.repart.d/10-esp.conf [Partition] Type=esp Format=vfat -SizeMinBytes=96M -SizeMaxBytes=96M +SizeMinBytes=160M +SizeMaxBytes=160M CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI CopyFiles=/boot/patos_${version}.efi:/EFI/Linux/patos_${version}.efi +CopyFiles=/boot/patos_factory_reset.efi:/EFI/Linux/patos_factory_reset.efi CopyFiles=/boot/loader.conf:/loader/loader.conf EOF diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.sh index 7e8df9e..3ccc93c 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.sh @@ -52,8 +52,8 @@ cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] Type=esp Format=vfat -SizeMaxBytes=96M -SizeMinBytes=96M +SizeMaxBytes=160M +SizeMinBytes=160M EOF cat <<EOF > $out/etc/repart.d/20-root-a.conf From 1f1c93b775b3ef6d2b25fad3f475cb28b5be0783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Fri, 14 Mar 2025 10:45:39 +0100 Subject: [PATCH 45/67] feat: enable secure boot --- pkgs/image/default.nix | 1 + pkgs/image/mkimage.sh | 37 ++++++++++++++++++++---------- pkgs/systemd/default.nix | 2 ++ pkgs/systemd/skip-verify-esp.patch | 24 +++++++++++++++++++ 4 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 pkgs/systemd/skip-verify-esp.patch diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 74e0931..5612185 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -18,6 +18,7 @@ stdenvNoCC.mkDerivation (finalAttrs: { mtools e2fsprogs jq + openssl ]; env = { diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 8c94348..3e6ed9e 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -58,8 +58,7 @@ $systemd/usr/bin/systemd-repart \ --split=true \ --json=pretty \ --root=$out \ - patos-$version.raw > init-repart-output.json -rm -f patos-$version.raw + patos-$version.raw > init-repart-output.json && rm -f patos-$version.raw roothash=$(jq -r '.[0].roothash' init-repart-output.json) rootPart=$(jq -r '.[0].split_path' init-repart-output.json) @@ -91,12 +90,29 @@ $systemd/usr/bin/ukify build \ --os-release @./reset-os-release \ --cmdline "$kernelCmdLine roothash=$roothash systemd.factory_reset=yes" \ -o patos_factory_reset.efi -rm -rf rootfs -cp patos_${version}.efi boot/ -cp patos_factory_reset.efi boot/ -cp ${systemd}/usr/lib/systemd/boot/efi/systemd-bootx64.efi boot/ -echo "timeout 2" > boot/loader.conf +# Secure boot +openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout key.pem -subj "/CN=patagia-signing" + +SYSTEMD_RELAX_ESP_CHECKS=1 $systemd/usr/bin/bootctl install --root ./rootfs --esp-path /boot \ + --secure-boot-auto-enroll=true --certificate=./cert.pem --private-key=./key.pem + +# install UKIs +cp patos_${version}.efi rootfs/boot/EFI/Linux +cp patos_factory_reset.efi rootfs/boot/EFI/Linux + +# sign EFIs +$systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ + rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI + +$systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ + rootfs/boot/EFI/Linux/patos_0.0.1.efi --output=rootfs/boot/EFI/Linux/patos_0.0.1.efi + +$systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ + rootfs/boot/EFI/Linux/patos_factory_reset.efi --output=rootfs/boot/EFI/Linux/patos_factory_reset.efi + +echo "timeout 2" > rootfs/boot/loader/loader.conf +echo "secure-boot-enroll force" >> rootfs/boot/loader/loader.conf # Final partitioning cat <<EOF > final.repart.d/10-esp.conf @@ -105,10 +121,7 @@ Type=esp Format=vfat SizeMinBytes=160M SizeMaxBytes=160M -CopyFiles=/boot/systemd-bootx64.efi:/EFI/BOOT/BOOTX64.EFI -CopyFiles=/boot/patos_${version}.efi:/EFI/Linux/patos_${version}.efi -CopyFiles=/boot/patos_factory_reset.efi:/EFI/Linux/patos_factory_reset.efi -CopyFiles=/boot/loader.conf:/loader/loader.conf +CopyFiles=/rootfs/boot:/ EOF cat <<EOF > final.repart.d/20-root.conf @@ -142,6 +155,6 @@ $systemd/usr/bin/systemd-repart \ --root=$out \ patos-$version.raw > final-repart-output.json -rm -rf boot +rm -rf rootfs popd diff --git a/pkgs/systemd/default.nix b/pkgs/systemd/default.nix index b22d243..a1cb314 100644 --- a/pkgs/systemd/default.nix +++ b/pkgs/systemd/default.nix @@ -30,6 +30,8 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-6rxJUYRq785U6aik5VhQRqG+Ss67lBB6T3eQF+tkyhk="; }; + patches = [ ./skip-verify-esp.patch ]; + dontCheckForBrokenSymlinks = true; nativeBuildInputs = with pkgs; [ diff --git a/pkgs/systemd/skip-verify-esp.patch b/pkgs/systemd/skip-verify-esp.patch new file mode 100644 index 0000000..2cb9505 --- /dev/null +++ b/pkgs/systemd/skip-verify-esp.patch @@ -0,0 +1,24 @@ +diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c +index f830d6dfe3..7ad2a8cd1d 100644 +--- a/src/shared/find-esp.c ++++ b/src/shared/find-esp.c +@@ -403,15 +403,15 @@ static int verify_esp( + "File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p); + } + +- r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid); +- if (r < 0) +- return r; +- + /* In a container we don't have access to block devices, skip this part of the verification, we trust + * the container manager set everything up correctly on its own. */ + if (FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK)) + goto finish; + ++ r = verify_fsroot_dir(pfd, p, flags, FLAGS_SET(flags, VERIFY_ESP_SKIP_DEVICE_CHECK) ? NULL : &devid); ++ if (r < 0) ++ return r; ++ + if (devnum_is_zero(devid)) + return log_full_errno(searching ? LOG_DEBUG : LOG_ERR, + SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV), From 7376743266d48b3c3db49c9c6fdb711a25b660c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Fri, 14 Mar 2025 15:13:31 +0100 Subject: [PATCH 46/67] chore: clean up --- pkgs/image/mkimage.sh | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh index 3e6ed9e..1d14349 100644 --- a/pkgs/image/mkimage.sh +++ b/pkgs/image/mkimage.sh @@ -74,44 +74,24 @@ $systemd/usr/bin/ukify build \ --cmdline "$kernelCmdLine roothash=$roothash" \ -o patos_${version}.efi -cat <<EOF > reset-os-release -NAME=PatOS -PRETTY_NAME=PatOS Factory Reset -IMAGE_ID=patos -ID=patos -IMAGE_VERSION=${version} -VERSION=${version} -VERSION_ID=patos -EOF - -$systemd/usr/bin/ukify build \ - --linux $kernel/bzImage \ - --initrd $initrd/initrd.xz \ - --os-release @./reset-os-release \ - --cmdline "$kernelCmdLine roothash=$roothash systemd.factory_reset=yes" \ - -o patos_factory_reset.efi - # Secure boot openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout key.pem -subj "/CN=patagia-signing" +# install ESP SYSTEMD_RELAX_ESP_CHECKS=1 $systemd/usr/bin/bootctl install --root ./rootfs --esp-path /boot \ --secure-boot-auto-enroll=true --certificate=./cert.pem --private-key=./key.pem - -# install UKIs -cp patos_${version}.efi rootfs/boot/EFI/Linux -cp patos_factory_reset.efi rootfs/boot/EFI/Linux +echo "timeout 2" > rootfs/boot/loader/loader.conf # sign EFIs $systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI $systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ - rootfs/boot/EFI/Linux/patos_0.0.1.efi --output=rootfs/boot/EFI/Linux/patos_0.0.1.efi + patos_${version}.efi --output=patos_${version}.efi -$systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ - rootfs/boot/EFI/Linux/patos_factory_reset.efi --output=rootfs/boot/EFI/Linux/patos_factory_reset.efi +# install UKI +cp patos_${version}.efi rootfs/boot/EFI/Linux -echo "timeout 2" > rootfs/boot/loader/loader.conf echo "secure-boot-enroll force" >> rootfs/boot/loader/loader.conf # Final partitioning From b619c6f01d9d91e86e32fe5415bfd2ffe7094c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Sat, 15 Mar 2025 18:26:28 +0100 Subject: [PATCH 47/67] chore: remove result symlink --- pkgs/kernel/result | 1 - 1 file changed, 1 deletion(-) delete mode 120000 pkgs/kernel/result diff --git a/pkgs/kernel/result b/pkgs/kernel/result deleted file mode 120000 index adacbb4..0000000 --- a/pkgs/kernel/result +++ /dev/null @@ -1 +0,0 @@ -/nix/store/kwigngi2rkbhd5qmhjaxla2wh3adm4ph-linux-6.13.4-patos1 \ No newline at end of file From 1725120a49ac03c29562c085984c880441843a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Sat, 15 Mar 2025 18:49:38 +0100 Subject: [PATCH 48/67] chore: upgrade kernel --- pkgs/kernel/default.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix index c5dabce..edbfb65 100644 --- a/pkgs/kernel/default.nix +++ b/pkgs/kernel/default.nix @@ -1,14 +1,14 @@ -{ pkgs, lib, stdenv, ... }: +{ pkgs }: let - version = "6.13.4"; + version = "6.13.7"; + hash = "sha256-Ojm2IDi3rC9D0mofhLQoPhl4BOHoF61jfpo9h0xHgB0="; in - (pkgs.callPackage ./manual-config.nix { }) { - inherit lib stdenv; + (pkgs.callPackage ./manual-config.nix {}) { version = "${version}-patos1"; modDirVersion = version; src = pkgs.fetchurl { url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz"; - hash = "sha256-uA4LyO+8MenOWoTRCE3Mz6QOAb6ozCWv0GZIuT1hM54="; + hash = hash; }; configfile = ./generic.config; allowImportFromDerivation = true; From a3e2a970f896821f75c9f57962953d77c4c5a39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 17 Mar 2025 10:18:30 +0100 Subject: [PATCH 49/67] chore: clean up --- flake.nix | 80 +- pkgs/cert/default.nix | 17 + pkgs/image/default.nix | 149 +++- pkgs/image/mkimage.sh | 140 --- pkgs/kernel/default.nix | 20 +- pkgs/kernel/generic.config | 7 +- pkgs/kernel/manual-config.nix | 981 ++++++++++++---------- pkgs/rootfs/default.nix | 38 - pkgs/rootfs/mkinitrd.nix | 67 +- pkgs/rootfs/mkinitrd.sh | 53 -- pkgs/rootfs/{mkrootfs.sh => mkrootfs.nix} | 65 +- 11 files changed, 845 insertions(+), 772 deletions(-) create mode 100644 pkgs/cert/default.nix delete mode 100644 pkgs/image/mkimage.sh delete mode 100644 pkgs/rootfs/default.nix delete mode 100644 pkgs/rootfs/mkinitrd.sh rename pkgs/rootfs/{mkrootfs.sh => mkrootfs.nix} (75%) diff --git a/flake.nix b/flake.nix index 5b1774f..2358ab1 100644 --- a/flake.nix +++ b/flake.nix @@ -22,22 +22,14 @@ { packages = { default = patosPkgs.image; - image = pkgs.callPackage ./pkgs/image { - inherit patosPkgs; - inherit version; - }; - rootfs = pkgs.callPackage ./pkgs/rootfs { - inherit patosPkgs; - inherit version; - }; - initrd = pkgs.callPackage ./pkgs/rootfs/mkinitrd.nix { - inherit patosPkgs; - inherit version; - }; + image = pkgs.callPackage ./pkgs/image { inherit patosPkgs version; }; + rootfs = pkgs.callPackage ./pkgs/rootfs/mkrootfs.nix { inherit patosPkgs version; }; + initrd = pkgs.callPackage ./pkgs/rootfs/mkinitrd.nix { inherit patosPkgs version; }; kernel = pkgs.callPackage ./pkgs/kernel { }; glibc = pkgs.callPackage ./pkgs/glibc { }; busybox = pkgs.callPackage ./pkgs/busybox { }; openssl = pkgs.callPackage ./pkgs/openssl { }; + cert = pkgs.callPackage ./pkgs/cert { }; kexec = pkgs.callPackage ./pkgs/kexec-tools { }; lvm2 = pkgs.callPackage ./pkgs/lvm2 { }; tpm2-tools = pkgs.callPackage ./pkgs/tpm2-tools { inherit patosPkgs; }; @@ -51,38 +43,38 @@ name = "debug-tools"; version = "0.0.1"; packages = [ - { drv = pkgs.curl; path = "bin/curl"; } - { drv = pkgs.bash; path = "bin/bash"; } - { drv = patosPkgs.glibc; path = "bin/ldd"; } - { drv = pkgs.keyutils; path = "bin/keyctl"; } - { drv = pkgs.gnutar; path = "bin/tar"; } - { drv = pkgs.binutils-unwrapped; path = "bin/strings"; } - { drv = pkgs.strace; path = "bin/strace"; } - { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } - { drv = patosPkgs.openssl; path = "bin/openssl"; } - { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } - { drv = pkgs.cryptsetup; path = "bin/veritysetup"; } - { drv = pkgs.erofs-utils; path = "bin/mkfs.erofs"; } - # shared lib required for cryptsetup - { drv = pkgs.popt; path = "lib/libpopt.so.0.0.2"; } - { drv = pkgs.popt; path = "lib/libpopt.so.0"; } - { drv = pkgs.popt; path = "lib/libpopt.so"; } - # shared lib required for mkfs.erofs - { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1.10.0"; } - { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1"; } - { drv = pkgs.lz4.lib; path = "lib/liblz4.so"; } - # shared lib required for binutils - { drv = pkgs.binutils-unwrapped.lib; path = "lib/libsframe.so.1.0.0"; } - { drv = pkgs.binutils-unwrapped.lib; path = "lib/libsframe.so.1"; } - { drv = pkgs.binutils-unwrapped.lib; path = "lib/libbfd-2.43.1.so"; } - { drv = pkgs.binutils-unwrapped.lib; path = "lib/libbfd.so"; } - # shared lib required for strace - { drv = pkgs.elfutils.out; path = "lib/libdw-0.192.so"; } - { drv = pkgs.elfutils.out; path = "lib/libdw.so.1"; } - { drv = pkgs.elfutils.out; path = "lib/libdw.so"; } - { drv = pkgs.elfutils.out; path = "lib/libelf-0.192.so"; } - { drv = pkgs.elfutils.out; path = "lib/libelf.so.1"; } - { drv = pkgs.elfutils.out; path = "lib/libelf.so"; } + { drv = pkgs.curl; path = "bin/curl"; } + { drv = pkgs.bash; path = "bin/bash"; } + { drv = patosPkgs.glibc; path = "bin/ldd"; } + { drv = pkgs.keyutils; path = "bin/keyctl"; } + { drv = pkgs.gnutar; path = "bin/tar"; } + { drv = pkgs.binutils-unwrapped; path = "bin/strings"; } + { drv = pkgs.strace; path = "bin/strace"; } + { drv = patosPkgs.tpm2-tools; path = "bin/tpm2"; } + { drv = patosPkgs.openssl; path = "bin/openssl"; } + { drv = pkgs.cryptsetup; path = "bin/cryptsetup"; } + { drv = pkgs.cryptsetup; path = "bin/veritysetup"; } + { drv = pkgs.erofs-utils; path = "bin/mkfs.erofs"; } + # shared lib required for cryptsetup + { drv = pkgs.popt; path = "lib/libpopt.so.0.0.2"; } + { drv = pkgs.popt; path = "lib/libpopt.so.0"; } + { drv = pkgs.popt; path = "lib/libpopt.so"; } + # shared lib required for mkfs.erofs + { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1.10.0"; } + { drv = pkgs.lz4.lib; path = "lib/liblz4.so.1"; } + { drv = pkgs.lz4.lib; path = "lib/liblz4.so"; } + # shared lib required for binutils + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libsframe.so.1.0.0"; } + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libsframe.so.1"; } + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libbfd-2.43.1.so"; } + { drv = pkgs.binutils-unwrapped.lib; path = "lib/libbfd.so"; } + # shared lib required for strace + { drv = pkgs.elfutils.out; path = "lib/libdw-0.192.so"; } + { drv = pkgs.elfutils.out; path = "lib/libdw.so.1"; } + { drv = pkgs.elfutils.out; path = "lib/libdw.so"; } + { drv = pkgs.elfutils.out; path = "lib/libelf-0.192.so"; } + { drv = pkgs.elfutils.out; path = "lib/libelf.so.1"; } + { drv = pkgs.elfutils.out; path = "lib/libelf.so"; } ]; }; }; diff --git a/pkgs/cert/default.nix b/pkgs/cert/default.nix new file mode 100644 index 0000000..f3237e9 --- /dev/null +++ b/pkgs/cert/default.nix @@ -0,0 +1,17 @@ +{ + runCommand, + pkgs, + +}: + +runCommand "patagia-certs" + { + buildInputs = with pkgs; [ + openssl + ]; + + } + '' + mkdir -pv $out + openssl req -new -x509 -days 365 -nodes -out $out/cert.pem -keyout $out/key.pem -subj "/CN=patagia-signing" + '' diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 5612185..7d5f565 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -1,16 +1,15 @@ { pkgs, - stdenvNoCC, patosPkgs, version, + runCommand, ... }: let pname = "patos-image"; in -stdenvNoCC.mkDerivation (finalAttrs: { +runCommand pname { inherit version; - inherit pname; buildInputs = with pkgs; [ erofs-utils @@ -27,12 +26,142 @@ stdenvNoCC.mkDerivation (finalAttrs: { SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; # -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; }; - systemd = patosPkgs.systemd.out; - kernel = patosPkgs.kernel; - initrd = patosPkgs.initrd.out; - rootfs = patosPkgs.rootfs.out; - kernelCmdLine = "console=ttyS0"; +} +'' +mkdir -p $out/init.repart.d $out/final.repart.d $out/boot +pushd $out - builder = ./mkimage.sh; -}) +# Don't seem to work just to create a symlink to rootfs derivation? +# ln -sf $rootfs rootfs +mkdir rootfs +cp -prP ${patosPkgs.rootfs}/* rootfs/ +find rootfs/ -type d -exec chmod 755 {} \; + +# set default target to multi-user +ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target + +# enable dbus +ln -sf ../dbus.service rootfs/usr/lib/systemd/system/multi-user.target.wants/dbus.service +ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket + +# enable network services +ln -sf ../systemd-networkd.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-networkd.service +ln -sf ../systemd-resolved.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-resolved.service +ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.target.wants/systemd-timesyncd.service +# enable default network config +mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network + +# enable confext/sysext services +ln -sf ../systemd-confext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-confext.service +ln -sf ../systemd-sysext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-sysext.service + +# Initial partitioning +cat <<EOF > init.repart.d/10-root.conf +[Partition] +Type=root +Format=erofs +Minimize=best +CopyFiles=/rootfs:/ +Verity=data +VerityMatchKey=root +SplitName=root +EOF + +cat <<EOF > init.repart.d/20-root-verity.conf +[Partition] +Type=root-verity +Verity=hash +VerityMatchKey=root +Minimize=best +SplitName=verity +EOF + +#TODO: Add verity signature partition + +${patosPkgs.systemd}/usr/bin/systemd-repart \ + --no-pager \ + --empty=create \ + --size=auto \ + --definitions=./init.repart.d \ + --split=true \ + --json=pretty \ + --root=$out \ + patos-$version.raw > init-repart-output.json && rm -f patos-$version.raw + +roothash=$(jq -r '.[0].roothash' init-repart-output.json) +rootPart=$(jq -r '.[0].split_path' init-repart-output.json) +rootUuid=$(jq -r '.[0].uuid' init-repart-output.json) + +verityPart=$(jq -r '.[1].split_path' init-repart-output.json) +verityUuid=$(jq -r '.[1].uuid' init-repart-output.json) + +${patosPkgs.systemd}/usr/bin/ukify build \ + --linux ${patosPkgs.kernel}/bzImage \ + --initrd ${patosPkgs.initrd}/initrd.xz \ + --os-release @rootfs/etc/os-release \ + --cmdline "$kernelCmdLine roothash=$roothash" \ + -o patos_${version}.efi + +# install ESP +SYSTEMD_RELAX_ESP_CHECKS=1 ${patosPkgs.systemd}/usr/bin/bootctl install --root ./rootfs --esp-path /boot \ + --secure-boot-auto-enroll=true --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem +echo "timeout 2" > rootfs/boot/loader/loader.conf + +# sign EFIs +${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ + rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI + +${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ + patos_${version}.efi --output=patos_${version}.efi + +# install UKI +cp patos_${version}.efi rootfs/boot/EFI/Linux + +echo "secure-boot-enroll force" >> rootfs/boot/loader/loader.conf + +# Final partitioning +cat <<EOF > final.repart.d/10-esp.conf +[Partition] +Type=esp +Format=vfat +SizeMinBytes=160M +SizeMaxBytes=160M +CopyFiles=/rootfs/boot:/ +EOF + +cat <<EOF > final.repart.d/20-root.conf +[Partition] +Type=root +Label=root-${version} +CopyBlocks=/$rootPart +UUID=$rootUuid +SizeMinBytes=256M +SizeMaxBytes=256M +ReadOnly=1 +EOF + +cat <<EOF > final.repart.d/22-root-verity.conf +[Partition] +Type=root-verity +Label=verity-${version} +CopyBlocks=/$verityPart +UUID=$verityUuid +SizeMinBytes=10M +SizeMaxBytes=10M +ReadOnly=1 +EOF + +# finalize image ready for boot +${patosPkgs.systemd}/usr/bin/systemd-repart \ + --no-pager \ + --empty=create \ + --size=auto \ + --definitions=./final.repart.d \ + --root=$out \ + patos-$version.raw > final-repart-output.json + +rm -rf rootfs + +popd +'' diff --git a/pkgs/image/mkimage.sh b/pkgs/image/mkimage.sh deleted file mode 100644 index 1d14349..0000000 --- a/pkgs/image/mkimage.sh +++ /dev/null @@ -1,140 +0,0 @@ -set -ex -o pipefail - -mkdir -p $out/init.repart.d $out/final.repart.d $out/boot -pushd $out - -# Don't seem to work just to create a symlink to rootfs derivation? -# ln -sf $rootfs rootfs -mkdir rootfs -cp -prP $rootfs/* rootfs/ -find rootfs/ -type d -exec chmod 755 {} \; - -# set default target to multi-user -ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target - -# enable dbus -ln -sf ../dbus.service rootfs/usr/lib/systemd/system/multi-user.target.wants/dbus.service -ln -sf ../dbus.socket rootfs/usr/lib/systemd/system/sockets.target.wants/dbus.socket - -# enable network services -ln -sf ../systemd-networkd.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-networkd.service -ln -sf ../systemd-resolved.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-resolved.service -ln -sf ../systemd-timesyncd.service rootfs/usr/lib/systemd/system/multi-user.target.wants/systemd-timesyncd.service -# enable default network config -mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/systemd/network/89-ethernet.network - -# enable confext/sysext services -ln -sf ../systemd-confext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-confext.service -ln -sf ../systemd-sysext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-sysext.service - -# Initial partitioning -cat <<EOF > init.repart.d/10-root.conf -[Partition] -Type=root -Format=erofs -Minimize=best -CopyFiles=/rootfs:/ -Verity=data -VerityMatchKey=root -SplitName=root -EOF - -cat <<EOF > init.repart.d/20-root-verity.conf -[Partition] -Type=root-verity -Verity=hash -VerityMatchKey=root -Minimize=best -SplitName=verity -EOF - -#TODO: Add verity signature partition - -$systemd/usr/bin/systemd-repart \ - --no-pager \ - --empty=create \ - --size=auto \ - --definitions=./init.repart.d \ - --split=true \ - --json=pretty \ - --root=$out \ - patos-$version.raw > init-repart-output.json && rm -f patos-$version.raw - -roothash=$(jq -r '.[0].roothash' init-repart-output.json) -rootPart=$(jq -r '.[0].split_path' init-repart-output.json) -rootUuid=$(jq -r '.[0].uuid' init-repart-output.json) - -verityPart=$(jq -r '.[1].split_path' init-repart-output.json) -verityUuid=$(jq -r '.[1].uuid' init-repart-output.json) - -$systemd/usr/bin/ukify build \ - --linux $kernel/bzImage \ - --initrd $initrd/initrd.xz \ - --os-release @rootfs/etc/os-release \ - --cmdline "$kernelCmdLine roothash=$roothash" \ - -o patos_${version}.efi - -# Secure boot -openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout key.pem -subj "/CN=patagia-signing" - -# install ESP -SYSTEMD_RELAX_ESP_CHECKS=1 $systemd/usr/bin/bootctl install --root ./rootfs --esp-path /boot \ - --secure-boot-auto-enroll=true --certificate=./cert.pem --private-key=./key.pem -echo "timeout 2" > rootfs/boot/loader/loader.conf - -# sign EFIs -$systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ - rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI - -$systemd/usr/lib/systemd/systemd-sbsign sign --certificate=./cert.pem --private-key=./key.pem \ - patos_${version}.efi --output=patos_${version}.efi - -# install UKI -cp patos_${version}.efi rootfs/boot/EFI/Linux - -echo "secure-boot-enroll force" >> rootfs/boot/loader/loader.conf - -# Final partitioning -cat <<EOF > final.repart.d/10-esp.conf -[Partition] -Type=esp -Format=vfat -SizeMinBytes=160M -SizeMaxBytes=160M -CopyFiles=/rootfs/boot:/ -EOF - -cat <<EOF > final.repart.d/20-root.conf -[Partition] -Type=root -Label=root-${version} -CopyBlocks=/${rootPart} -UUID=${rootUuid} -SizeMinBytes=256M -SizeMaxBytes=256M -ReadOnly=1 -EOF - -cat <<EOF > final.repart.d/22-root-verity.conf -[Partition] -Type=root-verity -Label=verity-${version} -CopyBlocks=/${verityPart} -UUID=${verityUuid} -SizeMinBytes=10M -SizeMaxBytes=10M -ReadOnly=1 -EOF - -# finalize image ready for boot -$systemd/usr/bin/systemd-repart \ - --no-pager \ - --empty=create \ - --size=auto \ - --definitions=./final.repart.d \ - --root=$out \ - patos-$version.raw > final-repart-output.json - -rm -rf rootfs - -popd diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix index edbfb65..a5f24db 100644 --- a/pkgs/kernel/default.nix +++ b/pkgs/kernel/default.nix @@ -3,13 +3,13 @@ let version = "6.13.7"; hash = "sha256-Ojm2IDi3rC9D0mofhLQoPhl4BOHoF61jfpo9h0xHgB0="; in - (pkgs.callPackage ./manual-config.nix {}) { - version = "${version}-patos1"; - modDirVersion = version; - src = pkgs.fetchurl { - url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz"; - hash = hash; - }; - configfile = ./generic.config; - allowImportFromDerivation = true; - } +(pkgs.callPackage ./manual-config.nix { }) { + version = "${version}-patos1"; + modDirVersion = version; + src = pkgs.fetchurl { + url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${version}.tar.xz"; + hash = hash; + }; + configfile = ./generic.config; + allowImportFromDerivation = true; +} diff --git a/pkgs/kernel/generic.config b/pkgs/kernel/generic.config index 647bf91..048421b 100644 --- a/pkgs/kernel/generic.config +++ b/pkgs/kernel/generic.config @@ -522,10 +522,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_ENTRY=y CONFIG_DEBUG_FS_ALLOW_ALL=y CONFIG_DEBUG_FS=y -#CONFIG_DEBUG_INFO_BTF_MODULES=y -#CONFIG_DEBUG_INFO_BTF=y -#CONFIG_DEBUG_INFO_COMPRESSED_NONE=y -#CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y CONFIG_DEBUG_INFO=n CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_LIST=y @@ -1401,9 +1397,8 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_SIG=y -CONFIG_MODULE_SIG_FORCE=n +CONFIG_MODULE_SIG_FORCE=y CONFIG_MODULE_SIG_ALL=y -CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_MODULES=y diff --git a/pkgs/kernel/manual-config.nix b/pkgs/kernel/manual-config.nix index ffcf758..9f1ba99 100644 --- a/pkgs/kernel/manual-config.nix +++ b/pkgs/kernel/manual-config.nix @@ -1,465 +1,576 @@ -{ lib, stdenv, buildPackages, runCommand, nettools, bc, bison, flex, perl, rsync, gmp, libmpc, mpfr, openssl -, cpio, elfutils, hexdump, zstd, python3Minimal, zlib, pahole, kmod, ubootTools -, fetchpatch -, rustc, rust-bindgen, rustPlatform +{ + lib, + stdenv, + buildPackages, + runCommand, + nettools, + bc, + bison, + flex, + perl, + rsync, + gmp, + libmpc, + mpfr, + openssl, + cpio, + elfutils, + hexdump, + zstd, + python3Minimal, + zlib, + pahole, + kmod, + ubootTools, + fetchpatch, + rustc, + rust-bindgen, + rustPlatform, }: let lib_ = lib; stdenv_ = stdenv; - readConfig = configfile: import (runCommand "config.nix" {} '' - echo "{" > "$out" - while IFS='=' read key val; do - [ "x''${key#CONFIG_}" != "x$key" ] || continue - no_firstquote="''${val#\"}"; - echo ' "'"$key"'" = "'"''${no_firstquote%\"}"'";' >> "$out" - done < "${configfile}" - echo "}" >> $out - '').outPath; -in lib.makeOverridable ({ - # The kernel version - version, - # The kernel pname (should be set for variants) - pname ? "linux", - # Position of the Linux build expression - pos ? null, - # Additional kernel make flags - extraMakeFlags ? [], - # The name of the kernel module directory - # Needs to be X.Y.Z[-extra], so pad with zeros if needed. - modDirVersion ? null /* derive from version */, - # The kernel source (tarball, git checkout, etc.) - src, - # a list of { name=..., patch=..., extraConfig=...} patches - kernelPatches ? [], - # The kernel .config file - configfile, - # Manually specified nixexpr representing the config - # If unspecified, this will be autodetected from the .config - config ? lib.optionalAttrs allowImportFromDerivation (readConfig configfile), - # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is - # automatically extended with extra per-version and per-config values. - randstructSeed ? "", - # Extra meta attributes - extraMeta ? {}, - - # for module compatibility - isZen ? false, - isLibre ? false, - isHardened ? false, - - # Whether to utilize the controversial import-from-derivation feature to parse the config - allowImportFromDerivation ? false, - # ignored - features ? null, lib ? lib_, stdenv ? stdenv_, -}: - -let - # Provide defaults. Note that we support `null` so that callers don't need to use optionalAttrs, - # which can lead to unnecessary strictness and infinite recursions. - modDirVersion_ = if modDirVersion == null then lib.versions.pad 3 version else modDirVersion; + readConfig = + configfile: + import + (runCommand "config.nix" { } '' + echo "{" > "$out" + while IFS='=' read key val; do + [ "x''${key#CONFIG_}" != "x$key" ] || continue + no_firstquote="''${val#\"}"; + echo ' "'"$key"'" = "'"''${no_firstquote%\"}"'";' >> "$out" + done < "${configfile}" + echo "}" >> $out + '').outPath; in -let - # Shadow the un-defaulted parameter; don't want null. - modDirVersion = modDirVersion_; - inherit (lib) - hasAttr getAttr optional optionals optionalString optionalAttrs maintainers platforms; +lib.makeOverridable ( + { + # The kernel version + version, + # The kernel pname (should be set for variants) + pname ? "linux", + # Position of the Linux build expression + pos ? null, + # Additional kernel make flags + extraMakeFlags ? [ ], + # The name of the kernel module directory + # Needs to be X.Y.Z[-extra], so pad with zeros if needed. + modDirVersion ? null, # derive from version + # The kernel source (tarball, git checkout, etc.) + src, + # a list of { name=..., patch=..., extraConfig=...} patches + kernelPatches ? [ ], + # The kernel .config file + configfile, + # Manually specified nixexpr representing the config + # If unspecified, this will be autodetected from the .config + config ? lib.optionalAttrs allowImportFromDerivation (readConfig configfile), + # Custom seed used for CONFIG_GCC_PLUGIN_RANDSTRUCT if enabled. This is + # automatically extended with extra per-version and per-config values. + randstructSeed ? "", + # Extra meta attributes + extraMeta ? { }, - drvAttrs = config_: kernelConf: kernelPatches: configfile: - let - # Folding in `ubootTools` in the default nativeBuildInputs is problematic, as - # it makes updating U-Boot cumbersome, since it will go above the current - # threshold of rebuilds - # - # To prevent these needless rounds of staging for U-Boot builds, we can - # limit the inclusion of ubootTools to target platforms where uImage *may* - # be produced. - # - # This command lists those (kernel-named) platforms: - # .../linux $ grep -l uImage ./arch/*/Makefile | cut -d'/' -f3 | sort - # - # This is still a guesstimation, but since none of our cached platforms - # coincide in that list, this gives us "perfect" decoupling here. - linuxPlatformsUsingUImage = [ - "arc" - "arm" - "csky" - "mips" - "powerpc" - "sh" - "sparc" - "xtensa" - ]; - needsUbootTools = - lib.elem stdenv.hostPlatform.linuxArch linuxPlatformsUsingUImage + # for module compatibility + isZen ? false, + isLibre ? false, + isHardened ? false, + + # Whether to utilize the controversial import-from-derivation feature to parse the config + allowImportFromDerivation ? false, + # ignored + features ? null, + lib ? lib_, + stdenv ? stdenv_, + }: + + let + # Provide defaults. Note that we support `null` so that callers don't need to use optionalAttrs, + # which can lead to unnecessary strictness and infinite recursions. + modDirVersion_ = if modDirVersion == null then lib.versions.pad 3 version else modDirVersion; + in + let + # Shadow the un-defaulted parameter; don't want null. + modDirVersion = modDirVersion_; + inherit (lib) + hasAttr + getAttr + optional + optionals + optionalString + optionalAttrs + maintainers + platforms ; - config = let attrName = attr: "CONFIG_" + attr; in { - isSet = attr: hasAttr (attrName attr) config; + drvAttrs = + config_: kernelConf: kernelPatches: configfile: + let + # Folding in `ubootTools` in the default nativeBuildInputs is problematic, as + # it makes updating U-Boot cumbersome, since it will go above the current + # threshold of rebuilds + # + # To prevent these needless rounds of staging for U-Boot builds, we can + # limit the inclusion of ubootTools to target platforms where uImage *may* + # be produced. + # + # This command lists those (kernel-named) platforms: + # .../linux $ grep -l uImage ./arch/*/Makefile | cut -d'/' -f3 | sort + # + # This is still a guesstimation, but since none of our cached platforms + # coincide in that list, this gives us "perfect" decoupling here. + linuxPlatformsUsingUImage = [ + "arc" + "arm" + "csky" + "mips" + "powerpc" + "sh" + "sparc" + "xtensa" + ]; + needsUbootTools = lib.elem stdenv.hostPlatform.linuxArch linuxPlatformsUsingUImage; - getValue = attr: if config.isSet attr then getAttr (attrName attr) config else null; + config = + let + attrName = attr: "CONFIG_" + attr; + in + { + isSet = attr: hasAttr (attrName attr) config; - isYes = attr: (config.getValue attr) == "y"; + getValue = attr: if config.isSet attr then getAttr (attrName attr) config else null; - isNo = attr: (config.getValue attr) == "n"; + isYes = attr: (config.getValue attr) == "y"; - isModule = attr: (config.getValue attr) == "m"; + isNo = attr: (config.getValue attr) == "n"; - isEnabled = attr: (config.isModule attr) || (config.isYes attr); + isModule = attr: (config.getValue attr) == "m"; - isDisabled = attr: (!(config.isSet attr)) || (config.isNo attr); - } // config_; + isEnabled = attr: (config.isModule attr) || (config.isYes attr); - isModular = config.isYes "MODULES"; - withRust = config.isYes "RUST"; + isDisabled = attr: (!(config.isSet attr)) || (config.isNo attr); + } + // config_; - buildDTBs = kernelConf.DTB or false; + isModular = config.isYes "MODULES"; + withRust = config.isYes "RUST"; - # Dependencies that are required to build kernel modules - moduleBuildDependencies = [ - pahole - perl - elfutils - # module makefiles often run uname commands to find out the kernel version - (buildPackages.deterministic-uname.override { inherit modDirVersion; }) - ] - ++ optional (lib.versionAtLeast version "5.13") zstd - ++ optionals withRust [ rustc rust-bindgen ] - ; + buildDTBs = kernelConf.DTB or false; - in (optionalAttrs isModular { outputs = [ "out" "dev" ]; }) // { - passthru = rec { - inherit version modDirVersion config kernelPatches configfile - moduleBuildDependencies stdenv; - inherit isZen isHardened isLibre withRust; - isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true; - baseVersion = lib.head (lib.splitString "-rc" version); - kernelOlder = lib.versionOlder baseVersion; - kernelAtLeast = lib.versionAtLeast baseVersion; + # Dependencies that are required to build kernel modules + moduleBuildDependencies = + [ + pahole + perl + elfutils + # module makefiles often run uname commands to find out the kernel version + (buildPackages.deterministic-uname.override { inherit modDirVersion; }) + ] + ++ optional (lib.versionAtLeast version "5.13") zstd + ++ optionals withRust [ + rustc + rust-bindgen + ]; + + in + (optionalAttrs isModular { + outputs = [ + "out" + "dev" + ]; + }) + // { + passthru = rec { + inherit + version + modDirVersion + config + kernelPatches + configfile + moduleBuildDependencies + stdenv + ; + inherit + isZen + isHardened + isLibre + withRust + ; + isXen = lib.warn "The isXen attribute is deprecated. All Nixpkgs kernels that support it now have Xen enabled." true; + baseVersion = lib.head (lib.splitString "-rc" version); + kernelOlder = lib.versionOlder baseVersion; + kernelAtLeast = lib.versionAtLeast baseVersion; + }; + + inherit src; + + depsBuildBuild = [ buildPackages.stdenv.cc ]; + nativeBuildInputs = + [ + bison + flex + perl + bc + nettools + openssl + rsync + gmp + libmpc + mpfr + elfutils + zstd + python3Minimal + kmod + hexdump + ] + ++ optional needsUbootTools ubootTools + ++ optionals (lib.versionAtLeast version "5.2") [ + cpio + pahole + zlib + ] + ++ optionals withRust [ + rustc + rust-bindgen + ]; + + RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc; + + # avoid leaking Rust source file names into the final binary, which adds + # a false dependency on rust-lib-src on targets with uncompressed kernels + KRUSTFLAGS = lib.optionalString withRust "--remap-path-prefix ${rustPlatform.rustLibSrc}=/"; + + # patches = + # map (p: p.patch) kernelPatches + # # Required for deterministic builds along with some postPatch magic. + # ++ optional (lib.versionOlder version "5.19") ./randstruct-provide-seed.patch + # ++ optional (lib.versionAtLeast version "5.19") ./randstruct-provide-seed-5.19.patch + # # Linux 5.12 marked certain PowerPC-only symbols as GPL, which breaks + # # OpenZFS; this was fixed in Linux 5.19 so we backport the fix + # # https://github.com/openzfs/zfs/pull/13367 + # ++ optional (lib.versionAtLeast version "5.12" && + # lib.versionOlder version "5.19" && + # stdenv.hostPlatform.isPower) + # (fetchpatch { + # url = "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/patch/?id=d9e5c3e9e75162f845880535957b7fd0b4637d23"; + # hash = "sha256-bBOyJcP6jUvozFJU0SPTOf3cmnTQ6ZZ4PlHjiniHXLU="; + # }); + + postPatch = '' + # Ensure that depmod gets resolved through PATH + sed -i Makefile -e 's|= /sbin/depmod|= depmod|' + + # Some linux-hardened patches now remove certain files in the scripts directory, so the file may not exist. + [[ -f scripts/ld-version.sh ]] && patchShebangs scripts/ld-version.sh + + # Set randstruct seed to a deterministic but diversified value. Note: + # we could have instead patched gen-random-seed.sh to take input from + # the buildFlags, but that would require also patching the kernel's + # toplevel Makefile to add a variable export. This would be likely to + # cause future patch conflicts. + # for file in scripts/gen-randstruct-seed.sh scripts/gcc-plugins/gen-random-seed.sh; do + # if [ -f "$file" ]; then + # substituteInPlace "$file" \ + # --replace NIXOS_RANDSTRUCT_SEED \ + # $(echo ${randstructSeed}${src} ${placeholder "configfile"} | sha256sum | cut -d ' ' -f 1 | tr -d '\n') + # break + # fi + # done + + patchShebangs scripts + + # also patch arch-specific install scripts + for i in $(find arch -name install.sh); do + patchShebangs "$i" + done + + # unset $src because the build system tries to use it and spams a bunch of warnings + # see: https://github.com/torvalds/linux/commit/b1992c3772e69a6fd0e3fc81cd4d2820c8b6eca0 + unset src + ''; + + configurePhase = '' + runHook preConfigure + + mkdir build + export buildRoot="$(pwd)/build" + + echo "manual-config configurePhase buildRoot=$buildRoot pwd=$PWD" + + if [ -f "$buildRoot/.config" ]; then + echo "Could not link $buildRoot/.config : file exists" + exit 1 + fi + ln -sv ${configfile} $buildRoot/.config + + # reads the existing .config file and prompts the user for options in + # the current kernel source that are not found in the file. + make $makeFlags "''${makeFlagsArray[@]}" oldconfig + runHook postConfigure + + make $makeFlags "''${makeFlagsArray[@]}" prepare + actualModDirVersion="$(cat $buildRoot/include/config/kernel.release)" + if [ "$actualModDirVersion" != "${modDirVersion}" ]; then + echo "Error: modDirVersion ${modDirVersion} specified in the Nix expression is wrong, it should be: $actualModDirVersion" + exit 1 + fi + + buildFlagsArray+=("KBUILD_BUILD_TIMESTAMP=$(date -u -d @$SOURCE_DATE_EPOCH)") + + cd $buildRoot + ''; + + buildFlags = + [ + "KBUILD_BUILD_VERSION=1-PatOS" + kernelConf.target + "vmlinux" # for "perf" and things like that + ] + ++ optional isModular "modules" + ++ optionals buildDTBs [ + "dtbs" + "DTC_FLAGS=-@" + ] + ++ extraMakeFlags; + + installFlags = + [ + "INSTALL_PATH=$(out)" + ] + ++ (optional isModular "INSTALL_MOD_PATH=$(out)") + ++ optionals buildDTBs [ + "dtbs_install" + "INSTALL_DTBS_PATH=$(out)/dtbs" + ]; + + dontStrip = true; + + preInstall = + let + # All we really need to do here is copy the final image and System.map to $out, + # and use the kernel's modules_install, firmware_install, dtbs_install, etc. targets + # for the rest. Easy, right? + # + # Unfortunately for us, the obvious way of getting the built image path, + # make -s image_name, does not work correctly, because some architectures + # (*cough* aarch64 *cough*) change KBUILD_IMAGE on the fly in their install targets, + # so we end up attempting to install the thing we didn't actually build. + # + # Thankfully, there's a way out that doesn't involve just hardcoding everything. + # + # The kernel has an install target, which runs a pretty simple shell script + # (located at scripts/install.sh or arch/$arch/boot/install.sh, depending on + # which kernel version you're looking at) that tries to do something sensible. + # + # (it would be great to hijack this script immediately, as it has all the + # information we need passed to it and we don't need it to try and be smart, + # but unfortunately, the exact location of the scripts differs between kernel + # versions, and they're seemingly not considered to be public API at all) + # + # One of the ways it tries to discover what "something sensible" actually is + # is by delegating to what's supposed to be a user-provided install script + # located at ~/bin/installkernel. + # + # (the other options are: + # - a distribution-specific script at /sbin/installkernel, + # which we can't really create in the sandbox easily + # - an architecture-specific script at arch/$arch/boot/install.sh, + # which attempts to guess _something_ and usually guesses very wrong) + # + # More specifically, the install script exec's into ~/bin/installkernel, if one + # exists, with the following arguments: + # + # $1: $KERNELRELEASE - full kernel version string + # $2: $KBUILD_IMAGE - the final image path + # $3: System.map - path to System.map file, seemingly hardcoded everywhere + # $4: $INSTALL_PATH - path to the destination directory as specified in installFlags + # + # $2 is exactly what we want, so hijack the script and use the knowledge given to it + # by the makefile overlords for our own nefarious ends. + # + # Note that the makefiles specifically look in ~/bin/installkernel, and + # writeShellScriptBin writes the script to <store path>/bin/installkernel, + # so HOME needs to be set to just the store path. + # + # FIXME: figure out a less roundabout way of doing this. + installkernel = buildPackages.writeShellScriptBin "installkernel" '' + cp -av $2 $4 + cp -av $3 $4 + ''; + in + '' + installFlagsArray+=("-j$NIX_BUILD_CORES") + export HOME=${installkernel} + ''; + + # Some image types need special install targets (e.g. uImage is installed with make uinstall on arm) + installTargets = [ + (kernelConf.installTarget or ( + if kernelConf.target == "uImage" && stdenv.hostPlatform.linuxArch == "arm" then + "uinstall" + else if + kernelConf.target == "zImage" + || kernelConf.target == "Image.gz" + || kernelConf.target == "vmlinuz.efi" + then + "zinstall" + else + "install" + ) + ) + ]; + + # We remove a bunch of stuff that is symlinked from other places to save space, + # which trips the broken symlink check. So, just skip it. We'll know if it explodes. + dontCheckForBrokenSymlinks = true; + + postInstall = optionalString isModular '' + mkdir -p $dev + cp vmlinux $dev/ + # if [ -z "''${dontStrip-}" ]; then + # installFlagsArray+=("INSTALL_MOD_STRIP=1") + # fi + make modules_install $makeFlags "''${makeFlagsArray[@]}" \ + $installFlags "''${installFlagsArray[@]}" + unlink $out/lib/modules/${modDirVersion}/build + rm -f $out/lib/modules/${modDirVersion}/source + + mkdir -p $dev/lib/modules/${modDirVersion}/{build,source} + + # To save space, exclude a bunch of unneeded stuff when copying. + (cd .. && rsync --archive --prune-empty-dirs \ + --exclude='/build/' \ + * $dev/lib/modules/${modDirVersion}/source/) + + cd $dev/lib/modules/${modDirVersion}/source + + cp $buildRoot/{.config,Module.symvers} $dev/lib/modules/${modDirVersion}/build + make modules_prepare $makeFlags "''${makeFlagsArray[@]}" O=$dev/lib/modules/${modDirVersion}/build + + # For reproducibility, removes accidental leftovers from a `cc1` call + # from a `try-run` call from the Makefile + rm -f $dev/lib/modules/${modDirVersion}/build/.[0-9]*.d + + # Keep some extra files on some arches (powerpc, aarch64) + for f in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o; do + if [ -f "$buildRoot/$f" ]; then + cp $buildRoot/$f $dev/lib/modules/${modDirVersion}/build/$f + fi + done + + # !!! No documentation on how much of the source tree must be kept + # If/when kernel builds fail due to missing files, you can add + # them here. Note that we may see packages requiring headers + # from drivers/ in the future; it adds 50M to keep all of its + # headers on 3.10 though. + + chmod u+w -R .. + arch=$(cd $dev/lib/modules/${modDirVersion}/build/arch; ls) + + # Remove unused arches + for d in $(cd arch/; ls); do + if [ "$d" = "$arch" ]; then continue; fi + if [ "$arch" = arm64 ] && [ "$d" = arm ]; then continue; fi + rm -rf arch/$d + done + + # Remove all driver-specific code (50M of which is headers) + rm -fR drivers + + # Keep all headers + find . -type f -name '*.h' -print0 | xargs -0 -r chmod u-w + + # Keep linker scripts (they are required for out-of-tree modules on aarch64) + find . -type f -name '*.lds' -print0 | xargs -0 -r chmod u-w + + # Keep root and arch-specific Makefiles + chmod u-w Makefile arch/"$arch"/Makefile* + + # Keep whole scripts dir + chmod u-w -R scripts + + # Delete everything not kept + find . -type f -perm -u=w -print0 | xargs -0 -r rm + + # Delete empty directories + find -empty -type d -delete + ''; + + requiredSystemFeatures = [ "big-parallel" ]; + + meta = { + # https://github.com/NixOS/nixpkgs/pull/345534#issuecomment-2391238381 + broken = withRust && lib.versionOlder version "6.12"; + + description = + "The Linux kernel" + + ( + if kernelPatches == [ ] then + "" + else + " (with patches: " + lib.concatStringsSep ", " (map (x: x.name) kernelPatches) + ")" + ); + license = lib.licenses.gpl2Only; + homepage = "https://www.kernel.org/"; + maintainers = lib.teams.linux-kernel.members ++ [ + maintainers.thoughtpolice + ]; + platforms = platforms.linux; + badPlatforms = + lib.optionals (lib.versionOlder version "4.15") [ + "riscv32-linux" + "riscv64-linux" + ] + ++ lib.optional (lib.versionOlder version "5.19") "loongarch64-linux"; + timeout = 14400; # 4 hours + } // extraMeta; }; - inherit src; - - depsBuildBuild = [ buildPackages.stdenv.cc ]; - nativeBuildInputs = [ - bison - flex - perl - bc - nettools - openssl - rsync - gmp - libmpc - mpfr - elfutils - zstd - python3Minimal - kmod - hexdump - ] ++ optional needsUbootTools ubootTools - ++ optionals (lib.versionAtLeast version "5.2") [ cpio pahole zlib ] - ++ optionals withRust [ rustc rust-bindgen ]; - - RUST_LIB_SRC = lib.optionalString withRust rustPlatform.rustLibSrc; - - # avoid leaking Rust source file names into the final binary, which adds - # a false dependency on rust-lib-src on targets with uncompressed kernels - KRUSTFLAGS = lib.optionalString withRust "--remap-path-prefix ${rustPlatform.rustLibSrc}=/"; - - # patches = - # map (p: p.patch) kernelPatches - # # Required for deterministic builds along with some postPatch magic. - # ++ optional (lib.versionOlder version "5.19") ./randstruct-provide-seed.patch - # ++ optional (lib.versionAtLeast version "5.19") ./randstruct-provide-seed-5.19.patch - # # Linux 5.12 marked certain PowerPC-only symbols as GPL, which breaks - # # OpenZFS; this was fixed in Linux 5.19 so we backport the fix - # # https://github.com/openzfs/zfs/pull/13367 - # ++ optional (lib.versionAtLeast version "5.12" && - # lib.versionOlder version "5.19" && - # stdenv.hostPlatform.isPower) - # (fetchpatch { - # url = "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/patch/?id=d9e5c3e9e75162f845880535957b7fd0b4637d23"; - # hash = "sha256-bBOyJcP6jUvozFJU0SPTOf3cmnTQ6ZZ4PlHjiniHXLU="; - # }); - - postPatch = '' - # Ensure that depmod gets resolved through PATH - sed -i Makefile -e 's|= /sbin/depmod|= depmod|' - - # Some linux-hardened patches now remove certain files in the scripts directory, so the file may not exist. - [[ -f scripts/ld-version.sh ]] && patchShebangs scripts/ld-version.sh - - # Set randstruct seed to a deterministic but diversified value. Note: - # we could have instead patched gen-random-seed.sh to take input from - # the buildFlags, but that would require also patching the kernel's - # toplevel Makefile to add a variable export. This would be likely to - # cause future patch conflicts. - for file in scripts/gen-randstruct-seed.sh scripts/gcc-plugins/gen-random-seed.sh; do - if [ -f "$file" ]; then - substituteInPlace "$file" \ - --replace NIXOS_RANDSTRUCT_SEED \ - $(echo ${randstructSeed}${src} ${placeholder "configfile"} | sha256sum | cut -d ' ' -f 1 | tr -d '\n') - break - fi - done - - patchShebangs scripts - - # also patch arch-specific install scripts - for i in $(find arch -name install.sh); do - patchShebangs "$i" - done - - # unset $src because the build system tries to use it and spams a bunch of warnings - # see: https://github.com/torvalds/linux/commit/b1992c3772e69a6fd0e3fc81cd4d2820c8b6eca0 - unset src - ''; - - configurePhase = '' - runHook preConfigure - - mkdir build - export buildRoot="$(pwd)/build" - - echo "manual-config configurePhase buildRoot=$buildRoot pwd=$PWD" - - if [ -f "$buildRoot/.config" ]; then - echo "Could not link $buildRoot/.config : file exists" - exit 1 - fi - ln -sv ${configfile} $buildRoot/.config - - # reads the existing .config file and prompts the user for options in - # the current kernel source that are not found in the file. - make $makeFlags "''${makeFlagsArray[@]}" oldconfig - runHook postConfigure - - make $makeFlags "''${makeFlagsArray[@]}" prepare - actualModDirVersion="$(cat $buildRoot/include/config/kernel.release)" - if [ "$actualModDirVersion" != "${modDirVersion}" ]; then - echo "Error: modDirVersion ${modDirVersion} specified in the Nix expression is wrong, it should be: $actualModDirVersion" - exit 1 - fi - - buildFlagsArray+=("KBUILD_BUILD_TIMESTAMP=$(date -u -d @$SOURCE_DATE_EPOCH)") - - cd $buildRoot - ''; - - buildFlags = [ - "KBUILD_BUILD_VERSION=1-PatOS" - kernelConf.target - "vmlinux" # for "perf" and things like that - ] ++ optional isModular "modules" - ++ optionals buildDTBs ["dtbs" "DTC_FLAGS=-@"] + # Absolute paths for compilers avoid any PATH-clobbering issues. + commonMakeFlags = + [ + "ARCH=${stdenv.hostPlatform.linuxArch}" + "CROSS_COMPILE=${stdenv.cc.targetPrefix}" + ] + ++ lib.optionals (stdenv.isx86_64 && stdenv.cc.bintools.isLLVM) [ + # The wrapper for ld.lld breaks linking the kernel. We use the + # unwrapped linker as workaround. See: + # + # https://github.com/NixOS/nixpkgs/issues/321667 + "LD=${stdenv.cc.bintools.bintools}/bin/${stdenv.cc.targetPrefix}ld" + ] + ++ (stdenv.hostPlatform.linux-kernel.makeFlags or [ ]) ++ extraMakeFlags; + in - installFlags = [ - "INSTALL_PATH=$(out)" - ] ++ (optional isModular "INSTALL_MOD_PATH=$(out)") - ++ optionals buildDTBs ["dtbs_install" "INSTALL_DTBS_PATH=$(out)/dtbs"]; + stdenv.mkDerivation ( + builtins.foldl' lib.recursiveUpdate { } [ + (drvAttrs config stdenv.hostPlatform.linux-kernel kernelPatches configfile) + { + inherit pname version; - dontStrip = true; + enableParallelBuilding = true; - preInstall = let - # All we really need to do here is copy the final image and System.map to $out, - # and use the kernel's modules_install, firmware_install, dtbs_install, etc. targets - # for the rest. Easy, right? - # - # Unfortunately for us, the obvious way of getting the built image path, - # make -s image_name, does not work correctly, because some architectures - # (*cough* aarch64 *cough*) change KBUILD_IMAGE on the fly in their install targets, - # so we end up attempting to install the thing we didn't actually build. - # - # Thankfully, there's a way out that doesn't involve just hardcoding everything. - # - # The kernel has an install target, which runs a pretty simple shell script - # (located at scripts/install.sh or arch/$arch/boot/install.sh, depending on - # which kernel version you're looking at) that tries to do something sensible. - # - # (it would be great to hijack this script immediately, as it has all the - # information we need passed to it and we don't need it to try and be smart, - # but unfortunately, the exact location of the scripts differs between kernel - # versions, and they're seemingly not considered to be public API at all) - # - # One of the ways it tries to discover what "something sensible" actually is - # is by delegating to what's supposed to be a user-provided install script - # located at ~/bin/installkernel. - # - # (the other options are: - # - a distribution-specific script at /sbin/installkernel, - # which we can't really create in the sandbox easily - # - an architecture-specific script at arch/$arch/boot/install.sh, - # which attempts to guess _something_ and usually guesses very wrong) - # - # More specifically, the install script exec's into ~/bin/installkernel, if one - # exists, with the following arguments: - # - # $1: $KERNELRELEASE - full kernel version string - # $2: $KBUILD_IMAGE - the final image path - # $3: System.map - path to System.map file, seemingly hardcoded everywhere - # $4: $INSTALL_PATH - path to the destination directory as specified in installFlags - # - # $2 is exactly what we want, so hijack the script and use the knowledge given to it - # by the makefile overlords for our own nefarious ends. - # - # Note that the makefiles specifically look in ~/bin/installkernel, and - # writeShellScriptBin writes the script to <store path>/bin/installkernel, - # so HOME needs to be set to just the store path. - # - # FIXME: figure out a less roundabout way of doing this. - installkernel = buildPackages.writeShellScriptBin "installkernel" '' - cp -av $2 $4 - cp -av $3 $4 - ''; - in '' - installFlagsArray+=("-j$NIX_BUILD_CORES") - export HOME=${installkernel} - ''; - - # Some image types need special install targets (e.g. uImage is installed with make uinstall on arm) - installTargets = [ - (kernelConf.installTarget or ( - /**/ if kernelConf.target == "uImage" && stdenv.hostPlatform.linuxArch == "arm" then "uinstall" - else if kernelConf.target == "zImage" || kernelConf.target == "Image.gz" || kernelConf.target == "vmlinuz.efi" then "zinstall" - else "install")) - ]; - - # We remove a bunch of stuff that is symlinked from other places to save space, - # which trips the broken symlink check. So, just skip it. We'll know if it explodes. - dontCheckForBrokenSymlinks = true; - - postInstall = optionalString isModular '' - mkdir -p $dev - cp vmlinux $dev/ - if [ -z "''${dontStrip-}" ]; then - installFlagsArray+=("INSTALL_MOD_STRIP=1") - fi - make modules_install $makeFlags "''${makeFlagsArray[@]}" \ - $installFlags "''${installFlagsArray[@]}" - unlink $out/lib/modules/${modDirVersion}/build - rm -f $out/lib/modules/${modDirVersion}/source - - mkdir -p $dev/lib/modules/${modDirVersion}/{build,source} - - # To save space, exclude a bunch of unneeded stuff when copying. - (cd .. && rsync --archive --prune-empty-dirs \ - --exclude='/build/' \ - * $dev/lib/modules/${modDirVersion}/source/) - - cd $dev/lib/modules/${modDirVersion}/source - - cp $buildRoot/{.config,Module.symvers} $dev/lib/modules/${modDirVersion}/build - make modules_prepare $makeFlags "''${makeFlagsArray[@]}" O=$dev/lib/modules/${modDirVersion}/build - - # For reproducibility, removes accidental leftovers from a `cc1` call - # from a `try-run` call from the Makefile - rm -f $dev/lib/modules/${modDirVersion}/build/.[0-9]*.d - - # Keep some extra files on some arches (powerpc, aarch64) - for f in arch/powerpc/lib/crtsavres.o arch/arm64/kernel/ftrace-mod.o; do - if [ -f "$buildRoot/$f" ]; then - cp $buildRoot/$f $dev/lib/modules/${modDirVersion}/build/$f - fi - done - - # !!! No documentation on how much of the source tree must be kept - # If/when kernel builds fail due to missing files, you can add - # them here. Note that we may see packages requiring headers - # from drivers/ in the future; it adds 50M to keep all of its - # headers on 3.10 though. - - chmod u+w -R .. - arch=$(cd $dev/lib/modules/${modDirVersion}/build/arch; ls) - - # Remove unused arches - for d in $(cd arch/; ls); do - if [ "$d" = "$arch" ]; then continue; fi - if [ "$arch" = arm64 ] && [ "$d" = arm ]; then continue; fi - rm -rf arch/$d - done - - # Remove all driver-specific code (50M of which is headers) - rm -fR drivers - - # Keep all headers - find . -type f -name '*.h' -print0 | xargs -0 -r chmod u-w - - # Keep linker scripts (they are required for out-of-tree modules on aarch64) - find . -type f -name '*.lds' -print0 | xargs -0 -r chmod u-w - - # Keep root and arch-specific Makefiles - chmod u-w Makefile arch/"$arch"/Makefile* - - # Keep whole scripts dir - chmod u-w -R scripts - - # Delete everything not kept - find . -type f -perm -u=w -print0 | xargs -0 -r rm - - # Delete empty directories - find -empty -type d -delete - ''; - - requiredSystemFeatures = [ "big-parallel" ]; - - meta = { - # https://github.com/NixOS/nixpkgs/pull/345534#issuecomment-2391238381 - broken = withRust && lib.versionOlder version "6.12"; - - description = - "The Linux kernel" + - (if kernelPatches == [] then "" else - " (with patches: " - + lib.concatStringsSep ", " (map (x: x.name) kernelPatches) - + ")"); - license = lib.licenses.gpl2Only; - homepage = "https://www.kernel.org/"; - maintainers = lib.teams.linux-kernel.members ++ [ - maintainers.thoughtpolice + hardeningDisable = [ + "bindnow" + "format" + "fortify" + "stackprotector" + "pic" + "pie" ]; - platforms = platforms.linux; - badPlatforms = - lib.optionals (lib.versionOlder version "4.15") [ "riscv32-linux" "riscv64-linux" ] ++ - lib.optional (lib.versionOlder version "5.19") "loongarch64-linux"; - timeout = 14400; # 4 hours - } // extraMeta; - }; - # Absolute paths for compilers avoid any PATH-clobbering issues. - commonMakeFlags = [ - "ARCH=${stdenv.hostPlatform.linuxArch}" - "CROSS_COMPILE=${stdenv.cc.targetPrefix}" - ] ++ lib.optionals (stdenv.isx86_64 && stdenv.cc.bintools.isLLVM) [ - # The wrapper for ld.lld breaks linking the kernel. We use the - # unwrapped linker as workaround. See: - # - # https://github.com/NixOS/nixpkgs/issues/321667 - "LD=${stdenv.cc.bintools.bintools}/bin/${stdenv.cc.targetPrefix}ld" - ] ++ (stdenv.hostPlatform.linux-kernel.makeFlags or []) - ++ extraMakeFlags; -in + makeFlags = [ + "O=$(buildRoot)" + ] ++ commonMakeFlags; -stdenv.mkDerivation ( - builtins.foldl' lib.recursiveUpdate {} [ - (drvAttrs config stdenv.hostPlatform.linux-kernel kernelPatches configfile) - { - inherit pname version; + passthru = { inherit commonMakeFlags; }; - enableParallelBuilding = true; - - hardeningDisable = [ "bindnow" "format" "fortify" "stackprotector" "pic" "pie" ]; - - makeFlags = [ - "O=$(buildRoot)" - ] ++ commonMakeFlags; - - passthru = { inherit commonMakeFlags; }; - - karch = stdenv.hostPlatform.linuxArch; - } - (optionalAttrs (pos != null) { inherit pos; }) - ] -)) + karch = stdenv.hostPlatform.linuxArch; + } + (optionalAttrs (pos != null) { inherit pos; }) + ] + ) +) diff --git a/pkgs/rootfs/default.nix b/pkgs/rootfs/default.nix deleted file mode 100644 index d3c39c3..0000000 --- a/pkgs/rootfs/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ - pkgs, - stdenvNoCC, - patosPkgs, - version, - ... -}: -let - pname = "patos-rootfs"; - defaultPassword = "patos"; -in -stdenvNoCC.mkDerivation (finalAttrs: { - inherit version; - inherit pname; - inherit defaultPassword; - - buildInputs = with pkgs; [ - glibc - binutils - ]; - - glibcPatos = patosPkgs.glibc.out; - systemd = patosPkgs.systemd.out; - dbusBroker = patosPkgs.dbus-broker.out; - kernel = patosPkgs.kernel; - busybox = patosPkgs.busybox.out; - kmodLibs = pkgs.kmod.lib; - kmodBin = pkgs.kmod.out; - cacert = pkgs.cacert.out; - libbpf = pkgs.libbpf.out; - btrfs = pkgs.btrfs-progs.out; - tpm2Libs = patosPkgs.tpm2-tss.out; - kexec = patosPkgs.kexec.out; - lvm2 = patosPkgs.lvm2.out; - openssl = patosPkgs.openssl.out; - - builder = ./mkrootfs.sh; -}) diff --git a/pkgs/rootfs/mkinitrd.nix b/pkgs/rootfs/mkinitrd.nix index 3708483..8eb721e 100644 --- a/pkgs/rootfs/mkinitrd.nix +++ b/pkgs/rootfs/mkinitrd.nix @@ -1,23 +1,66 @@ { pkgs, - stdenvNoCC, patosPkgs, - version, + runCommand, ... }: -let - pname = "patos-ramdisk"; -in -stdenvNoCC.mkDerivation (finalAttrs: { - inherit version; - inherit pname; - +runCommand "patos-initrd" { buildInputs = with pkgs; [ cpio xz ]; +} +'' +echo "Building initram disk" +mkdir -p $out/root +pushd $out/root - rootfs = patosPkgs.rootfs.out; +### copy rootfs +cp -prP ${patosPkgs.rootfs}/* . +find . -type d -exec chmod 755 {} \; +mkdir sysroot - builder = ./mkinitrd.sh; -}) +### create directories +ln -sf ../usr/lib/systemd/systemd init + +### Create needed files +echo patos > ./etc/hostname + +ln -sf /etc/os-release ./etc/initrd-release + +# set default target to initrd inside initrd +ln -sf initrd.target ./usr/lib/systemd/system/default.target + +# bind mount /run to /sysroot/run +cat <<EOF > ./usr/lib/systemd/system/sysroot-run.mount +[Unit] +Before=initrd-fs.target +DefaultDependencies=false + +[Mount] +Options=bind +What=/run +Where=/sysroot/run +EOF +mkdir ./usr/lib/systemd/system/initrd-fs.target.requires/ +ln -sf ../sysroot-run.mount ./usr/lib/systemd/system/initrd-fs.target.requires/sysroot-run.mount + +# repart: generate crypttab and fstab under /run +mkdir ./usr/lib/systemd/system/systemd-repart.service.d +cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf +[Unit] +After=sysroot-run.mount +Requires=sysroot-run.mount + +[Service] +Environment=SYSTEMD_REPART_MKFS_OPTIONS_BTRFS=--nodiscard +ExecStart= +ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab +EOF + +# gen initrd +find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz + +popd +rm -rf $out/root +'' diff --git a/pkgs/rootfs/mkinitrd.sh b/pkgs/rootfs/mkinitrd.sh deleted file mode 100644 index 43708d0..0000000 --- a/pkgs/rootfs/mkinitrd.sh +++ /dev/null @@ -1,53 +0,0 @@ -set -ex -p pipefail -echo "Building initram disk" -mkdir -p $out/root -pushd $out/root - -### copy rootfs -cp -prP $rootfs/* . -find . -type d -exec chmod 755 {} \; -mkdir sysroot - -### create directories -ln -sf ../usr/lib/systemd/systemd init - -### Create needed files -echo patos > ./etc/hostname - -ln -sf /etc/os-release ./etc/initrd-release - -# set default target to initrd inside initrd -ln -sf initrd.target ./usr/lib/systemd/system/default.target - -# bind mount /run to /sysroot/run -cat <<EOF > ./usr/lib/systemd/system/sysroot-run.mount -[Unit] -Before=initrd-fs.target -DefaultDependencies=false - -[Mount] -Options=bind -What=/run -Where=/sysroot/run -EOF -mkdir ./usr/lib/systemd/system/initrd-fs.target.requires/ -ln -sf ../sysroot-run.mount ./usr/lib/systemd/system/initrd-fs.target.requires/sysroot-run.mount - -# repart: generate crypttab and fstab under /run -mkdir ./usr/lib/systemd/system/systemd-repart.service.d -cat <<EOF > ./usr/lib/systemd/system/systemd-repart.service.d/override.conf -[Unit] -After=sysroot-run.mount -Requires=sysroot-run.mount - -[Service] -Environment=SYSTEMD_REPART_MKFS_OPTIONS_BTRFS=--nodiscard -ExecStart= -ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab -EOF - -# gen initrd -find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz - -popd -rm -rf $out/root diff --git a/pkgs/rootfs/mkrootfs.sh b/pkgs/rootfs/mkrootfs.nix similarity index 75% rename from pkgs/rootfs/mkrootfs.sh rename to pkgs/rootfs/mkrootfs.nix index 3ccc93c..fb25c4d 100644 --- a/pkgs/rootfs/mkrootfs.sh +++ b/pkgs/rootfs/mkrootfs.nix @@ -1,5 +1,22 @@ -set -ex -o pipefail +{ + pkgs, + patosPkgs, + version, + runCommand, + ... +}: +let + defaultPassword = "patos"; +in +runCommand "patos-rootfs" +{ + buildInputs = [ + pkgs.glibc + pkgs.binutils + ]; +} +'' ### create directory structure mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys \ $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var/tmp @@ -11,7 +28,7 @@ ln -sf ../proc/self/mounts $out/etc/mtab ### install systemd echo "Installing systemd" -cp -Pr $systemd/* $out/ +cp -Pr ${patosPkgs.systemd}/* $out/ find $out -type d -exec chmod 755 {} \; rm -rf $out/usr/include rm -rf $out/usr/sbin @@ -117,57 +134,57 @@ ManagerEnvironment=PATH=/bin:/sbin:/usr/bin SYSTEMD_CRYPTTAB=/run/crypttab SYSTE EOF ### install PatOS glibc -cp -P $glibcPatos/lib/*.so* $out/usr/lib/ +cp -P ${patosPkgs.glibc}/lib/*.so* $out/usr/lib/ ### install openssl -cp -P $openssl/lib/*.so* $out/usr/lib/ -cp -Pr $openssl/etc/ssl $out/etc/ +cp -P ${patosPkgs.openssl}/lib/*.so* $out/usr/lib/ +cp -Pr ${patosPkgs.openssl}/etc/ssl $out/etc/ ### install busybox -cp $busybox/bin/busybox $out/usr/bin/ +cp ${patosPkgs.busybox}/bin/busybox $out/usr/bin/ $out/usr/bin/busybox --list | xargs -I {} ln -sf busybox $out/usr/bin/{} ### install dbus broker -cp -r $dbusBroker/* $out/ +cp -r ${patosPkgs.dbus-broker}/* $out/ ### install kexec -cp -Pr ${kexec}/sbin/kexec $out/usr/bin/ +cp -Pr ${patosPkgs.kexec}/sbin/kexec $out/usr/bin/ ### install dmsetup udev rules -cp -P ${lvm2}/usr/bin/dmsetup $out/usr/bin/ -cp -P ${lvm2}/lib/libdevmapper.so* $out/usr/lib/ -cp -P ${lvm2}/lib/udev/rules.d/* $out/usr/lib/udev/rules.d/ +cp -P ${patosPkgs.lvm2}/usr/bin/dmsetup $out/usr/bin/ +cp -P ${patosPkgs.lvm2}/lib/libdevmapper.so* $out/usr/lib/ +cp -P ${patosPkgs.lvm2}/lib/udev/rules.d/* $out/usr/lib/udev/rules.d/ ### install btrfs progs -cp -Pr ${btrfs}/bin/* $out/usr/bin/ -cp -Pr ${btrfs}/lib/* $out/usr/lib/ +cp -Pr ${pkgs.btrfs-progs}/bin/* $out/usr/bin/ +cp -Pr ${pkgs.btrfs-progs}/lib/* $out/usr/lib/ ### install tpm2 libs -cp -P ${tpm2Libs}/lib/*.so* $out/usr/lib/ +cp -P ${patosPkgs.tpm2-tss}/lib/*.so* $out/usr/lib/ ### install lib kmod -cp -P $kmodLibs/lib/*.so* $out/usr/lib/ -cp -P $kmodBin/bin/* $out/usr/bin +cp -P ${pkgs.kmod.lib}/lib/*.so* $out/usr/lib/ +cp -P ${pkgs.kmod}/bin/* $out/usr/bin ### install libbpf -cp -P $libbpf/lib/libbpf*.so* $out/usr/lib +cp -P ${pkgs.libbpf}/lib/libbpf*.so* $out/usr/lib ### install ca cert bundle chmod 755 $out/etc/ssl $out/etc/ssl/certs -cp -P $cacert/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/cert.pem +cp -P ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/cert.pem ln -sf ../cert.pem $out/etc/ssl/certs/ca-certificates.crt ln -sf ../cert.pem $out/etc/ssl/certs/ca-bundle.crt # setup default files -$systemd/usr/bin/systemd-hwdb --root=$out --usr update -$systemd/usr/bin/systemd-tmpfiles --root=$out $out/usr/lib/tmpfiles.d/etc.conf --create +${patosPkgs.systemd}/usr/bin/systemd-hwdb --root=$out --usr update +${patosPkgs.systemd}/usr/bin/systemd-tmpfiles --root=$out $out/usr/lib/tmpfiles.d/etc.conf --create cp $out/usr/share/factory/etc/nsswitch.conf $out/etc/ cp $out/usr/share/factory/etc/locale.conf $out/etc/ cp $out/usr/share/factory/etc/vconsole.conf $out/etc/ # install sys users mkdir creds -echo -n $defaultPassword > creds/passwd.plaintext-password.root -CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' $systemd/usr/bin/systemd-sysusers --root=$out rootfs/usr/lib/sysusers.d/*.conf +echo -n ${defaultPassword} > creds/passwd.plaintext-password.root +CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' ${patosPkgs.systemd}/usr/bin/systemd-sysusers --root=$out rootfs/usr/lib/sysusers.d/*.conf chmod 600 $out/etc/shadow rm -rf creds @@ -195,6 +212,6 @@ find $out -type f -executable -exec strip {} \; find $out -type d -exec chmod 755 {} \; ### install kernel modules -cp -r $kernel/lib/modules $out/usr/lib/ +cp -r ${patosPkgs.kernel}/lib/modules $out/usr/lib/ find $out/usr/lib/modules -type d -exec chmod 755 {} \; - +'' From df3a42da4be1a24bf96fee185483e3b49b75bb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 17 Mar 2025 17:03:52 +0100 Subject: [PATCH 50/67] chore: more clean up --- pkgs/image/default.nix | 4 +--- pkgs/rootfs/mkrootfs.nix | 13 +++++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 7d5f565..e82b49a 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -15,9 +15,7 @@ runCommand pname { erofs-utils dosfstools mtools - e2fsprogs jq - openssl ]; env = { @@ -159,7 +157,7 @@ ${patosPkgs.systemd}/usr/bin/systemd-repart \ --size=auto \ --definitions=./final.repart.d \ --root=$out \ - patos-$version.raw > final-repart-output.json + patos-${version}.raw > final-repart-output.json rm -rf rootfs diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index fb25c4d..a40e17b 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -11,6 +11,8 @@ in runCommand "patos-rootfs" { + inherit version; + buildInputs = [ pkgs.glibc pkgs.binutils @@ -175,6 +177,9 @@ cp -P ${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt $out/etc/ssl/cert.pem ln -sf ../cert.pem $out/etc/ssl/certs/ca-certificates.crt ln -sf ../cert.pem $out/etc/ssl/certs/ca-bundle.crt +# no need for pkgconfig, removing.. +rm -rf $out/usr/lib/pkgconfig + # setup default files ${patosPkgs.systemd}/usr/bin/systemd-hwdb --root=$out --usr update ${patosPkgs.systemd}/usr/bin/systemd-tmpfiles --root=$out $out/usr/lib/tmpfiles.d/etc.conf --create @@ -188,13 +193,9 @@ CREDENTIALS_DIRECTORY=$PWD/creds SYSTEMD_CRYPT_PREFIX='$6$' ${patosPkgs.systemd} chmod 600 $out/etc/shadow rm -rf creds - # Ephemeral machine-id until registration ln -sf /run/machine-id $out/etc/machine-id -# remove pkgconfig -rm -rf $out/usr/lib/pkgconfig - ### Find and install all shared libs find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ grep -vE "(systemd|glibc|openssl|tpm2|devmapper)" | \ @@ -202,7 +203,7 @@ find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \ find $out -type f -executable -exec chmod 755 {} \; -# FIXME: ELF patching. Is there a better way? +# patch ELFs find $out -type f -executable -exec patchelf --set-rpath /lib:/usr/lib:/usr/lib/systemd:/usr/lib/cryptsetup {} \; find $out -type f -executable -exec patchelf --set-interpreter /lib/ld-linux-x86-64.so.2 {} \; patchelf --remove-rpath $out/usr/lib/ld-linux-x86-64.so.2 @@ -211,7 +212,7 @@ patchelf --remove-rpath $out/usr/lib/ld-linux-x86-64.so.2 find $out -type f -executable -exec strip {} \; find $out -type d -exec chmod 755 {} \; -### install kernel modules +# install kernel modules cp -r ${patosPkgs.kernel}/lib/modules $out/usr/lib/ find $out/usr/lib/modules -type d -exec chmod 755 {} \; '' From dc8ed2a7741810ab6806fb078eded015ef147e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 17 Mar 2025 22:22:35 +0100 Subject: [PATCH 51/67] feat: enable factory reset --- pkgs/image/default.nix | 27 +++++++++++++++++++++++---- pkgs/rootfs/mkinitrd.nix | 1 + pkgs/rootfs/mkrootfs.nix | 17 ++++++++++------- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index e82b49a..e82bc3d 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -27,7 +27,7 @@ runCommand pname { kernelCmdLine = "console=ttyS0"; } '' -mkdir -p $out/init.repart.d $out/final.repart.d $out/boot +mkdir -p $out/init.repart.d $out/final.repart.d pushd $out # Don't seem to work just to create a symlink to rootfs derivation? @@ -106,9 +106,28 @@ SYSTEMD_RELAX_ESP_CHECKS=1 ${patosPkgs.systemd}/usr/bin/bootctl install --root . --secure-boot-auto-enroll=true --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem echo "timeout 2" > rootfs/boot/loader/loader.conf +# setup factory reset +mkdir -p rootfs/boot/EFI/tools +cp ${pkgs.edk2-uefi-shell}/shell.efi rootfs/boot/EFI/tools/ + +cat <<EOF > rootfs/boot/EFI/tools/factoryreset.nsh +setvar FactoryReset -guid 8cf2644b-4b0b-428f-9387-6d876050dc67 -nv -rt =%1 +reset +EOF + +cat <<EOF > rootfs/boot/loader/entries/factoryreset.conf +title Enable Factory Reset +options -nostartup -nomap +options \EFI\tools\factoryreset.nsh L"t" +efi EFI/tools/shell.efi +EOF + # sign EFIs ${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ - rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI + rootfs/boot/EFI/tools/shell.efi --output=rootfs/boot/EFI/tools/shell.efi + +${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ + rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI ${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ patos_${version}.efi --output=patos_${version}.efi @@ -123,8 +142,8 @@ cat <<EOF > final.repart.d/10-esp.conf [Partition] Type=esp Format=vfat -SizeMinBytes=160M -SizeMaxBytes=160M +SizeMinBytes=96M +SizeMaxBytes=96M CopyFiles=/rootfs/boot:/ EOF diff --git a/pkgs/rootfs/mkinitrd.nix b/pkgs/rootfs/mkinitrd.nix index 8eb721e..2187514 100644 --- a/pkgs/rootfs/mkinitrd.nix +++ b/pkgs/rootfs/mkinitrd.nix @@ -57,6 +57,7 @@ Environment=SYSTEMD_REPART_MKFS_OPTIONS_BTRFS=--nodiscard ExecStart= ExecStart=systemd-repart --dry-run=no --generate-crypttab=/run/crypttab --generate-fstab=/run/fstab EOF +ln -sf ../systemd-repart.service ./usr/lib/systemd/system/initrd-root-fs.target.wants/systemd-repart.service # gen initrd find . -print0 | cpio --null --owner=root:root -o --format=newc | xz -9 --check=crc32 > ../initrd.xz diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index a40e17b..ca449b3 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -3,7 +3,6 @@ patosPkgs, version, runCommand, - ... }: let defaultPassword = "patos"; @@ -13,10 +12,11 @@ runCommand "patos-rootfs" { inherit version; - buildInputs = [ - pkgs.glibc - pkgs.binutils + buildInputs = with pkgs;[ + glibc + binutils ]; + } '' ### create directory structure @@ -29,13 +29,16 @@ ln -sf /usr/lib $out/lib64 ln -sf ../proc/self/mounts $out/etc/mtab ### install systemd -echo "Installing systemd" cp -Pr ${patosPkgs.systemd}/* $out/ find $out -type d -exec chmod 755 {} \; rm -rf $out/usr/include rm -rf $out/usr/sbin ln -sf /usr/bin $out/usr/sbin rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service +# enable in ramdisk instead +rm -f $out/usr/lib/systemd/system/sysinit.target.wants/systemd-repart.service +rm -f $out/usr/lib/systemd/system/initrd-root-fs.target.wants/systemd-repart.service + rm -f $out/usr/lib/systemd/ukify rm -f $out/usr/bin/ukify rm -f $out/usr/lib/udev/rules.d/90-vconsole.rules @@ -71,8 +74,8 @@ cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] Type=esp Format=vfat -SizeMaxBytes=160M -SizeMinBytes=160M +SizeMaxBytes=96M +SizeMinBytes=96M EOF cat <<EOF > $out/etc/repart.d/20-root-a.conf From 8fb3174c7868f39470a0070462344f7e64a5d6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 17 Mar 2025 22:22:35 +0100 Subject: [PATCH 52/67] feat: enroll secure boot at first boot --- pkgs/image/default.nix | 32 +++++++++++++++++------------- pkgs/rootfs/mkinitrd.nix | 43 ++++++++++++++++++++++++++++++++++++++++ pkgs/rootfs/mkrootfs.nix | 8 +++++++- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index e82bc3d..2084901 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -54,6 +54,22 @@ mv rootfs/usr/lib/systemd/network/89-ethernet.network.example rootfs/usr/lib/sys ln -sf ../systemd-confext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-confext.service ln -sf ../systemd-sysext.service rootfs/usr/lib/systemd/system/sysinit.target.wants/systemd-sysext.service +cat <<EOF > rootfs/usr/lib/systemd/system/secure-boot-import-keys.service +[Unit] +Description=Import Secure Boot keys +DefaultDependencies=no +RequiresMountsFor=/var/lib/sbctl /boot +ConditionPathExists=/boot/sbctl/keys +After=local-fs.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=sbctl import-keys -d /boot/sbctl/keys +ExecStartPost=rm -rf /boot/sbctl +EOF +ln -sf ../secure-boot-import-keys.service rootfs/usr/lib/systemd/system/sysinit.target.wants/secure-boot-import-keys.service + # Initial partitioning cat <<EOF > init.repart.d/10-root.conf [Partition] @@ -102,9 +118,7 @@ ${patosPkgs.systemd}/usr/bin/ukify build \ -o patos_${version}.efi # install ESP -SYSTEMD_RELAX_ESP_CHECKS=1 ${patosPkgs.systemd}/usr/bin/bootctl install --root ./rootfs --esp-path /boot \ - --secure-boot-auto-enroll=true --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem -echo "timeout 2" > rootfs/boot/loader/loader.conf +SYSTEMD_RELAX_ESP_CHECKS=1 ${patosPkgs.systemd}/usr/bin/bootctl install --root ./rootfs --esp-path /boot # setup factory reset mkdir -p rootfs/boot/EFI/tools @@ -122,21 +136,11 @@ options \EFI\tools\factoryreset.nsh L"t" efi EFI/tools/shell.efi EOF -# sign EFIs -${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ - rootfs/boot/EFI/tools/shell.efi --output=rootfs/boot/EFI/tools/shell.efi - -${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ - rootfs/boot/EFI/BOOT/BOOTX64.EFI --output=rootfs/boot/EFI/BOOT/BOOTX64.EFI - -${patosPkgs.systemd}/usr/lib/systemd/systemd-sbsign sign --certificate=${patosPkgs.cert}/cert.pem --private-key=${patosPkgs.cert}/key.pem \ - patos_${version}.efi --output=patos_${version}.efi +echo "timeout 2" > rootfs/boot/loader/loader.conf # install UKI cp patos_${version}.efi rootfs/boot/EFI/Linux -echo "secure-boot-enroll force" >> rootfs/boot/loader/loader.conf - # Final partitioning cat <<EOF > final.repart.d/10-esp.conf [Partition] diff --git a/pkgs/rootfs/mkinitrd.nix b/pkgs/rootfs/mkinitrd.nix index 2187514..5cc6411 100644 --- a/pkgs/rootfs/mkinitrd.nix +++ b/pkgs/rootfs/mkinitrd.nix @@ -31,6 +31,49 @@ ln -sf /etc/os-release ./etc/initrd-release # set default target to initrd inside initrd ln -sf initrd.target ./usr/lib/systemd/system/default.target +# setup secure boot +cat <<EOF > ./usr/bin/secure-boot-enroll +#!/bin/sh +set -ex -o pipefail + +SETUP_MODE=\$(sbctl status --json | xq -r '.setup_mode') + +[ "\$SETUP_MODE" = "false" ] && exit 0 + +cat <<EOL> /run/sbctl.yml +--- +keydir: /sysroot/boot/sbctl/keys +guid: /sysroot/boot/sbctl/GUID +EOL + +ESP=\$(blkid --label ESP) + +mount \$ESP /sysroot/boot && \ + sbctl --config /run/sbctl.yml create-keys && \ + sbctl --config /run/sbctl.yml enroll-keys --yolo && \ + # Sign EFIs + find /sysroot/boot -type f \( -iname "*.efi" -o -iname "*.EFI" \) -print0 | xargs -I {} sbctl --config /run/sbctl.yml sign {} + +umount /sysroot/boot && \ + systemctl reboot -f +EOF +chmod +x ./usr/bin/secure-boot-enroll + +cat <<EOF > ./usr/lib/systemd/system/secure-boot-enroll.service +[Unit] +Description=Enroll Secure Boot +DefaultDependencies=false +After=sysroot-run.mount +Requires=sysroot-run.mount +Before=systemd-repart.service initrd.target shutdown.target sysinit.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/secure-boot-enroll +RemainAfterExit=yes +EOF +ln -sf ../secure-boot-enroll.service ./usr/lib/systemd/system/initrd-root-fs.target.wants/secure-boot-enroll.service + # bind mount /run to /sysroot/run cat <<EOF > ./usr/lib/systemd/system/sysroot-run.mount [Unit] diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index ca449b3..f98a219 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -172,7 +172,13 @@ cp -P ${pkgs.kmod.lib}/lib/*.so* $out/usr/lib/ cp -P ${pkgs.kmod}/bin/* $out/usr/bin ### install libbpf -cp -P ${pkgs.libbpf}/lib/libbpf*.so* $out/usr/lib +cp -P ${pkgs.libbpf}/lib/libbpf*.so* $out/usr/lib/ + +### install secure boot tools +cp -P ${pkgs.sbctl}/bin/sbctl $out/usr/bin/ +rm -f $out/usr/bin/blkid +cp -P ${pkgs.util-linuxMinimal}/bin/blkid $out/usr/bin/ +cp -P ${pkgs.xq}/bin/xq $out/usr/bin/ ### install ca cert bundle chmod 755 $out/etc/ssl $out/etc/ssl/certs From a7b86fd03e26caf9429a12ac84dadaf9969aff5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Mon, 17 Mar 2025 22:22:35 +0100 Subject: [PATCH 53/67] feat: add sysupdate definitions --- flake.nix | 3 +- pkgs/image/default.nix | 66 +++++++++++++++++++++++++++++-- pkgs/rootfs/mkinitrd.nix | 31 +++------------ pkgs/rootfs/mkrootfs.nix | 9 ++++- pkgs/rootfs/secure-boot-enroll.sh | 37 +++++++++++++++++ 5 files changed, 114 insertions(+), 32 deletions(-) create mode 100644 pkgs/rootfs/secure-boot-enroll.sh diff --git a/flake.nix b/flake.nix index 2358ab1..7c17fff 100644 --- a/flake.nix +++ b/flake.nix @@ -18,11 +18,12 @@ pkgs = import nixpkgs { inherit system; }; patosPkgs = self.packages.${system}; version = "0.0.1"; + updateUrl = "http://10.0.2.2:8000"; in { packages = { default = patosPkgs.image; - image = pkgs.callPackage ./pkgs/image { inherit patosPkgs version; }; + image = pkgs.callPackage ./pkgs/image { inherit patosPkgs version updateUrl; }; rootfs = pkgs.callPackage ./pkgs/rootfs/mkrootfs.nix { inherit patosPkgs version; }; initrd = pkgs.callPackage ./pkgs/rootfs/mkinitrd.nix { inherit patosPkgs version; }; kernel = pkgs.callPackage ./pkgs/kernel { }; diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 2084901..8f3acbf 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -3,13 +3,14 @@ patosPkgs, version, runCommand, - ... + updateUrl }: let pname = "patos-image"; in runCommand pname { inherit version; + inherit updateUrl; buildInputs = with pkgs; [ erofs-utils @@ -24,7 +25,7 @@ runCommand pname { SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; # -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; }; - kernelCmdLine = "console=ttyS0"; + kernelCmdLine = "console=ttyS0 patos.secureboot=true"; } '' mkdir -p $out/init.repart.d $out/final.repart.d @@ -70,6 +71,63 @@ ExecStartPost=rm -rf /boot/sbctl EOF ln -sf ../secure-boot-import-keys.service rootfs/usr/lib/systemd/system/sysinit.target.wants/secure-boot-import-keys.service +# sysupdate +mkdir -p rootfs/etc/sysupdate.d +cat <<EOF > rootfs/etc/sysupdate.d/10-uki.transfer +[Source] +Path=${updateUrl} +MatchPattern=patos_@v.efi +Type=url-file + +[Target] +InstancesMax=2 +MatchPattern=patos_@v+@l-@d.efi patos_@v+@l.efi patos_@v.efi +Mode=0444 +Path=/EFI/Linux +PathRelativeTo=esp +TriesDone=0 +TriesLeft=3 +Type=regular-file + +[Transfer] +Verify=no +EOF + +cat <<EOF > rootfs/etc/sysupdate.d/20-root.transfer +[Source] +Type=url-file +Path=${updateUrl} +MatchPattern=patos_@v_@u.verity + +[Target] +Type=partition +Path=auto +MatchPattern=verity-@v +MatchPartitionType=root-verity +ReadOnly=1 + +[Transfer] +Verify=no +EOF + +cat <<EOF > rootfs/etc/sysupdate.d/22-root.transfer +[Source] +Type=url-file +Path=${updateUrl} +MatchPattern=patos_@v_@u.root + +[Target] +Type=partition +Path=auto +MatchPattern=root-@v +MatchPartitionType=root +ReadOnly=1 + +[Transfer] +Verify=no +EOF + + # Initial partitioning cat <<EOF > init.repart.d/10-root.conf [Partition] @@ -146,8 +204,8 @@ cat <<EOF > final.repart.d/10-esp.conf [Partition] Type=esp Format=vfat -SizeMinBytes=96M -SizeMaxBytes=96M +SizeMinBytes=128M +SizeMaxBytes=128M CopyFiles=/rootfs/boot:/ EOF diff --git a/pkgs/rootfs/mkinitrd.nix b/pkgs/rootfs/mkinitrd.nix index 5cc6411..10399a6 100644 --- a/pkgs/rootfs/mkinitrd.nix +++ b/pkgs/rootfs/mkinitrd.nix @@ -4,7 +4,12 @@ runCommand, ... }: +let + secureBootEnroll = ./secure-boot-enroll.sh; +in runCommand "patos-initrd" { + inherit secureBootEnroll; + buildInputs = with pkgs; [ cpio xz @@ -32,31 +37,7 @@ ln -sf /etc/os-release ./etc/initrd-release ln -sf initrd.target ./usr/lib/systemd/system/default.target # setup secure boot -cat <<EOF > ./usr/bin/secure-boot-enroll -#!/bin/sh -set -ex -o pipefail - -SETUP_MODE=\$(sbctl status --json | xq -r '.setup_mode') - -[ "\$SETUP_MODE" = "false" ] && exit 0 - -cat <<EOL> /run/sbctl.yml ---- -keydir: /sysroot/boot/sbctl/keys -guid: /sysroot/boot/sbctl/GUID -EOL - -ESP=\$(blkid --label ESP) - -mount \$ESP /sysroot/boot && \ - sbctl --config /run/sbctl.yml create-keys && \ - sbctl --config /run/sbctl.yml enroll-keys --yolo && \ - # Sign EFIs - find /sysroot/boot -type f \( -iname "*.efi" -o -iname "*.EFI" \) -print0 | xargs -I {} sbctl --config /run/sbctl.yml sign {} - -umount /sysroot/boot && \ - systemctl reboot -f -EOF +cat $secureBootEnroll > ./usr/bin/secure-boot-enroll chmod +x ./usr/bin/secure-boot-enroll cat <<EOF > ./usr/lib/systemd/system/secure-boot-enroll.service diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index f98a219..61e99d1 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -74,8 +74,8 @@ cat <<EOF > $out/etc/repart.d/10-esp.conf [Partition] Type=esp Format=vfat -SizeMaxBytes=96M -SizeMinBytes=96M +SizeMaxBytes=128M +SizeMinBytes=128M EOF cat <<EOF > $out/etc/repart.d/20-root-a.conf @@ -178,7 +178,12 @@ cp -P ${pkgs.libbpf}/lib/libbpf*.so* $out/usr/lib/ cp -P ${pkgs.sbctl}/bin/sbctl $out/usr/bin/ rm -f $out/usr/bin/blkid cp -P ${pkgs.util-linuxMinimal}/bin/blkid $out/usr/bin/ +cp -P ${pkgs.util-linuxMinimal}/bin/lsblk $out/usr/bin/ +cp -P ${pkgs.bash}/bin/bash $out/usr/bin/ + +### install xq (jq clone) cp -P ${pkgs.xq}/bin/xq $out/usr/bin/ +ln -sf /usr/bin/xq $out/usr/bin/jq ### install ca cert bundle chmod 755 $out/etc/ssl $out/etc/ssl/certs diff --git a/pkgs/rootfs/secure-boot-enroll.sh b/pkgs/rootfs/secure-boot-enroll.sh new file mode 100644 index 0000000..9546027 --- /dev/null +++ b/pkgs/rootfs/secure-boot-enroll.sh @@ -0,0 +1,37 @@ +#!/bin/bash +set -ex -uo pipefail + +enroll= +for o in $(< /proc/cmdline); do + case $o in + patos.secureboot=*) + enroll=${o#*=} + ;; + esac +done + +if [ -z "$enroll" ]; then + echo 'No patos.secureboot= parameter on the kernel command line' >&2 + exit 0 +fi + +SETUP_MODE=$(sbctl status --json | jq -r '.setup_mode') + +[ "$SETUP_MODE" = "false" -o "$enroll" != "true" ] && exit 0 + +cat <<EOL> /run/sbctl.yml +--- +keydir: /sysroot/boot/sbctl/keys +guid: /sysroot/boot/sbctl/GUID +EOL + +ESP=$(blkid --label ESP) + +mount $ESP /sysroot/boot && \ + sbctl --config /run/sbctl.yml create-keys && \ + sbctl --config /run/sbctl.yml enroll-keys --yolo && \ + # Sign EFIs + find /sysroot/boot -type f \( -iname "*.efi" -o -iname "*.EFI" \) -print0 | xargs -I {} sbctl --config /run/sbctl.yml sign {} + +umount /sysroot/boot && \ + systemctl reboot -f From 91a5646555d4c9c2337d42d504c2a118a7591090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 19 Mar 2025 13:21:52 +0100 Subject: [PATCH 54/67] fix: include uuid in sysupdate images --- flake.nix | 2 +- pkgs/image/default.nix | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/flake.nix b/flake.nix index 7c17fff..9e92cc8 100644 --- a/flake.nix +++ b/flake.nix @@ -18,7 +18,7 @@ pkgs = import nixpkgs { inherit system; }; patosPkgs = self.packages.${system}; version = "0.0.1"; - updateUrl = "http://10.0.2.2:8000"; + updateUrl = "http://10.0.2.2:8000/"; in { packages = { diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 8f3acbf..e0a4a24 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -93,7 +93,7 @@ Type=regular-file Verify=no EOF -cat <<EOF > rootfs/etc/sysupdate.d/20-root.transfer +cat <<EOF > rootfs/etc/sysupdate.d/20-root-verity.transfer [Source] Type=url-file Path=${updateUrl} @@ -159,7 +159,7 @@ ${patosPkgs.systemd}/usr/bin/systemd-repart \ --split=true \ --json=pretty \ --root=$out \ - patos-$version.raw > init-repart-output.json && rm -f patos-$version.raw + patos_$version.raw > init-repart-output.json && rm -f patos_$version.raw roothash=$(jq -r '.[0].roothash' init-repart-output.json) rootPart=$(jq -r '.[0].split_path' init-repart-output.json) @@ -168,6 +168,9 @@ rootUuid=$(jq -r '.[0].uuid' init-repart-output.json) verityPart=$(jq -r '.[1].split_path' init-repart-output.json) verityUuid=$(jq -r '.[1].uuid' init-repart-output.json) +ln -sf patos_$version.verity.raw patos_${version}_$verityUuid.verity +ln -sf patos_$version.root.raw patos_${version}_$rootUuid.root + ${patosPkgs.systemd}/usr/bin/ukify build \ --linux ${patosPkgs.kernel}/bzImage \ --initrd ${patosPkgs.initrd}/initrd.xz \ @@ -238,9 +241,10 @@ ${patosPkgs.systemd}/usr/bin/systemd-repart \ --size=auto \ --definitions=./final.repart.d \ --root=$out \ - patos-${version}.raw > final-repart-output.json + patos_${version}.img > final-repart-output.json rm -rf rootfs +sha256sum *.root *.verity *.efi > SHA256SUMS popd '' From 6819565d790d5a6228161e9dd2b57f447566d5cc Mon Sep 17 00:00:00 2001 From: Daniel Lundin <dln@arity.se> Date: Wed, 19 Mar 2025 19:50:39 +0100 Subject: [PATCH 55/67] qemu: remove unused ssh port forward --- utils/qemu-uefi-tpm.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/utils/qemu-uefi-tpm.nix b/utils/qemu-uefi-tpm.nix index 4fcadfd..9087ada 100644 --- a/utils/qemu-uefi-tpm.nix +++ b/utils/qemu-uefi-tpm.nix @@ -12,7 +12,10 @@ pkgs.writeShellApplication { text = let - tpmOVMF = pkgs.OVMF.override { tpmSupport = true; secureBoot = true; }; + tpmOVMF = pkgs.OVMF.override { + tpmSupport = true; + secureBoot = true; + }; in '' set -ex @@ -44,7 +47,6 @@ pkgs.writeShellApplication { -chardev socket,id=chrtpm,path="$state/swtpm-sock" \ -tpmdev emulator,id=tpm0,chardev=chrtpm \ -device tpm-tis,tpmdev=tpm0 \ - -netdev id=net00,type=user,hostfwd=tcp::2222-:22 \ -device virtio-net-pci,netdev=net00 \ -drive "format=qcow2,file=$state/disk.qcow2" ''; From c748e172796965769cc28c63ae574f1da4f62a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 19 Mar 2025 15:03:15 +0100 Subject: [PATCH 56/67] chore(sb): use systemd kernel cmdline condition --- pkgs/image/default.nix | 8 +++----- pkgs/rootfs/mkinitrd.nix | 2 ++ pkgs/rootfs/mkrootfs.nix | 13 ++++--------- pkgs/rootfs/secure-boot-enroll.sh | 18 ++---------------- 4 files changed, 11 insertions(+), 30 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index e0a4a24..94748a3 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -22,7 +22,7 @@ runCommand pname { env = { # vfat options won't efi won't find the fs otherwise. SYSTEMD_REPART_MKFS_OPTIONS_VFAT = "-S 512 -c"; - SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root"; # -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; + SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; }; kernelCmdLine = "console=ttyS0 patos.secureboot=true"; @@ -218,8 +218,8 @@ Type=root Label=root-${version} CopyBlocks=/$rootPart UUID=$rootUuid -SizeMinBytes=256M -SizeMaxBytes=256M +SizeMinBytes=64M +SizeMaxBytes=64M ReadOnly=1 EOF @@ -229,8 +229,6 @@ Type=root-verity Label=verity-${version} CopyBlocks=/$verityPart UUID=$verityUuid -SizeMinBytes=10M -SizeMaxBytes=10M ReadOnly=1 EOF diff --git a/pkgs/rootfs/mkinitrd.nix b/pkgs/rootfs/mkinitrd.nix index 10399a6..c46ed9d 100644 --- a/pkgs/rootfs/mkinitrd.nix +++ b/pkgs/rootfs/mkinitrd.nix @@ -47,6 +47,8 @@ DefaultDependencies=false After=sysroot-run.mount Requires=sysroot-run.mount Before=systemd-repart.service initrd.target shutdown.target sysinit.target +ConditionKernelCommandLine=patos.secureboot=true +ConditionPathExists=|!/sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c [Service] Type=oneshot diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index 61e99d1..257ffb6 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -81,23 +81,21 @@ EOF cat <<EOF > $out/etc/repart.d/20-root-a.conf [Partition] Type=root -SizeMaxBytes=256M -SizeMinBytes=256M +SizeMaxBytes=64M +SizeMinBytes=64M EOF cat <<EOF > $out/etc/repart.d/22-root-verify-a.conf [Partition] Type=root-verity -SizeMaxBytes=10M -SizeMinBytes=10M EOF cat <<EOF > $out/etc/repart.d/30-root-b.conf [Partition] Type=root Label=_empty -SizeMaxBytes=256M -SizeMinBytes=256M +SizeMaxBytes=64M +SizeMinBytes=64M ReadOnly=1 EOF @@ -105,8 +103,6 @@ cat <<EOF > $out/etc/repart.d/32-root-verity-b.conf [Partition] Type=root-verity Label=_empty -SizeMaxBytes=10M -SizeMinBytes=10M ReadOnly=1 EOF @@ -179,7 +175,6 @@ cp -P ${pkgs.sbctl}/bin/sbctl $out/usr/bin/ rm -f $out/usr/bin/blkid cp -P ${pkgs.util-linuxMinimal}/bin/blkid $out/usr/bin/ cp -P ${pkgs.util-linuxMinimal}/bin/lsblk $out/usr/bin/ -cp -P ${pkgs.bash}/bin/bash $out/usr/bin/ ### install xq (jq clone) cp -P ${pkgs.xq}/bin/xq $out/usr/bin/ diff --git a/pkgs/rootfs/secure-boot-enroll.sh b/pkgs/rootfs/secure-boot-enroll.sh index 9546027..2588baf 100644 --- a/pkgs/rootfs/secure-boot-enroll.sh +++ b/pkgs/rootfs/secure-boot-enroll.sh @@ -1,23 +1,9 @@ -#!/bin/bash +#!/bin/sh set -ex -uo pipefail -enroll= -for o in $(< /proc/cmdline); do - case $o in - patos.secureboot=*) - enroll=${o#*=} - ;; - esac -done - -if [ -z "$enroll" ]; then - echo 'No patos.secureboot= parameter on the kernel command line' >&2 - exit 0 -fi - SETUP_MODE=$(sbctl status --json | jq -r '.setup_mode') -[ "$SETUP_MODE" = "false" -o "$enroll" != "true" ] && exit 0 +[ "$SETUP_MODE" = "false" ] && exit 0 cat <<EOL> /run/sbctl.yml --- From 4166b4c1fb0ba384d7f8de43b9517a9bfc0205be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 19 Mar 2025 15:03:15 +0100 Subject: [PATCH 57/67] feat: kernel modules as system extensions --- flake.nix | 2 +- pkgs/image/default.nix | 36 +++++++++++++++++++++++++++++++----- pkgs/kernel/generic.config | 10 +++++----- pkgs/rootfs/mkrootfs.nix | 2 ++ utils/qemu-uefi-tpm.nix | 1 + 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/flake.nix b/flake.nix index 9e92cc8..b4a7411 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ let pkgs = import nixpkgs { inherit system; }; patosPkgs = self.packages.${system}; - version = "0.0.1"; + version = "0.0.3"; updateUrl = "http://10.0.2.2:8000/"; in { diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 94748a3..452bf1f 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -25,18 +25,28 @@ runCommand pname { SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; }; - kernelCmdLine = "console=ttyS0 patos.secureboot=true"; + kernelCmdLine = "console=ttyS0 patos.secureboot=false"; } '' mkdir -p $out/init.repart.d $out/final.repart.d pushd $out -# Don't seem to work just to create a symlink to rootfs derivation? -# ln -sf $rootfs rootfs mkdir rootfs cp -prP ${patosPkgs.rootfs}/* rootfs/ find rootfs/ -type d -exec chmod 755 {} \; +# package kernel modules as sysext +pkgName="patos-kernel-modules-${version}" +mkdir -p ./tree/usr/lib/extension-release.d +cat << EOF > ./tree/usr/lib/extension-release.d/extension-release.patos-kernel-modules +ID=patos +IMAGE_ID=patos-kernel-modules +IMAGE_VERSION=${version} +VERSION_ID=patos +EOF +cp -Prp rootfs/usr/lib/modules ./tree/usr/lib/modules && rm -rf rootfs/usr/lib/modules +tar -cJf $pkgName.tar.xz -C ./tree . --owner=root:0 --group=root:0 && rm -rf tree + # set default target to multi-user ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target @@ -127,6 +137,22 @@ ReadOnly=1 Verify=no EOF +cat <<EOF > rootfs/etc/sysupdate.d/30-kernel-modules.transfer +[Source] +Type=url-tar +Path=${updateUrl} +MatchPattern=patos-kernel-modules-@v.tar.xz + +[Target] +Type=subvolume +Path=/var/lib/extensions +MatchPattern=patos-kernel-modules-@v +CurrentSymlink=patos-kernel-modules + +[Transfer] +Verify=no +EOF + # Initial partitioning cat <<EOF > init.repart.d/10-root.conf @@ -241,8 +267,8 @@ ${patosPkgs.systemd}/usr/bin/systemd-repart \ --root=$out \ patos_${version}.img > final-repart-output.json -rm -rf rootfs -sha256sum *.root *.verity *.efi > SHA256SUMS +rm -rf rootfs init.repart.d final.repart.d *.json +sha256sum *.root *.verity *.efi *.tar.xz > SHA256SUMS popd '' diff --git a/pkgs/kernel/generic.config b/pkgs/kernel/generic.config index 048421b..4c67b0a 100644 --- a/pkgs/kernel/generic.config +++ b/pkgs/kernel/generic.config @@ -276,7 +276,7 @@ CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE=y CONFIG_BSD_DISKLABEL=y CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_BUFFER_HEAD=y CONFIG_BUG_ON_DATA_CORRUPTION=y @@ -426,7 +426,7 @@ CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=y CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=y CONFIG_CRYPTO_AUTHENC=y -CONFIG_CRYPTO_BLAKE2B=m +CONFIG_CRYPTO_BLAKE2B=y CONFIG_CRYPTO_BLAKE2S_X86=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CCM=y @@ -643,7 +643,7 @@ CONFIG_ELF_CORE=y CONFIG_ELFCORE=y CONFIG_ENA_ETHERNET=y CONFIG_ENCLOSURE_SERVICES=y -CONFIG_ENCRYPTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=y CONFIG_ENIC=m CONFIG_EPOLL=y CONFIG_EROFS_FS_POSIX_ACL=y @@ -1953,7 +1953,7 @@ CONFIG_QUOTA_TREE=y CONFIG_QUOTA=y CONFIG_R8169=m CONFIG_RAID6_PQ_BENCHMARK=y -CONFIG_RAID6_PQ=m +CONFIG_RAID6_PQ=y CONFIG_RAID_ATTRS=y CONFIG_RANDOMIZE_BASE=y CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y @@ -2487,7 +2487,7 @@ CONFIG_XFS_QUOTA=y CONFIG_XFS_RT=y CONFIG_XFS_SUPPORT_ASCII_CI=y CONFIG_XFS_SUPPORT_V4=y -CONFIG_XOR_BLOCKS=m +CONFIG_XOR_BLOCKS=y CONFIG_XPS=y CONFIG_XXHASH=y CONFIG_XZ_DEC_ARMTHUMB=y diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index 257ffb6..235a70a 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -172,7 +172,9 @@ cp -P ${pkgs.libbpf}/lib/libbpf*.so* $out/usr/lib/ ### install secure boot tools cp -P ${pkgs.sbctl}/bin/sbctl $out/usr/bin/ +rm -f $out/usr/bin/tar rm -f $out/usr/bin/blkid +cp -P ${pkgs.gnutar}/bin/tar $out/usr/bin/ cp -P ${pkgs.util-linuxMinimal}/bin/blkid $out/usr/bin/ cp -P ${pkgs.util-linuxMinimal}/bin/lsblk $out/usr/bin/ diff --git a/utils/qemu-uefi-tpm.nix b/utils/qemu-uefi-tpm.nix index 9087ada..7d51868 100644 --- a/utils/qemu-uefi-tpm.nix +++ b/utils/qemu-uefi-tpm.nix @@ -47,6 +47,7 @@ pkgs.writeShellApplication { -chardev socket,id=chrtpm,path="$state/swtpm-sock" \ -tpmdev emulator,id=tpm0,chardev=chrtpm \ -device tpm-tis,tpmdev=tpm0 \ + -netdev id=net00,type=user \ -device virtio-net-pci,netdev=net00 \ -drive "format=qcow2,file=$state/disk.qcow2" ''; From 91191a29474d3b1a2aec4314c3ee8545b1339f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 20 Mar 2025 14:01:50 +0100 Subject: [PATCH 58/67] revert version --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index b4a7411..9e92cc8 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ let pkgs = import nixpkgs { inherit system; }; patosPkgs = self.packages.${system}; - version = "0.0.3"; + version = "0.0.1"; updateUrl = "http://10.0.2.2:8000/"; in { From a7de3101a8184a8a885a2973756fffb2f50e3bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 20 Mar 2025 16:06:31 +0100 Subject: [PATCH 59/67] chore: include kernel modules in rootfs as sysext --- pkgs/image/default.nix | 32 ++++---------------------------- pkgs/kernel/manual-config.nix | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index 452bf1f..a248a09 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -35,17 +35,10 @@ mkdir rootfs cp -prP ${patosPkgs.rootfs}/* rootfs/ find rootfs/ -type d -exec chmod 755 {} \; -# package kernel modules as sysext -pkgName="patos-kernel-modules-${version}" -mkdir -p ./tree/usr/lib/extension-release.d -cat << EOF > ./tree/usr/lib/extension-release.d/extension-release.patos-kernel-modules -ID=patos -IMAGE_ID=patos-kernel-modules -IMAGE_VERSION=${version} -VERSION_ID=patos -EOF -cp -Prp rootfs/usr/lib/modules ./tree/usr/lib/modules && rm -rf rootfs/usr/lib/modules -tar -cJf $pkgName.tar.xz -C ./tree . --owner=root:0 --group=root:0 && rm -rf tree +# package kernel modules as sysext (will reduce the image size a little bit (~3MB)) +mkdir rootfs/etc/extensions +rm -rf rootfs/usr/lib/modules +cp ${patosPkgs.kernel}/patos-kernel-modules* rootfs/etc/extensions/ # set default target to multi-user ln -sf multi-user.target rootfs/usr/lib/systemd/system/default.target @@ -137,23 +130,6 @@ ReadOnly=1 Verify=no EOF -cat <<EOF > rootfs/etc/sysupdate.d/30-kernel-modules.transfer -[Source] -Type=url-tar -Path=${updateUrl} -MatchPattern=patos-kernel-modules-@v.tar.xz - -[Target] -Type=subvolume -Path=/var/lib/extensions -MatchPattern=patos-kernel-modules-@v -CurrentSymlink=patos-kernel-modules - -[Transfer] -Verify=no -EOF - - # Initial partitioning cat <<EOF > init.repart.d/10-root.conf [Partition] diff --git a/pkgs/kernel/manual-config.nix b/pkgs/kernel/manual-config.nix index 9f1ba99..98b09f8 100644 --- a/pkgs/kernel/manual-config.nix +++ b/pkgs/kernel/manual-config.nix @@ -22,6 +22,8 @@ pahole, kmod, ubootTools, + erofs-utils, + cryptsetup, fetchpatch, rustc, rust-bindgen, @@ -224,6 +226,8 @@ lib.makeOverridable ( python3Minimal kmod hexdump + erofs-utils + cryptsetup ] ++ optional needsUbootTools ubootTools ++ optionals (lib.versionAtLeast version "5.2") [ @@ -496,6 +500,20 @@ lib.makeOverridable ( # Delete empty directories find -empty -type d -delete + + pkgName="patos-kernel-modules" + mkdir -p $out/tree/usr/lib/extension-release.d + cat << EOF > $out/tree/usr/lib/extension-release.d/extension-release.$pkgName + ID=patos + IMAGE_ID=$pkgName + IMAGE_VERSION=${version} + VERSION_ID=patos + EOF + cp -Prp $out/lib/modules $out/tree/usr/lib/modules + find $out/tree -type d -exec chmod 0755 {} \; + mkfs.erofs --all-root -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking $out/$pkgName.raw $out/tree/ + veritysetup format --root-hash-file $out/$pkgName.roothash $out/$pkgName.raw $out/$pkgName.verity + chmod -R 755 $out/tree && rm -rf $out/tree ''; requiredSystemFeatures = [ "big-parallel" ]; From 2841610f418660be880ccfde482255b0de71394d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Mar 2025 10:30:23 +0100 Subject: [PATCH 60/67] chore: bump kernel version --- pkgs/kernel/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix index a5f24db..51a05bf 100644 --- a/pkgs/kernel/default.nix +++ b/pkgs/kernel/default.nix @@ -1,7 +1,7 @@ { pkgs }: let - version = "6.13.7"; - hash = "sha256-Ojm2IDi3rC9D0mofhLQoPhl4BOHoF61jfpo9h0xHgB0="; + version = "6.13.8"; + hash = "sha256-JZr6Wdc9Z2vsKuib6s2UngjVTT9wp/iwp0IxUJV1Grs="; in (pkgs.callPackage ./manual-config.nix { }) { version = "${version}-patos1"; From bb708e3e61102caef9337c45f29b033dfd2b4ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Mar 2025 10:37:38 +0100 Subject: [PATCH 61/67] feat(image): parameter to include microcode and secureboot --- flake.nix | 4 +++- pkgs/image/default.nix | 14 ++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 9e92cc8..99fce5b 100644 --- a/flake.nix +++ b/flake.nix @@ -18,12 +18,14 @@ pkgs = import nixpkgs { inherit system; }; patosPkgs = self.packages.${system}; version = "0.0.1"; + secureBoot = "false"; + cpuArch = "intel"; updateUrl = "http://10.0.2.2:8000/"; in { packages = { default = patosPkgs.image; - image = pkgs.callPackage ./pkgs/image { inherit patosPkgs version updateUrl; }; + image = pkgs.callPackage ./pkgs/image { inherit patosPkgs version updateUrl cpuArch secureBoot; }; rootfs = pkgs.callPackage ./pkgs/rootfs/mkrootfs.nix { inherit patosPkgs version; }; initrd = pkgs.callPackage ./pkgs/rootfs/mkinitrd.nix { inherit patosPkgs version; }; kernel = pkgs.callPackage ./pkgs/kernel { }; diff --git a/pkgs/image/default.nix b/pkgs/image/default.nix index a248a09..05d9c72 100644 --- a/pkgs/image/default.nix +++ b/pkgs/image/default.nix @@ -1,16 +1,21 @@ { + lib, pkgs, patosPkgs, version, runCommand, - updateUrl + updateUrl, + cpuArch ? "", + secureBoot ? "false" }: let pname = "patos-image"; in runCommand pname { - inherit version; - inherit updateUrl; + inherit version cpuArch updateUrl secureBoot; + + microcode = lib.optionalString (cpuArch == "amd") "--microcode ${pkgs.microcode-amd}/amd-ucode.img" + + lib.optionalString (cpuArch == "intel") "--microcode ${pkgs.microcode-intel}/intel-ucode.img"; buildInputs = with pkgs; [ erofs-utils @@ -25,7 +30,7 @@ runCommand pname { SYSTEMD_REPART_MKFS_OPTIONS_EROFS = "--all-root -zlz4hc,12 -C1048576 -Efragments,dedupe,ztailpacking"; }; - kernelCmdLine = "console=ttyS0 patos.secureboot=false"; + kernelCmdLine = "console=ttyS0 patos.secureboot=${secureBoot}"; } '' mkdir -p $out/init.repart.d $out/final.repart.d @@ -176,6 +181,7 @@ ln -sf patos_$version.root.raw patos_${version}_$rootUuid.root ${patosPkgs.systemd}/usr/bin/ukify build \ --linux ${patosPkgs.kernel}/bzImage \ --initrd ${patosPkgs.initrd}/initrd.xz \ + $microcode \ --os-release @rootfs/etc/os-release \ --cmdline "$kernelCmdLine roothash=$roothash" \ -o patos_${version}.efi From 242294eb8dba13d301acb2a5b463cf3648eb7df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Mar 2025 11:13:16 +0100 Subject: [PATCH 62/67] chore: nix flake update --- flake.lock | 6 +++--- pkgs/busybox/default.nix | 8 +++----- pkgs/openssl/default.nix | 9 +++------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/flake.lock b/flake.lock index 85be38f..2272d3d 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1739020877, - "narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=", + "lastModified": 1742669843, + "narHash": "sha256-G5n+FOXLXcRx+3hCJ6Rt6ZQyF1zqQ0DL0sWAMn2Nk0w=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a79cfe0ebd24952b580b1cf08cd906354996d547", + "rev": "1e5b653dff12029333a6546c11e108ede13052eb", "type": "github" }, "original": { diff --git a/pkgs/busybox/default.nix b/pkgs/busybox/default.nix index e318d8a..6f22641 100644 --- a/pkgs/busybox/default.nix +++ b/pkgs/busybox/default.nix @@ -1,6 +1,7 @@ { stdenv, lib, + pkgs, buildPackages, fetchurl, fetchpatch, @@ -57,15 +58,12 @@ in stdenv.mkDerivation rec { pname = "busybox"; - version = "1.36.1"; + version = pkgs.busybox.version; # Note to whoever is updating busybox: please verify that: # nix-build pkgs/stdenv/linux/make-bootstrap-tools.nix -A test # still builds after the update. - src = fetchurl { - url = "https://busybox.net/downloads/${pname}-${version}.tar.bz2"; - sha256 = "sha256-uMwkyVdNgJ5yecO+NJeVxdXOtv3xnKcJ+AzeUOR94xQ="; - }; + src = pkgs.busybox.src; hardeningDisable = [ "format" diff --git a/pkgs/openssl/default.nix b/pkgs/openssl/default.nix index bc833cc..08c1309 100644 --- a/pkgs/openssl/default.nix +++ b/pkgs/openssl/default.nix @@ -1,5 +1,6 @@ { lib, + pkgs, stdenv, fetchurl, perl, @@ -18,13 +19,9 @@ stdenv.mkDerivation rec { pname = "openssl"; - version = "3.4.1"; - hash = "sha256-ACotazC1i/S+pGxDvdljZar42qbEKHgqpP7uBtoZffM="; + version = pkgs.openssl.version; - src = fetchurl { - url = "https://github.com/openssl/openssl/releases/download/openssl-${version}/openssl-${version}.tar.gz"; - hash = hash; - }; + src = pkgs.openssl.src; outputs = [ "out" ]; From c470bf6d595176023198e1164db01f00aa177c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Mar 2025 11:49:37 +0100 Subject: [PATCH 63/67] chore: track upstream nixpkgs for our forks --- pkgs/dbus-broker/default.nix | 9 ++------- pkgs/lvm2/default.nix | 13 ++++--------- pkgs/result | 1 + pkgs/tpm2-tools/default.nix | 11 +++++------ pkgs/tpm2-tss/default.nix | 10 +++------- 5 files changed, 15 insertions(+), 29 deletions(-) create mode 120000 pkgs/result diff --git a/pkgs/dbus-broker/default.nix b/pkgs/dbus-broker/default.nix index 809f3ce..0002d9c 100644 --- a/pkgs/dbus-broker/default.nix +++ b/pkgs/dbus-broker/default.nix @@ -100,14 +100,9 @@ in stdenv.mkDerivation (finalAttrs: { pname = "dbus-broker"; - version = "36"; + version = pkgs.dbus-broker.version; - src = fetchFromGitHub { - owner = "bus1"; - repo = "dbus-broker"; - rev = "v${finalAttrs.version}"; - hash = "sha256-5dAMKjybqrHG57vArbtWEPR/svSj2ION75JrjvnnpVM="; - }; + src = pkgs.dbus-broker.src; nativeBuildInputs = with pkgs; [ docutils diff --git a/pkgs/lvm2/default.nix b/pkgs/lvm2/default.nix index f211e26..8d18663 100644 --- a/pkgs/lvm2/default.nix +++ b/pkgs/lvm2/default.nix @@ -1,5 +1,6 @@ { stdenv, + pkgs, fetchurl, lib, pkg-config, @@ -7,17 +8,11 @@ udev, }: -stdenv.mkDerivation rec { +stdenv.mkDerivation { pname = "lvm2"; - version = "2.03.30"; + version = pkgs.lvm2.version; - src = fetchurl { - urls = [ - "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${version}.tgz" - "ftp://sourceware.org/pub/lvm2/LVM2.${version}.tgz" - ]; - hash = "sha256-rXar7LjciHcz4GxEnLmt0Eo1BvnweAwSiBem4aF87AU="; - }; + src = pkgs.lvm2.src; nativeBuildInputs = [ pkg-config diff --git a/pkgs/result b/pkgs/result new file mode 120000 index 0000000..301e3b1 --- /dev/null +++ b/pkgs/result @@ -0,0 +1 @@ +/nix/store/9m1cdv4fiky0mihfx3ck8vcknclcagn2-patos-image \ No newline at end of file diff --git a/pkgs/tpm2-tools/default.nix b/pkgs/tpm2-tools/default.nix index f447fe6..4bb14c1 100644 --- a/pkgs/tpm2-tools/default.nix +++ b/pkgs/tpm2-tools/default.nix @@ -1,5 +1,6 @@ { stdenv, + pkgs, fetchurl, lib, pandoc, @@ -10,19 +11,17 @@ libuuid, }: -stdenv.mkDerivation rec { +stdenv.mkDerivation { pname = "tpm2-tools"; - version = "5.7"; + version = pkgs.tpm2-tools.version; - src = fetchurl { - url = "https://github.com/tpm2-software/${pname}/releases/download/${version}/${pname}-${version}.tar.gz"; - sha256 = "sha256-OBDTa1B5JW9PL3zlUuIiE9Q7EDHBMVON+KLbw8VwmDo="; - }; + src = pkgs.tpm2-tools.src; nativeBuildInputs = [ pandoc pkg-config ]; + buildInputs = [ curl openssl diff --git a/pkgs/tpm2-tss/default.nix b/pkgs/tpm2-tss/default.nix index 5e23100..5a6477a 100644 --- a/pkgs/tpm2-tss/default.nix +++ b/pkgs/tpm2-tss/default.nix @@ -1,5 +1,6 @@ { stdenv, + pkgs, lib, fetchFromGitHub, autoreconfHook, @@ -19,14 +20,9 @@ stdenv.mkDerivation rec { pname = "tpm2-tss"; - version = "4.1.3"; + version = pkgs.tpm2-tss.version; - src = fetchFromGitHub { - owner = "tpm2-software"; - repo = pname; - rev = version; - hash = "sha256-BP28utEUI9g1VNv3lCXuiKrDtEImFQxxZfIjLiE3Wr8="; - }; + src = pkgs.tpm2-tss.src; patches = [ ./no-shadow.patch From d10bd7bb04c494ef37096467d34135b4b447ca61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Wed, 26 Mar 2025 11:57:03 +0100 Subject: [PATCH 64/67] fix(rootfs): symlink /var/tmp to /tmp if no state partition available this enable systemd networkd and resolved to work --- pkgs/result | 1 - pkgs/rootfs/mkrootfs.nix | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 120000 pkgs/result diff --git a/pkgs/result b/pkgs/result deleted file mode 120000 index 301e3b1..0000000 --- a/pkgs/result +++ /dev/null @@ -1 +0,0 @@ -/nix/store/9m1cdv4fiky0mihfx3ck8vcknclcagn2-patos-image \ No newline at end of file diff --git a/pkgs/rootfs/mkrootfs.nix b/pkgs/rootfs/mkrootfs.nix index 235a70a..bda4c7d 100644 --- a/pkgs/rootfs/mkrootfs.nix +++ b/pkgs/rootfs/mkrootfs.nix @@ -21,11 +21,12 @@ runCommand "patos-rootfs" '' ### create directory structure mkdir -p $out/etc/repart.d $out/dev $out/proc $out/sys \ - $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var/tmp + $out/tmp $out/root $out/run $out/boot $out/mnt $out/home $out/srv $out/var ln -sf /usr/bin $out/bin ln -sf /usr/bin $out/sbin ln -sf /usr/lib $out/lib ln -sf /usr/lib $out/lib64 +ln -sf /tmp $out/var/tmp ln -sf ../proc/self/mounts $out/etc/mtab ### install systemd From 58861e6de6c80d6b93609185048f2a98e515b444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Thu, 17 Apr 2025 19:06:37 +0200 Subject: [PATCH 65/67] chore: upgrade systemd --- pkgs/systemd/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/systemd/default.nix b/pkgs/systemd/default.nix index a1cb314..a93fd76 100644 --- a/pkgs/systemd/default.nix +++ b/pkgs/systemd/default.nix @@ -7,7 +7,7 @@ ... }: let - version = "257.4"; + version = "257.5"; # Use the command below to update `releaseTimestamp` on every (major) version # change. More details in the commentary at mesonFlags. From 92c204231b7cfaa9f3b880e8d3b27af2ad6474d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Sat, 19 Apr 2025 22:56:00 +0200 Subject: [PATCH 66/67] chore: nix flake update --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 2272d3d..3725da4 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1742669843, - "narHash": "sha256-G5n+FOXLXcRx+3hCJ6Rt6ZQyF1zqQ0DL0sWAMn2Nk0w=", + "lastModified": 1744932701, + "narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1e5b653dff12029333a6546c11e108ede13052eb", + "rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", "type": "github" }, "original": { From 15227256ecf0e8aea67d3ebb21e2122a7b6a0f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= <lars@radicore.se> Date: Sat, 19 Apr 2025 23:06:44 +0200 Subject: [PATCH 67/67] chore: kernel upgrade --- pkgs/kernel/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/kernel/default.nix b/pkgs/kernel/default.nix index 51a05bf..1297825 100644 --- a/pkgs/kernel/default.nix +++ b/pkgs/kernel/default.nix @@ -1,7 +1,7 @@ { pkgs }: let - version = "6.13.8"; - hash = "sha256-JZr6Wdc9Z2vsKuib6s2UngjVTT9wp/iwp0IxUJV1Grs="; + version = "6.14.2"; + hash = "sha256-xcaCo1TqMZATk1elfTSnnlw3IhrOgjqTjhARa1d6Lhs="; in (pkgs.callPackage ./manual-config.nix { }) { version = "${version}-patos1";