diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index c9e5123743be..ba8317e9c660 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -127,6 +127,11 @@ - `zammad` has had its support for MySQL removed, since it was never working correctly and is now deprecated upstream. Check the [migration guide](https://docs.zammad.org/en/latest/appendix/migrate-to-postgresql.html) for how to convert your database to PostgreSQL. +- The `earlyoom` service is now using upstream systemd service, which enables + hardening and filesystem isolation by default. If you need filesystem write + access or want to access home directory via `killHook`, hardening setting can + be changed via, e.g. `systemd.services.earlyoom.serviceConfig.ProtectSystem`. + - `nodePackages.vls` has been deprecated, as the upstream consumer of it, vetur, has been deprecated by upstream. Upstream suggests migrating to Volar for Vue LSP tooling instead. - `nodePackages.create-react-native-app` has been removed, as it is deprecated. Upstream suggests using a framework for React Native apps instead. diff --git a/nixos/modules/services/system/earlyoom.nix b/nixos/modules/services/system/earlyoom.nix index 7e012dee02cb..adf754c6abd6 100644 --- a/nixos/modules/services/system/earlyoom.nix +++ b/nixos/modules/services/system/earlyoom.nix @@ -115,6 +115,11 @@ in [README](https://github.com/rfjakob/earlyoom#notifications) and [the man page](https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#-n-pathtoscript) for details. + + WARNING: earlyoom is running in a sandbox with ProtectSystem="strict" + by default, so filesystem write is also prohibited for the hook. + If you want to change these protection rules, override the systemd + service via `systemd.services.earlyoom.serviceConfig.ProtectSystem`. ''; }; @@ -149,25 +154,33 @@ in config = mkIf cfg.enable { services.systembus-notify.enable = mkDefault cfg.enableNotifications; + systemd.packages = [ cfg.package ]; + systemd.services.earlyoom = { - description = "Early OOM Daemon for Linux"; + overrideStrategy = "asDropin"; + wantedBy = [ "multi-user.target" ]; path = optionals cfg.enableNotifications [ pkgs.dbus ]; - serviceConfig = { - StandardError = "journal"; - ExecStart = concatStringsSep " " ([ - "${lib.getExe cfg.package}" - ("-m ${toString cfg.freeMemThreshold}" - + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}") - ("-s ${toString cfg.freeSwapThreshold}" - + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}") - "-r ${toString cfg.reportInterval}" - ] - ++ optionals cfg.enableDebugInfo [ "-d" ] - ++ optionals cfg.enableNotifications [ "-n" ] - ++ optionals (cfg.killHook != null) [ "-N ${escapeShellArg cfg.killHook}" ] - ++ cfg.extraArgs); - }; + + # We setup `EARLYOOM_ARGS` via drop-ins, so disable the default import + # from /etc/default/earlyoom. + serviceConfig.EnvironmentFile = ""; + + environment.EARLYOOM_ARGS = + lib.cli.toGNUCommandLineShell { } { + m = + "${toString cfg.freeMemThreshold}" + + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}"; + s = + "${toString cfg.freeSwapThreshold}" + + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}"; + r = "${toString cfg.reportInterval}"; + d = cfg.enableDebugInfo; + n = cfg.enableNotifications; + N = if cfg.killHook != null then cfg.killHook else null; + } + + " " + + lib.escapeShellArgs cfg.extraArgs; }; }; } diff --git a/pkgs/by-name/ea/earlyoom/package.nix b/pkgs/by-name/ea/earlyoom/package.nix index fead6ff586e0..ed3f0006b466 100644 --- a/pkgs/by-name/ea/earlyoom/package.nix +++ b/pkgs/by-name/ea/earlyoom/package.nix @@ -1,11 +1,13 @@ { lib, fetchFromGitHub, - installShellFiles, pandoc, stdenv, nixosTests, - # Boolean flags + fetchpatch, + # The man page requires pandoc to build and resides in a separate "man" + # output which is pulled in on-demand. There is no need to disabled it unless + # pandoc is hard to build on your platform. withManpage ? true, }: @@ -22,25 +24,26 @@ stdenv.mkDerivation (finalAttrs: { outputs = [ "out" ] ++ lib.optionals withManpage [ "man" ]; - patches = [ ./0000-fix-dbus-path.patch ]; - - nativeBuildInputs = lib.optionals withManpage [ - installShellFiles - pandoc + patches = [ + ./0000-fix-dbus-path.patch + # Respect `MANDIR`. + (fetchpatch { + url = "https://github.com/rfjakob/earlyoom/commit/c5a1799a5ff4b3fd3132d50a510e8c126933cf4a.patch"; + hash = "sha256-64AkpTMmjiqZ6Byq6687zNIqrQ/IGRGgzzjyyAfcg14="; + }) + # Correctly handle `PREFIX` as a default rather than always-concatenate. + (fetchpatch { + url = "https://github.com/rfjakob/earlyoom/commit/f7d6f1cc925962fbdcf57b1c2aeeabbf11e2d542.patch"; + hash = "sha256-DJDeQzcEGJMoMGIi1D/ogMaKG1VQvPZN9jXtUDGjyjk="; + }) ]; + nativeBuildInputs = lib.optionals withManpage [ pandoc ]; + makeFlags = [ "VERSION=${finalAttrs.version}" - ]; - - installPhase = '' - runHook preInstall - install -D earlyoom $out/bin/earlyoom - '' + lib.optionalString withManpage '' - installManPage earlyoom.1 - '' + '' - runHook postInstall - ''; + "PREFIX=${placeholder "out"}" + ] ++ lib.optional withManpage "MANDIR=${placeholder "man"}/share/man"; passthru.tests = { inherit (nixosTests) earlyoom; @@ -58,7 +61,9 @@ stdenv.mkDerivation (finalAttrs: { ''; license = lib.licenses.mit; mainProgram = "earlyoom"; - maintainers = with lib.maintainers; [ ]; + maintainers = with lib.maintainers; [ + oxalica + ]; platforms = lib.platforms.linux; }; })