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] 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/