Compare commits

..

1 commit

47 changed files with 1188 additions and 5211 deletions

View file

@ -1,3 +1 @@
nix_direnv_manual_reload
use flake
dotenv_if_exists

1
.gitignore vendored
View file

@ -4,7 +4,6 @@
.task
/result
/target
/out
.*.swp
.*.swo
.nixos-test-history

53
flake.lock generated
View file

@ -1,30 +1,12 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1744932701,
"narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=",
"lastModified": 1731139594,
"narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef",
"rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2",
"type": "github"
},
"original": {
@ -34,26 +16,27 @@
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"nixpkgs-staging-next": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"lastModified": 1736775562,
"narHash": "sha256-4qqVIwZXGezX1X6Hyo+MdU/xhQv4IMKCE4qqa1oXYw4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "71c2fcc94d888c994a0962af2d1d78ae73181c79",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"owner": "NixOS",
"ref": "staging-next",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"nixpkgs-staging-next": "nixpkgs-staging-next"
}
}
},
"root": "root",

168
flake.nix
View file

@ -2,104 +2,96 @@
description = "PatOS is a minimal, immutable Linux distribution specialized for the Patagia Platform.";
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs-staging-next.url = "github:NixOS/nixpkgs/staging-next";
};
outputs =
{ self, nixpkgs, nixpkgs-staging-next }:
let
releaseVersion = "0.0.1";
system = "x86_64-linux";
updateUrl = "https://images.dl.patagia.dev/patos/";
pkgs = import nixpkgs { inherit system; };
in
{
self,
flake-utils,
nixpkgs,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
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 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 { };
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; };
tpm2-tss = pkgs.callPackage ./pkgs/tpm2-tss { };
systemd = pkgs.callPackage ./pkgs/systemd { };
dbus-broker = pkgs.callPackage ./pkgs/dbus-broker { };
nixosModules.devel.imports = [
./modules/profiles/devel.nix
];
qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { };
nixosModules.server.imports = [
./modules/profiles/server.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 = 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"; }
nixosModules.image.imports = [
./modules
./modules/profiles/base.nix
./modules/image
];
packages.${system} = {
devel =
(nixpkgs.lib.nixosSystem {
modules = [
(
{ lib, ... }:
{
nixpkgs.hostPlatform = system;
system.stateVersion = "24.05";
}
)
{
system.image.updates.url = "${updateUrl}";
system.image.id = "patos";
system.image.version = releaseVersion;
image.compress = false;
nixpkgs.overlays = [
(final: prev: {
systemd = nixpkgs-staging-next.legacyPackages.${final.system}.systemd;
})
];
}
self.nixosModules.image
self.nixosModules.devel
];
};
};
}).config.system.build.updatePackage;
checks = {
simple-test = pkgs.runCommand "simple-test" { } ''
${self.packages.${system}.default}/bin/my-program
touch $out
'';
};
patos =
(nixpkgs.lib.nixosSystem {
modules = [
(
{ lib, ... }:
{
nixpkgs.hostPlatform = system;
system.stateVersion = "24.05";
}
)
{
system.image.updates.url = "${updateUrl}";
system.image.id = "patos";
system.image.version = releaseVersion;
}
self.nixosModules.image
self.nixosModules.server
];
}).config.system.build.updatePackage;
formatter = pkgs.nixpkgs-fmt;
qemu-uefi-tpm = pkgs.callPackage ./utils/qemu-uefi-tpm.nix { inherit pkgs; };
};
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
just
nixd
nixfmt-rfc-style
patosPkgs.qemu-uefi-tpm
];
};
checks.${system} = {
podman = import ./tests/podman.nix { inherit pkgs self; };
system-update = import ./tests/system-update.nix { inherit pkgs self; };
};
}
);
devShells.${system}.default = pkgs.mkShell {
buildInputs = with pkgs; [
erofs-utils
just
self.packages.${system}.qemu-uefi-tpm
squashfs-tools-ng
];
};
};
}

View file

@ -1,91 +0,0 @@
{
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 /usr/lib $destfile || true
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
# 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
''

View file

@ -0,0 +1,15 @@
{ config, ... }:
{
boot = {
bootspec.enable = false;
initrd.kernelModules = config.boot.kernelModules;
kernel.enable = false; # No kernel or modules in the rootfs
modprobeConfig.enable = false;
};
system.build = {
inherit (config.boot.kernelPackages) kernel;
};
system.modulesTree = [ config.boot.kernelPackages.kernel ] ++ config.boot.extraModulePackages;
}

View file

@ -0,0 +1,26 @@
{ ... }:
{
nixpkgs.overlays = [
(final: prev: {
composefs = final.callPackage ../../pkgs/composefs.nix { inherit prev; };
qemu_tiny = final.callPackage ../../pkgs/qemu.nix { inherit prev; };
systemdUkify = final.callPackage ../../pkgs/systemd-ukify.nix { inherit prev; };
# # FIXME: Revisit + refine these below in a future image minimization effort
#
# util-linux = prev.util-linux.override {
# ncursesSupport = false;
# nlsSupport = false;
# };
#
# dbus = prev.dbus.override {
# enableSystemd = false;
# x11Support = false;
# };
})
];
}

6
modules/default.nix Normal file
View file

@ -0,0 +1,6 @@
{
imports = [
./config/minimal-modules.nix
./config/minimal-system.nix
];
}

196
modules/image/builder.nix Normal file
View file

@ -0,0 +1,196 @@
{
config,
lib,
options,
pkgs,
...
}:
let
inherit (pkgs.stdenv.hostPlatform) efiArch;
initialPartitions = {
"10-root" = {
storePaths = [ config.system.build.toplevel ];
repartConfig = {
Type = "root";
Minimize = "best";
Format = "erofs";
MakeDirectories = "/home /root /etc /dev /sys /bin /var /proc /run /usr /srv /tmp /mnt /lib /efi";
Verity = "data";
VerityMatchKey = "root";
SplitName = "root";
};
};
"20-root-verity" = {
repartConfig = {
Type = "root-verity";
Minimize = "best";
Verity = "hash";
VerityMatchKey = "root";
SplitName = "verity";
};
};
};
# TODO: We don't need a combined image here - add dry-run flag to repart invocation
verityRepart = import (pkgs.path + "/nixos/lib/eval-config.nix") {
inherit lib pkgs;
system = null;
modules = [
(
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/image/repart.nix") ];
image.repart = {
name = "verity";
split = true;
mkfsOptions = lib.mkIf config.image.compress {
erofs = [
"-zlz4hc,level=12"
"-Efragments,dedupe,ztailpacking"
];
};
partitions = initialPartitions;
};
}
)
];
};
rootPart = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.root.raw";
verityPart = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.verity.raw";
verityImgAttrs = builtins.fromJSON (
builtins.readFile "${verityRepart.config.system.build.image}/repart-output.json"
);
rootAttrs = builtins.elemAt verityImgAttrs 0;
verityAttrs = builtins.elemAt verityImgAttrs 1;
rootUuid = rootAttrs.uuid;
verityUuid = verityAttrs.uuid;
verityRootHash = rootAttrs.roothash;
finalPartitions = {
"10-esp" = {
contents = {
"/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = "${pkgs.systemdUkify}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
"/EFI/Linux/${config.system.boot.loader.ukiFile}".source = "${config.system.build.uki}/${config.system.boot.loader.ukiFile}";
"/EFI/memtest86/memtest86.efi".source = "${pkgs.memtest86plus}/memtest.efi";
"/loader/entries/patos-factory-reset.conf".source = pkgs.writeText "patos-factory-reset.conf" ''
title Patos Factory Reset
efi /EFI/Linux/${config.system.boot.loader.ukiFile}
options ${toString config.boot.kernelParams} systemd.factory_reset=yes
sort-key z_factory_reset
'';
"/loader/entries/memtest86.conf".source = pkgs.writeText "memtest86.conf" ''
title Memtest86+
efi /EFI/memtest86/memtest86.efi
options console=ttyS0
sort-key z_memtest
'';
"/loader/loader.conf".source = pkgs.writeText "loader.conf" ''
timeout 2
'';
};
repartConfig = {
Type = "esp";
Format = "vfat";
SizeMinBytes = "96M";
SizeMaxBytes = "96M";
SplitName = "-";
};
};
"20-root-verity-a" = {
repartConfig = {
Type = "root-verity";
Label = "verity-${config.system.image.version}";
CopyBlocks = "${verityPart}";
SplitName = "-";
SizeMinBytes = "64M";
SizeMaxBytes = "64M";
UUID = "${verityUuid}";
ReadOnly = 1;
};
};
# TODO: Add signature partition for systemd-nspawn
"22-root-a" = {
repartConfig = {
Type = "root";
Label = "root-${config.system.image.version}";
CopyBlocks = "${rootPart}";
SplitName = "-";
UUID = "${rootUuid}";
ReadOnly = 1;
};
};
};
finalRepart = import (pkgs.path + "/nixos/lib/eval-config.nix") {
inherit lib pkgs;
system = null;
modules = [
(
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/image/repart.nix") ];
image.repart = {
name = "${config.system.image.id}";
partitions = finalPartitions;
};
}
)
];
};
in
{
# This fields is immutable by default, but can be overridden.
options.system.nixos.codeName = lib.mkOption { readOnly = false; };
options.system.nixos.release = lib.mkOption { readOnly = false; };
# FIXME: Should be configured somehow
config.system.nixos = {
codeName = "Finn";
distroId = "patos";
distroName = "PatOS";
release = "2024-11";
variant_id = "server";
variantName = "Server";
vendorName = "PatOS";
};
options.image.compress = lib.mkEnableOption "image compression" // {
default = true;
};
config.system.build = {
inherit verityRootHash;
image =
(pkgs.linkFarm "image-release" [
{
name = "${config.system.image.id}_${config.system.image.version}.efi";
path = "${config.system.build.uki}/${config.system.boot.loader.ukiFile}";
}
{
name = "${config.system.image.id}_${config.system.image.version}_${verityUuid}.verity";
path = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.verity.raw";
}
{
name = "${config.system.image.id}_${config.system.image.version}_${rootUuid}.root";
path = "${verityRepart.config.system.build.image}/${verityRepart.config.image.repart.imageFileBasename}.root.raw";
}
{
name = "${config.system.image.id}_${config.system.image.version}.img";
path = "${finalRepart.config.system.build.image}/${finalRepart.config.image.repart.imageFileBasename}.raw";
}
])
// {
imageFile = "${config.system.image.id}_${config.system.image.version}.img";
};
};
}

139
modules/image/default.nix Normal file
View file

@ -0,0 +1,139 @@
{
config,
lib,
pkgs,
...
}:
{
imports = [
./updater.nix
./builder.nix
./veritysetup.nix
];
system.build.updatePackage = pkgs.runCommand "update-package" { } ''
mkdir "$out"
cd "$out"
cp "${config.system.build.image}"/* .
${pkgs.coreutils}/bin/sha256sum * > SHA256SUMS
'';
systemd.repart.partitions = {
"10-esp" = {
Type = "esp";
Format = "vfat";
SizeMinBytes = "96M";
SizeMaxBytes = "96M";
};
"20-root-verity-a" = {
Type = "root-verity";
SizeMinBytes = "64M";
SizeMaxBytes = "64M";
};
"22-root-a" = {
Type = "root";
SizeMinBytes = "512M";
SizeMaxBytes = "512M";
};
"30-root-verity-b" = {
Type = "root-verity";
SizeMinBytes = "64M";
SizeMaxBytes = "64M";
Label = "_empty";
ReadOnly = 1;
};
"32-root-b" = {
Type = "root";
SizeMinBytes = "512M";
SizeMaxBytes = "512M";
Label = "_empty";
ReadOnly = 1;
};
"40-var" = {
Type = "var";
UUID = "4d21b016-b534-45c2-a9fb-5c16e091fd2d"; # Well known
Format = "btrfs";
Label = "patos-state";
Minimize = "off";
FactoryReset = "yes";
# FIXME: borked w/systemd 257?
# Encrypt = "tpm2";
SizeMinBytes = "2G";
SplitName = "-";
};
};
boot.loader.grub.enable = false;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.enable = true;
boot.uki.name = "patos";
boot.initrd = {
compressor = "zstd";
compressorArgs = [ "-8" ];
luks.forceLuksSupportInInitrd = true;
kernelModules = [
"dm_mod"
"dm_crypt"
] ++ config.boot.initrd.luks.cryptoModules;
supportedFilesystems = {
btrfs = true;
erofs = true;
};
systemd.enable = true;
systemd.repart.enable = true;
systemd.services.systemd-repart = {
after = lib.mkForce [ "sysroot.mount" ];
requires = [ "sysroot.mount" ];
serviceConfig.Environment = [
"SYSTEMD_REPART_MKFS_OPTIONS_BTRFS=--nodiscard"
];
};
};
system.etc.overlay.mutable = false;
users.mutableUsers = false;
boot.kernelParams = [
"rootfstype=erofs"
"rootflags=ro"
"roothash=${config.system.build.verityRootHash}"
];
fileSystems =
let
parts = config.systemd.repart.partitions;
in
{
"/var" = {
fsType = parts."40-var".Format;
device = "/dev/disk/by-partuuid/${parts."40-var".UUID}";
# FIXME: borked w/systemd 257?
# device = "/dev/mapper/var";
# encrypted = {
# enable = true;
# blkDev = "/dev/disk/by-partuuid/${parts."40-var".UUID}";
# label = "var";
# };
};
};
# Required to mount the efi partition
boot.kernelModules = [
"vfat"
"nls_cp437"
"nls_iso8859-1"
];
environment.etc."machine-id" = {
text = "";
mode = "0755";
};
# Refuse to boot on mount failure
systemd.targets."sysinit".requires = [ "local-fs.target" ];
}

87
modules/image/updater.nix Normal file
View file

@ -0,0 +1,87 @@
{ config, lib, ... }:
{
options.system.image.updates = {
enable = lib.mkEnableOption "system updates via systemd-sysupdate" // {
default = config.system.image.updates.url != null;
};
url = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
};
};
config = lib.mkIf config.system.image.updates.enable {
assertions = [
{ assertion = config.system.image.updates.url != null; }
];
systemd.sysupdate.enable = true;
systemd.sysupdate.reboot.enable = lib.mkDefault true;
systemd.sysupdate.transfers = {
"10-uki" = {
Transfer = {
Verify = "no";
};
Source = {
Type = "url-file";
Path = "${config.system.image.updates.url}";
MatchPattern = "${config.boot.uki.name}_@v.efi";
};
Target = {
Type = "regular-file";
Path = "/EFI/Linux";
PathRelativeTo = "esp";
MatchPattern = "${config.boot.uki.name}_@v+@l-@d.efi ${config.boot.uki.name}_@v+@l.efi ${config.boot.uki.name}_@v.efi";
Mode = "0444";
TriesLeft = 3;
TriesDone = 0;
InstancesMax = 2;
};
};
"20-root-verity" = {
Transfer = {
Verify = "no";
};
Source = {
Type = "url-file";
Path = "${config.system.image.updates.url}";
MatchPattern = "${config.system.image.id}_@v_@u.verity";
};
Target = {
Type = "partition";
Path = "auto";
MatchPattern = "verity-@v";
MatchPartitionType = "root-verity";
ReadOnly = 1;
};
};
"22-root" = {
Transfer = {
Verify = "no";
};
Source = {
Type = "url-file";
Path = "${config.system.image.updates.url}";
MatchPattern = "${config.system.image.id}_@v_@u.root";
};
Target = {
Type = "partition";
Path = "auto";
MatchPattern = "root-@v";
MatchPartitionType = "root";
ReadOnly = 1;
};
};
};
systemd.additionalUpstreamSystemUnits = [
"systemd-bless-boot.service"
"boot-complete.target"
];
};
}

View file

@ -0,0 +1,39 @@
{ config, lib, ... }:
{
options.boot.initrd.systemd.root = lib.mkOption {
type = lib.types.enum [
"fstab"
"gpt-auto"
""
];
};
config.boot.initrd = {
kernelModules = [
"dm_mod"
"dm_verity"
];
systemd = {
# Required to activate systemd-fstab-generator
root = "";
additionalUpstreamUnits = [
"veritysetup-pre.target"
"veritysetup.target"
"remote-veritysetup.target"
];
storePaths = [
"${config.boot.initrd.systemd.package}/lib/systemd/systemd-veritysetup"
"${config.boot.initrd.systemd.package}/lib/systemd/system-generators/systemd-veritysetup-generator"
];
};
};
}

95
modules/profiles/base.nix Normal file
View file

@ -0,0 +1,95 @@
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports = [
(modulesPath + "/profiles/image-based-appliance.nix")
(modulesPath + "/profiles/perlless.nix")
(modulesPath + "/profiles/qemu-guest.nix")
];
# system.forbiddenDependenciesRegexes = lib.mkForce [ ];
nixpkgs.flake.setNixPath = false;
nixpkgs.flake.setFlakeRegistry = false;
boot.enableContainers = false;
boot.kernelModules = [
"zram"
"usb_storage"
"uas"
"sd_mod"
"r8169"
"ehci-hcd"
"ehci-pci"
"xhci-hcd"
"xhci-pci"
"xhci-pci-renesas"
"nvme"
"virtio_net"
];
system.etc.overlay.mutable = lib.mkDefault false;
systemd.watchdog = lib.mkDefault {
runtimeTime = "10s";
rebootTime = "30s";
};
zramSwap.enable = true;
# FIXME: fstrim should only be enabled for virtual machine images?
services.fstrim.enable = true;
users.allowNoPasswordLogin = true;
users.users.root.home = lib.mkForce "/";
security.sudo.enable = lib.mkDefault false;
security.polkit = {
enable = true;
extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
'';
};
i18n.supportedLocales = [ "en_US.UTF-8/UTF-8" ];
# Console
systemd.enableEmergencyMode = false;
boot.consoleLogLevel = lib.mkDefault 1;
boot.kernelParams = [
"panic=1"
"boot.panic_on_fail"
# "nomodeset"
"console=ttyS0,115200n8"
"earlyprintk=ttyS0,115200n8"
"systemd.mask=systemd-vconsole-setup.service" # FIXME: Figure out why vconsole-setup fails when loading keymap
];
# This is vi country
programs.nano.enable = false;
programs.vim.enable = true;
programs.vim.defaultEditor = lib.mkDefault true;
# Temporary file
boot.tmp.useTmpfs = true;
# Logging
services.journald = {
storage = "volatile";
extraConfig = ''
SystemMaxUse=10M
'';
};
}

View file

@ -0,0 +1,39 @@
{
modulesPath,
...
}:
{
imports = [ ./server.nix ];
boot.kernel.sysctl = {
"net.ipv4.ip_unprivileged_port_start" = 0;
};
boot.kernelParams = [
"systemd.log_level=info"
"systemd.log_target=console"
"systemd.journald.forward_to_console"
];
users.users."admin" = {
isNormalUser = true;
linger = true;
extraGroups = [ "wheel" ];
home = "/var/home/admin";
};
environment.etc = {
subuid = {
text = "admin:100000:65536";
mode = "0644";
};
subgid = {
text = "admin:100000:65536";
mode = "0644";
};
};
services.getty.autologinUser = "admin";
}

View file

@ -0,0 +1,65 @@
{ lib, ... }:
{
# Use networkd
networking.useNetworkd = true;
systemd.network.wait-online.enable = true;
# Firewall
networking.firewall.enable = false;
networking.nftables.enable = lib.mkDefault true;
# DNS
services.resolved = {
fallbackDns = [ ]; # Disable fallback DNS. DNS will fail if resolvers are unconfigured
extraConfig = ''
DNSStubListener=no
'';
};
# Configuration
networking.hostName = "";
# Kernel
boot.kernel.sysctl = {
"net.core.default_qdisc" = "fq"; # FIXME: manage these with networkd?
"net.ipv4.tcp_congestion_control" = "bbr";
};
# Modules
boot.kernelModules = [
"ip_tables"
"x_tables"
"nf_tables"
"nft_ct"
"nft_log"
"nf_log_syslog"
"nft_fib"
"nft_fib_inet"
"nft_compat"
"nft_nat"
"nft_chain_nat"
"nft_masq"
"nfnetlink"
"xt_conntrack"
"nf_conntrack"
"nf_log_syslog"
"nf_nat"
"af_packet"
"bridge"
"veth"
"tcp_bbr"
"sch_fq_codel"
"ipt_rpfilter"
"ip6t_rpfilter"
"sch_fq"
"tun"
"tap"
"xt_MASQUERADE"
"xt_mark"
"xt_comment"
"xt_multiport"
"xt_addrtype"
];
}

View file

@ -0,0 +1,18 @@
{
modulesPath,
...
}:
{
imports = [
(modulesPath + "/profiles/minimal.nix")
./network.nix
./sysext.nix
];
boot.kernelParams = [
"quiet"
];
virtualisation.podman.enable = true;
}

View file

@ -0,0 +1,23 @@
{ ... }:
{
system.activationScripts.sysext = ''
mkdir -p /var/lib/confexts
mkdir -p /var/lib/extensions
mkdir -p /etc/systemd/extensions
'';
systemd.additionalUpstreamSystemUnits = [
"systemd-confext.service"
"systemd-sysext.service"
];
# systemd.services."systemd-confext" = {
# enable = true;
# wantedBy = [ "multi-user.target" ];
# };
# systemd.services."systemd-sysext.service" = {
# enable = true;
# wantedBy = [ "multi-user.target" ];
# };
}

View file

@ -1,37 +0,0 @@
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

View file

@ -1,208 +0,0 @@
{
stdenv,
lib,
pkgs,
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 = 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 = pkgs.busybox.src;
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 "/usr/share/busybox/"
${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" ];
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
};
}

View file

@ -1,17 +0,0 @@
{
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"
''

5
pkgs/composefs.nix Normal file
View file

@ -0,0 +1,5 @@
{ prev, ... }:
prev.composefs.overrideAttrs (final: prev: {
doCheck = false;
})

View file

@ -1,164 +0,0 @@
{
lib,
stdenv,
fetchFromGitHub,
pkgs,
...
}:
let
meta = {
maintainers = with lib.maintainers; [ peterhoeg ];
platforms = lib.platforms.linux;
};
dep =
{
pname,
version,
hash,
rev ? "v${version}",
buildInputs ? [ ],
}:
stdenv.mkDerivation {
inherit pname version;
src = fetchFromGitHub {
owner = "c-util";
repo = pname;
inherit hash rev;
};
nativeBuildInputs = with pkgs; [
meson
ninja
pkg-config
];
inherit buildInputs;
meta = meta // {
description = "The C-Util Project is a collection of utility libraries for the C11 language.";
homepage = "https://c-util.github.io/";
license = [
lib.licenses.asl20
lib.licenses.lgpl21Plus
];
};
};
# These libraries are not used outside of dbus-broker.
#
# If that changes, we can always break them out, but they are essentially
# part of the dbus-broker project, just in separate repositories.
c-dvar = dep {
pname = "c-dvar";
version = "1.1.0";
hash = "sha256-p/C+BktclVseCtZJ1Q/YK03vP2ClnYRLB1Vmj2OQJD4=";
buildInputs = [
c-stdaux
c-utf8
];
};
c-ini = dep {
pname = "c-ini";
version = "1.1.0";
hash = "sha256-wa7aNl20hkb/83c4AkQ/0YFDdmBs4XGW+WLUtBWIC98=";
buildInputs = [
c-list
c-rbtree
c-stdaux
c-utf8
];
};
c-list = dep {
pname = "c-list";
version = "3.1.0";
hash = "sha256-fp3EAqcbFCLaT2EstLSzwP2X13pi2EFpFAullhoCtpw=";
};
c-rbtree = dep {
pname = "c-rbtree";
version = "3.2.0";
hash = "sha256-dTMeawhPLRtHvMXfXCrT5iCdoh7qS3v+raC6c+t+X38=";
buildInputs = [ c-stdaux ];
};
c-shquote = dep {
pname = "c-shquote";
version = "1.1.0";
hash = "sha256-z6hpQ/kpCYAngMNfxLkfsxaGtvP4yBMigX1lGpIIzMQ=";
buildInputs = [ c-stdaux ];
};
c-stdaux = dep {
pname = "c-stdaux";
version = "1.5.0";
hash = "sha256-MsnuEyVCmOIr/q6I1qyPsNXp48jxIEcXoYLHbOAZtW0=";
};
c-utf8 = dep {
pname = "c-utf8";
version = "1.1.0";
hash = "sha256-9vBYylbt1ypJwIAQJd/oiAueh+4VYcn/KzofQuhUea0=";
buildInputs = [ c-stdaux ];
};
in
stdenv.mkDerivation (finalAttrs: {
pname = "dbus-broker";
version = pkgs.dbus-broker.version;
src = pkgs.dbus-broker.src;
nativeBuildInputs = with pkgs; [
docutils
meson
ninja
pkg-config
];
buildInputs = [
c-dvar
c-ini
c-list
c-rbtree
c-shquote
c-stdaux
c-utf8
pkgs.dbus
pkgs.linuxHeaders
pkgs.systemd
];
mesonFlags = [
# while we technically support 4.9 and 4.14, the NixOS module will throw an
# error when using a kernel that's too old
"--prefix=/"
"--bindir=/usr/bin"
"-D=linux-4-17=true"
"-D=system-console-users=gdm,sddm,lightdm"
];
PKG_CONFIG_SYSTEMD_SYSTEMDSYSTEMUNITDIR = "/usr/lib/systemd/system";
PKG_CONFIG_SYSTEMD_SYSTEMDUSERUNITDIR = "/usr/lib/systemd/user";
PKG_CONFIG_SYSTEMD_CATALOGDIR = "/usr/lib/systemd/catalog";
preInstall = ''
export DESTDIR=${placeholder "out"}
'';
postInstall = ''
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
mkdir -p $out/usr/lib/sysusers.d/
echo 'u! messagebus - "DBus broker"' > $out/usr/lib/sysusers.d/dbus-broker.conf
'';
doCheck = false;
meta = meta // {
description = "Linux D-Bus Message Broker";
homepage = "https://github.com/bus1/dbus-broker/wiki";
license = lib.licenses.asl20;
};
})

View file

@ -1,53 +0,0 @@
{
pkgs,
stdenv,
...
}:
let
version = pkgs.glibc.version;
src = pkgs.glibc.src;
pname = "glibcPatos";
in
stdenv.mkDerivation (finalAttrs: {
inherit version;
inherit src;
inherit pname;
enableParallelBuilding = true;
dontPatchShebangs = true;
configureFlags = [
"--prefix=/"
"--libdir=/lib"
"--bindir=/bin"
"--sysconfdir=/etc"
];
preConfigure =
''
export PWD_P=$(type -tP pwd)
for i in configure io/ftwtest-sh; do
sed -i "$i" -e "s^/bin/pwd^$PWD_P^g"
done
mkdir ../build
cd ../build
configureScript="`pwd`/../$sourceRoot/configure"
'';
nativeBuildInputs = with pkgs; [
bison
python3Minimal
];
outputs = [
"out"
];
preInstall = ''
export DESTDIR=${placeholder "out"}
'';
})

View file

@ -1,256 +0,0 @@
{
lib,
pkgs,
patosPkgs,
version,
runCommand,
updateUrl,
cpuArch ? "",
secureBoot ? "false"
}:
let
pname = "patos-image";
in
runCommand pname {
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
dosfstools
mtools
jq
];
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";
};
kernelCmdLine = "console=ttyS0 patos.secureboot=${secureBoot}";
}
''
mkdir -p $out/init.repart.d $out/final.repart.d
pushd $out
mkdir rootfs
cp -prP ${patosPkgs.rootfs}/* rootfs/
find rootfs/ -type d -exec chmod 755 {} \;
# 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
# 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
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
# 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-verity.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]
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)
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 \
$microcode \
--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
# 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
echo "timeout 2" > rootfs/boot/loader/loader.conf
# install UKI
cp patos_${version}.efi rootfs/boot/EFI/Linux
# Final partitioning
cat <<EOF > final.repart.d/10-esp.conf
[Partition]
Type=esp
Format=vfat
SizeMinBytes=128M
SizeMaxBytes=128M
CopyFiles=/rootfs/boot:/
EOF
cat <<EOF > final.repart.d/20-root.conf
[Partition]
Type=root
Label=root-${version}
CopyBlocks=/$rootPart
UUID=$rootUuid
SizeMinBytes=64M
SizeMaxBytes=64M
ReadOnly=1
EOF
cat <<EOF > final.repart.d/22-root-verity.conf
[Partition]
Type=root-verity
Label=verity-${version}
CopyBlocks=/$verityPart
UUID=$verityUuid
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}.img > final-repart-output.json
rm -rf rootfs init.repart.d final.repart.d *.json
sha256sum *.root *.verity *.efi *.tar.xz > SHA256SUMS
popd
''

View file

@ -1,15 +0,0 @@
{ pkgs }:
let
version = "6.14.2";
hash = "sha256-xcaCo1TqMZATk1elfTSnnlw3IhrOgjqTjhARa1d6Lhs=";
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;
}

File diff suppressed because it is too large Load diff

View file

@ -1,594 +0,0 @@
{
lib,
stdenv,
buildPackages,
runCommand,
nettools,
bc,
bison,
flex,
perl,
rsync,
gmp,
libmpc,
mpfr,
openssl,
cpio,
elfutils,
hexdump,
zstd,
python3Minimal,
zlib,
pahole,
kmod,
ubootTools,
erofs-utils,
cryptsetup,
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
erofs-utils
cryptsetup
]
++ 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
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" ];
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; })
]
)
)

View file

@ -1,62 +0,0 @@
{
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;
};
}

12
pkgs/linux-firmware.nix Normal file
View file

@ -0,0 +1,12 @@
{ stdenv, lib
, linux-firmware
, fwDirs
}: stdenv.mkDerivation {
pname = "linux-firmware-minimal";
version = linux-firmware.version;
buildCommand = lib.concatStringsSep "\n" (
[''mkdir -p "$out/lib/firmware"'']
++ (map (name: ''
cp -r "${linux-firmware}/lib/firmware/${name}" "$out/lib/firmware/${name}"
'') fwDirs));
}

View file

@ -1,61 +0,0 @@
{
stdenv,
pkgs,
fetchurl,
lib,
pkg-config,
libaio,
udev,
}:
stdenv.mkDerivation {
pname = "lvm2";
version = pkgs.lvm2.version;
src = pkgs.lvm2.src;
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
];
};
}

View file

@ -1,164 +0,0 @@
{
lib,
pkgs,
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 = pkgs.openssl.version;
src = pkgs.openssl.src;
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=/"
"--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
rm -rf $out/etc/ssl/*.dist $out/etc/ssl/misc
'';
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;
};
}

30
pkgs/qemu.nix Normal file
View file

@ -0,0 +1,30 @@
{ prev, pkgs, ... }:
(prev.qemu_test.override {
enableDocs = false;
capstoneSupport = false;
guestAgentSupport = false;
tpmSupport = false;
libiscsiSupport = false;
usbredirSupport = false;
canokeySupport = false;
hostCpuTargets = [ "x86_64-softmmu" ];
}).overrideDerivation (old: {
postFixup = ''
rm -r "$out/share/icons"
cp "${pkgs.OVMF.fd + "/FV/OVMF.fd"}" "$out/share/qemu/"
'';
configureFlags = old.configureFlags ++ [
"--disable-tcg"
"--disable-tcg-interpreter"
"--disable-docs"
"--disable-install-blobs"
"--disable-slirp"
"--disable-virtfs"
"--disable-virtfs-proxy-helper"
"--disable-vhost-user-blk-server"
"--without-default-features"
"--enable-kvm"
"--disable-tools"
];
})

View file

@ -1,93 +0,0 @@
{
pkgs,
patosPkgs,
runCommand,
...
}:
let
secureBootEnroll = ./secure-boot-enroll.sh;
in
runCommand "patos-initrd" {
inherit secureBootEnroll;
buildInputs = with pkgs; [
cpio
xz
];
}
''
echo "Building initram disk"
mkdir -p $out/root
pushd $out/root
### copy rootfs
cp -prP ${patosPkgs.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
# setup secure boot
cat $secureBootEnroll > ./usr/bin/secure-boot-enroll
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
ConditionKernelCommandLine=patos.secureboot=true
ConditionPathExists=|!/sys/firmware/efi/efivars/PK-8be4df61-93ca-11d2-aa0d-00e098032b8c
[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]
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
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
popd
rm -rf $out/root
''

View file

@ -1,230 +0,0 @@
{
pkgs,
patosPkgs,
version,
runCommand,
}:
let
defaultPassword = "patos";
in
runCommand "patos-rootfs"
{
inherit version;
buildInputs = with pkgs;[
glibc
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
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
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
ln -s /run/systemd/resolve/stub-resolv.conf $out/etc/resolv.conf
cat <<EOF > $out/etc/os-release
NAME=PatOS
PRETTY_NAME=PatOS v${version} (Pre-Alpha)
IMAGE_ID=patos
ID=patos
IMAGE_VERSION=${version}
VERSION=${version}
VERSION_ID=patos
BUILD_ID=somehash
EOF
cat <<EOF > $out/etc/issue
<<< Welcome to PatOS v${version} (Pre-Alpha) (\m) - \l >>>
EOF
# 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=-/bin/login -f root
EOF
# ExecStart=-/sbin/getty -L %I 115200 vt100
# Configure systemd-repart
cat <<EOF > $out/etc/repart.d/10-esp.conf
[Partition]
Type=esp
Format=vfat
SizeMaxBytes=128M
SizeMinBytes=128M
EOF
cat <<EOF > $out/etc/repart.d/20-root-a.conf
[Partition]
Type=root
SizeMaxBytes=64M
SizeMinBytes=64M
EOF
cat <<EOF > $out/etc/repart.d/22-root-verify-a.conf
[Partition]
Type=root-verity
EOF
cat <<EOF > $out/etc/repart.d/30-root-b.conf
[Partition]
Type=root
Label=_empty
SizeMaxBytes=64M
SizeMinBytes=64M
ReadOnly=1
EOF
cat <<EOF > $out/etc/repart.d/32-root-verity-b.conf
[Partition]
Type=root-verity
Label=_empty
ReadOnly=1
EOF
cat <<EOF > $out/etc/repart.d/40-var.conf
[Partition]
Type=var
Format=btrfs
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/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
FactoryReset=yes
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 in initrd)
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
### install PatOS glibc
cp -P ${patosPkgs.glibc}/lib/*.so* $out/usr/lib/
### install openssl
cp -P ${patosPkgs.openssl}/lib/*.so* $out/usr/lib/
cp -Pr ${patosPkgs.openssl}/etc/ssl $out/etc/
### install busybox
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 ${patosPkgs.dbus-broker}/* $out/
### install kexec
cp -Pr ${patosPkgs.kexec}/sbin/kexec $out/usr/bin/
### install dmsetup udev rules
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 ${pkgs.btrfs-progs}/bin/* $out/usr/bin/
cp -Pr ${pkgs.btrfs-progs}/lib/* $out/usr/lib/
### install tpm2 libs
cp -P ${patosPkgs.tpm2-tss}/lib/*.so* $out/usr/lib/
### install lib kmod
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/
### 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/
### 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
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
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$' ${patosPkgs.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
### Find and install all shared libs
find $out -type f -executable -exec ldd {} \; | awk '{print $3}' | \
grep -vE "(systemd|glibc|openssl|tpm2|devmapper)" | \
sort -u | xargs -I {} cp {} $out/usr/lib/
find $out -type f -executable -exec chmod 755 {} \;
# 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
# strip binaries
find $out -type f -executable -exec strip {} \;
find $out -type d -exec chmod 755 {} \;
# install kernel modules
cp -r ${patosPkgs.kernel}/lib/modules $out/usr/lib/
find $out/usr/lib/modules -type d -exec chmod 755 {} \;
''

View file

@ -1,23 +0,0 @@
#!/bin/sh
set -ex -uo pipefail
SETUP_MODE=$(sbctl status --json | jq -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

48
pkgs/systemd-ukify.nix Normal file
View file

@ -0,0 +1,48 @@
{ prev, ... }:
prev.systemd.override {
withAcl = false;
withAnalyze = false;
withApparmor = false;
withAudit = false;
withEfi = true;
withCompression = false;
withCoredump = false;
withCryptsetup = false;
withRepart = false;
withDocumentation = false;
withFido2 = false;
withFirstboot = false;
withHomed = false;
withHostnamed = false;
withHwdb = false;
withImportd = false;
withIptables = false;
withKmod = false;
withLibBPF = false;
withLibidn2 = false;
withLocaled = false;
withLogind = false;
withMachined = false;
withNetworkd = false;
withNss = false;
withOomd = false;
withPam = false;
withPasswordQuality = false;
withPCRE2 = false;
withPolkit = false;
withPortabled = false;
withQrencode = false;
withRemote = false;
withResolved = false;
withShellCompletions = false;
withSysusers = false;
withSysupdate = false;
withTimedated = false;
withTimesyncd = false;
withTpm2Tss = false;
withUkify = true;
withUserDb = false;
withUtmp = false;
withVmspawn = false;
}

10
pkgs/systemd.nix Normal file
View file

@ -0,0 +1,10 @@
{ prev, ... }:
prev.systemd.override {
withAcl = false;
withApparmor = false;
withDocumentation = false;
withRemote = false;
withShellCompletions = false;
withVmspawn = false;
}

View file

@ -1,323 +0,0 @@
{
fetchFromGitHub,
lib,
pkgs,
stdenv,
targetPackages,
...
}:
let
version = "257.5";
# Use the command below to update `releaseTimestamp` on every (major) version
# change. More details in the commentary at mesonFlags.
# command:
# $ curl -s https://api.github.com/repos/systemd/systemd/releases/latest | \
# jq '.created_at|strptime("%Y-%m-%dT%H:%M:%SZ")|mktime'
releaseTimestamp = "1734643670";
pname = "systemd";
in
stdenv.mkDerivation (finalAttrs: {
inherit version;
pname = pname;
src = fetchFromGitHub {
owner = "systemd";
repo = "systemd";
rev = "v${version}";
hash = "sha256-6rxJUYRq785U6aik5VhQRqG+Ss67lBB6T3eQF+tkyhk=";
};
patches = [ ./skip-verify-esp.patch ];
dontCheckForBrokenSymlinks = true;
nativeBuildInputs = with pkgs; [
bash
pkg-config
makeBinaryWrapper
gperf
ninja
meson
glibcLocales
getent
m4
autoPatchelfHook
intltool
gettext
libxslt
docbook_xsl
docbook_xml_dtd_42
docbook_xml_dtd_45
bash
(buildPackages.python3Packages.python.withPackages (
ps: with ps; [
lxml
jinja2
ps.pyelftools
]
))
bpftools
buildPackages.llvmPackages.clang
buildPackages.llvmPackages.libllvm
];
outputs = [
"out"
"dev"
];
separateDebugInfo = true;
autoPatchelfFlags = [ "--keep-libc" ];
hardeningDisable = [
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111523
"trivialautovarinit"
# breaks clang -target bpf; should be fixed to filter target?
"zerocallusedregs"
"shadowstack"
];
buildInputs = with pkgs; [
libxcrypt
libcap
libuuid
linuxHeaders
bashInteractive # for patch shebangs
libgcrypt
libgpg-error
openssl
acl
libapparmor
audit
zlib
bzip2
lz4
xz
zstd
elfutils
kexec-tools
kmod
libidn2
libseccomp
libselinux
iptables
p11-kit
libfido2
pam
pcre2
libbpf
tpm2-tss
qrencode
libarchive
(lib.getDev curl)
(lib.getDev cryptsetup.dev)
(python3Packages.python.withPackages (ps: with ps; [ pefile ]))
(llvmPackages.compiler-rt.override {
doFakeLibgcc = true;
})
];
mesonBuildType = "release";
doCheck = false; # fails a bunch of tests
preConfigure = ''
mesonFlagsArray+=(-Dntp-servers="0.europe.pool.ntp.org 1.europe.pool.ntp.org 2.europe.pool.ntp.org 3.europe.pool.ntp.org")
export LC_ALL="en_US.UTF-8";
'';
postPatch =
''
substituteInPlace meson.build \
--replace "find_program('clang'" "find_program('${stdenv.cc.targetPrefix}clang'"
''
+ ''
substituteInPlace src/ukify/ukify.py \
--replace \
"'readelf'" \
"'${targetPackages.stdenv.cc.bintools.targetPrefix}readelf'" \
--replace \
"/usr/lib/systemd/boot/efi" \
"$out/usr/lib/systemd/boot/efi"
''
# Finally, patch shebangs in scripts used at build time. This must not patch
# scripts that will end up in the output, to avoid build platform references
# when cross-compiling.
+ ''
shopt -s extglob
patchShebangs tools test src/!(rpm|kernel-install|ukify) src/kernel-install/test-kernel-install.sh
'';
# trigger the test -n "$DESTDIR" || mutate in upstreams build system
preInstall = ''
export DESTDIR=${placeholder "out"}
'';
mesonFlags = [
"--prefix=/usr"
"--sysconfdir=/etc"
"--localstatedir=/var"
"--libdir=/usr/lib"
"--bindir=/usr/bin"
"--includedir=/usr/include"
"--localedir=/usr/share/locale"
# Options
# We bump this attribute on every (major) version change to ensure that we
# have known-good value for a timestamp that is in the (not so distant)
# past. This serves as a lower bound for valid system timestamps during
# startup. Systemd will reset the system timestamp if this date is +- 15
# years from the system time.
# See the systemd v250 release notes for further details:
# https://github.com/systemd/systemd/blob/60e930fc3e6eb8a36fbc184773119eb8d2f30364/NEWS#L258-L266
(lib.mesonOption "time-epoch" releaseTimestamp)
(lib.mesonOption "version-tag" version)
(lib.mesonOption "mode" "release")
(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")
(lib.mesonOption "dbuspolicydir" "/usr/share/dbus-1/system.d")
(lib.mesonOption "dbussessionservicedir" "/usr/share/dbus-1/services")
(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 "nologin-path" "/usr/bin/nologin")
(lib.mesonOption "mount-path" "/usr/bin/mount")
(lib.mesonOption "umount-path" "/usr/bin/umount")
# SBAT
(lib.mesonOption "sbat-distro" "patos")
(lib.mesonOption "sbat-distro-summary" "PatOS")
(lib.mesonOption "sbat-distro-url" "https://patagia.io/")
(lib.mesonOption "sbat-distro-pkgname" pname)
(lib.mesonOption "sbat-distro-version" version)
# Users
(lib.mesonOption "system-uid-max" "999")
(lib.mesonOption "system-gid-max" "999")
# SysVinit
(lib.mesonOption "sysvinit-path" "")
(lib.mesonOption "sysvrcnd-path" "")
# SSH
# Disabled for now until someone makes this work.
(lib.mesonOption "sshconfdir" "no")
(lib.mesonOption "sshdconfdir" "no")
# Features
# Tests
(lib.mesonBool "tests" false)
(lib.mesonEnable "glib" false)
(lib.mesonEnable "dbus" false)
# Compression
(lib.mesonEnable "bzip2" true)
(lib.mesonEnable "lz4" true)
(lib.mesonEnable "xz" true)
(lib.mesonEnable "zstd" true)
(lib.mesonEnable "zlib" true)
# NSS
(lib.mesonEnable "nss-resolve" true)
(lib.mesonBool "nss-myhostname" true)
(lib.mesonBool "nss-systemd" true)
# Cryptsetup
(lib.mesonEnable "libcryptsetup" true)
(lib.mesonEnable "libcryptsetup-plugins" true)
(lib.mesonEnable "p11kit" true)
# FIDO2
(lib.mesonEnable "libfido2" true)
(lib.mesonEnable "openssl" true)
# Password Quality
(lib.mesonEnable "pwquality" false)
(lib.mesonEnable "passwdqc" false)
# Remote
(lib.mesonEnable "remote" false)
(lib.mesonEnable "microhttpd" false)
(lib.mesonEnable "pam" false)
(lib.mesonEnable "acl" true)
(lib.mesonEnable "audit" true)
(lib.mesonEnable "apparmor" true)
(lib.mesonEnable "gcrypt" true)
(lib.mesonEnable "importd" true)
(lib.mesonEnable "homed" false)
(lib.mesonEnable "polkit" true)
(lib.mesonEnable "elfutils" true)
(lib.mesonEnable "libcurl" true)
(lib.mesonEnable "libidn" false)
(lib.mesonEnable "libidn2" true)
(lib.mesonEnable "libiptc" true)
(lib.mesonEnable "repart" true)
(lib.mesonEnable "sysupdate" true)
(lib.mesonEnable "sysupdated" true)
(lib.mesonEnable "seccomp" true)
(lib.mesonEnable "selinux" true)
(lib.mesonEnable "tpm2" true)
(lib.mesonEnable "pcre2" true)
(lib.mesonEnable "bpf-framework" true)
(lib.mesonEnable "bootloader" true)
(lib.mesonEnable "ukify" true)
(lib.mesonEnable "kmod" true)
(lib.mesonEnable "qrencode" true)
(lib.mesonEnable "vmspawn" false)
(lib.mesonEnable "libarchive" true)
(lib.mesonEnable "xenctrl" false)
(lib.mesonEnable "gnutls" false)
(lib.mesonEnable "xkbcommon" false)
(lib.mesonEnable "man" false)
(lib.mesonBool "analyze" true)
(lib.mesonBool "logind" false)
(lib.mesonBool "localed" false)
(lib.mesonBool "hostnamed" true)
(lib.mesonBool "machined" true)
(lib.mesonBool "networkd" true)
(lib.mesonBool "oomd" true)
(lib.mesonBool "portabled" true)
(lib.mesonBool "hwdb" true)
(lib.mesonBool "timedated" true)
(lib.mesonBool "timesyncd" true)
(lib.mesonBool "userdb" false)
(lib.mesonBool "coredump" true)
(lib.mesonBool "firstboot" true)
(lib.mesonBool "resolve" true)
(lib.mesonBool "sysusers" true)
(lib.mesonBool "efi" true)
(lib.mesonBool "utmp" true)
(lib.mesonBool "log-trace" true)
(lib.mesonBool "kernel-install" false)
(lib.mesonBool "quotacheck" false)
(lib.mesonBool "ldconfig" false)
(lib.mesonBool "install-sysconfdir" true)
(lib.mesonBool "create-log-dirs" true)
(lib.mesonBool "smack" true)
(lib.mesonBool "b_pie" true)
(lib.mesonOption "bashcompletiondir" "no")
(lib.mesonOption "zshcompletiondir" "no")
];
})

View file

@ -1,24 +0,0 @@
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),

View file

@ -1,47 +0,0 @@
{
stdenv,
pkgs,
fetchurl,
lib,
pandoc,
pkg-config,
curl,
openssl,
patosPkgs,
libuuid,
}:
stdenv.mkDerivation {
pname = "tpm2-tools";
version = pkgs.tpm2-tools.version;
src = pkgs.tpm2-tools.src;
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 ];
};
}

View file

@ -1,82 +0,0 @@
{
stdenv,
pkgs,
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 = pkgs.tpm2-tss.version;
src = pkgs.tpm2-tss.src;
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 ];
};
}

View file

@ -1,16 +0,0 @@
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])

155
tests/common.nix Normal file
View file

@ -0,0 +1,155 @@
{
self,
lib,
pkgs,
...
}:
with import (pkgs.path + "/nixos/lib/testing-python.nix") {
inherit pkgs;
inherit (pkgs.hostPlatform) system;
};
let
qemu-common = import (pkgs.path + "/nixos/lib/qemu-common.nix") { inherit lib pkgs; };
in
rec {
makeSystem =
extraConfig:
(import (pkgs.path + "/nixos/lib/eval-config.nix")) {
inherit pkgs lib;
system = null;
modules = [
{
nixpkgs.hostPlatform = pkgs.hostPlatform;
}
{
users.allowNoPasswordLogin = true;
system.stateVersion = lib.versions.majorMinor lib.version;
system.image.id = lib.mkDefault "test";
system.image.version = lib.mkDefault "1";
networking.hosts."10.0.2.1" = [ "server.test" ];
}
{
boot.kernelParams = [
"console=ttyS0,115200n8"
"systemd.journald.forward_to_console=1"
];
image.compress = false;
boot.uki.name = lib.mkForce "test";
boot.initrd.compressor = lib.mkForce "zstd";
boot.initrd.compressorArgs = lib.mkForce [ "-8" ];
}
(pkgs.path + "/nixos/modules/testing/test-instrumentation.nix")
self.nixosModules.devel
self.nixosModules.image
extraConfig
];
};
makeImage =
extraConfig:
let
system = makeSystem extraConfig;
in
"${system.config.system.build.image}/${system.config.system.build.image.imageFile}";
makeUpdatePackage =
extraConfig:
let
system = makeSystem extraConfig;
in
"${system.config.system.build.updatePackage}";
makeImageTest =
{
name,
image,
script,
httpRoot ? null,
}:
let
qemu = qemu-common.qemuBinary pkgs.qemu_test;
flags = [
"-m"
"512M"
"-drive"
"if=pflash,format=raw,unit=0,readonly=on,file=${pkgs.OVMF.firmware}"
"-drive"
"if=pflash,format=raw,unit=1,readonly=on,file=${pkgs.OVMF.variables}"
"-drive"
"if=virtio,file=${mutableImage}"
"-chardev"
"socket,id=chrtpm,path=${tpmFolder}/swtpm-sock"
"-tpmdev"
"emulator,id=tpm0,chardev=chrtpm"
"-device"
"tpm-tis,tpmdev=tpm0"
"-netdev"
(
"'user,id=net0"
+ (lib.optionalString (
httpRoot != null
) ",guestfwd=tcp:10.0.2.1:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${httpRoot}")
+ "'"
)
"-device"
"virtio-net-pci,netdev=net0"
];
flagsStr = lib.concatStringsSep " " flags;
startCommand = "${qemu} ${flagsStr}";
mutableImage = "/tmp/linked-image.qcow2";
tpmFolder = "/tmp/emulated_tpm";
indentLines = str: lib.concatLines (map (s: " " + s) (lib.splitString "\n" str));
in
makeTest {
inherit name;
nodes = { };
testScript =
''
import os
import subprocess
subprocess.check_call(
[
"qemu-img",
"create",
"-f",
"qcow2",
"-F",
"raw",
"-b",
"${image}",
"${mutableImage}",
]
)
subprocess.check_call(["qemu-img", "resize", "${mutableImage}", "4G"])
os.mkdir("${tpmFolder}")
os.mkdir("${tpmFolder}/swtpm")
def start_tpm():
subprocess.Popen(
[
"${pkgs.swtpm}/bin/swtpm",
"socket",
"--tpmstate", "dir=${tpmFolder}/swtpm",
"--ctrl", "type=unixio,path=${tpmFolder}/swtpm-sock",
"--tpm2"
]
)
machine = create_machine("${startCommand}")
try:
''
+ indentLines script
+ ''
finally:
machine.shutdown()
'';
};
}

9
tests/lib.nix Normal file
View file

@ -0,0 +1,9 @@
test:
{ pkgs, self }:
let nixos-lib = import (pkgs.path + "/nixos/lib") {};
in (nixos-lib.runTest {
hostPkgs = pkgs;
defaults.documentation.enable = false;
node.specialArgs = { inherit self; };
imports = [ test ];
}).config.result

22
tests/podman.nix Normal file
View file

@ -0,0 +1,22 @@
{ pkgs, self }: let
lib = pkgs.lib;
test-common = import ./common.nix { inherit self lib pkgs; };
image = test-common.makeImage { };
in test-common.makeImageTest {
name = "podman";
inherit image;
script = ''
start_tpm()
machine.start()
machine.wait_for_unit("multi-user.target")
machine.wait_for_unit("network-online.target")
machine.succeed("tar cv --files-from /dev/null | su admin -l -c 'podman import - scratchimg'")
machine.succeed("su admin -l -c 'podman run --rm -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg true'")
'';
}

45
tests/system-update.nix Normal file
View file

@ -0,0 +1,45 @@
{ pkgs, self }: let
lib = pkgs.lib;
test-common = import ./common.nix { inherit self lib pkgs; };
initialImage = test-common.makeImage {
system.image.version = "1";
system.image.updates.url = "http://server.test/";
# The default root-b is too small for uncompressed test images
systemd.repart.partitions."32-root-b" = {
SizeMinBytes = lib.mkForce "1G";
SizeMaxBytes = lib.mkForce "1G";
};
};
updatePackage = test-common.makeUpdatePackage {
system.image.version = "2";
system.image.updates.url = "http://server.test/";
};
in test-common.makeImageTest {
name = "system-update";
image = initialImage;
httpRoot = updatePackage;
script = ''
start_tpm()
machine.start()
machine.wait_for_unit("multi-user.target")
machine.wait_for_unit("network-online.target")
machine.succeed("/run/current-system/sw/lib/systemd/systemd-sysupdate update")
machine.shutdown()
start_tpm()
machine.start()
machine.wait_for_unit("multi-user.target")
machine.succeed('. /etc/os-release; [ "$IMAGE_VERSION" == "2" ]')
machine.wait_for_unit("systemd-bless-boot.service")
'';
}

View file

@ -1,4 +1,5 @@
{
config,
pkgs,
...
}:
@ -12,25 +13,19 @@ pkgs.writeShellApplication {
text =
let
tpmOVMF = pkgs.OVMF.override {
tpmSupport = true;
secureBoot = true;
};
tpmOVMF = pkgs.OVMF.override { tpmSupport = true; };
in
''
set -ex
state="/tmp/patos-qemu-$USER"
rm -rf "$state"
mkdir -m 700 "$state"
qemu-img create -f qcow2 -F raw -b "$(readlink -e "$1")" "$state/disk.qcow2" 2G
qemu-img create -f qcow2 -F raw -b "$(readlink -e "$1")" "$state/disk.qcow2" 10G
swtpm socket -d --tpmstate dir="$state" \
--ctrl type=unixio,path="$state/swtpm-sock" \
--tpm2 \
--log file="$state/swtpm.log",level=20
cp ${tpmOVMF.variables} "$state"
chmod 700 "$state/OVMF_VARS.fd"
--log level=20
qemu-system-x86_64 \
-enable-kvm \
@ -43,11 +38,11 @@ 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,file=$state/OVMF_VARS.fd" \
-drive "if=pflash,format=raw,unit=1,readonly=on,file=${tpmOVMF.variables}" \
-chardev socket,id=chrtpm,path="$state/swtpm-sock" \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis,tpmdev=tpm0 \
-netdev id=net00,type=user \
-netdev id=net00,type=user,hostfwd=tcp::2222-:22 \
-device virtio-net-pci,netdev=net00 \
-drive "format=qcow2,file=$state/disk.qcow2"
'';