From 09280e17bbd29536efd1549751038fa155489bd4 Mon Sep 17 00:00:00 2001 From: Olmo Kramer Date: Sun, 30 Mar 2025 18:22:16 +0200 Subject: [PATCH] xdg-autostart: Add readOnly option (#6629) When `readOnly` is set to `true` the autostart entries are linked from a readonly directory in the nix store and `XDG_CONFIG_HOME/autostart` is a link to that directory, so that programs cannot install arbitrary autostart services. --- modules/misc/xdg-autostart.nix | 31 +++++++++----- tests/modules/misc/xdg/autostart-readonly.nix | 41 +++++++++++++++++++ tests/modules/misc/xdg/autostart.nix | 2 + tests/modules/misc/xdg/default.nix | 1 + 4 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 tests/modules/misc/xdg/autostart-readonly.nix diff --git a/modules/misc/xdg-autostart.nix b/modules/misc/xdg-autostart.nix index f6b8b7e24..d99b58a88 100644 --- a/modules/misc/xdg-autostart.nix +++ b/modules/misc/xdg-autostart.nix @@ -1,25 +1,31 @@ -{ config, lib, ... }: +{ config, lib, pkgs, ... }: let inherit (builtins) baseNameOf listToAttrs map unsafeDiscardStringContext; inherit (lib) literalExpression mkEnableOption mkIf mkOption types; cfg = config.xdg.autostart; - /* "/nix/store/x-foo/application.desktop" -> { - name = "autostart/application.desktop"; - value = { source = "/nix/store/x-foo/application.desktop"; }; - } - */ - mapDesktopEntry = entry: { - name = "autostart/${unsafeDiscardStringContext (baseNameOf entry)}"; - value.source = entry; - }; + linkedDesktopEntries = pkgs.runCommandNoCCLocal "xdg-autostart-entries" { } '' + mkdir -p $out + ${lib.concatMapStringsSep "\n" (e: "ln -s ${e} $out") cfg.entries} + ''; + in { meta.maintainers = with lib.maintainers; [ Scrumplex ]; options.xdg.autostart = { enable = mkEnableOption "creation of XDG autostart entries"; + readOnly = mkOption { + type = lib.types.bool; + description = '' + Make `XDG_CONFIG_HOME/autostart` a symlink to a readonly directory so that + programs cannot install arbitrary autostart services. + ''; + default = false; + example = true; + }; + entries = mkOption { type = with types; listOf path; description = '' @@ -35,6 +41,9 @@ in { }; config = mkIf (cfg.enable && cfg.entries != [ ]) { - xdg.configFile = listToAttrs (map mapDesktopEntry cfg.entries); + xdg.configFile.autostart = { + source = linkedDesktopEntries; + recursive = !cfg.readOnly; + }; }; } diff --git a/tests/modules/misc/xdg/autostart-readonly.nix b/tests/modules/misc/xdg/autostart-readonly.nix new file mode 100644 index 000000000..168a80108 --- /dev/null +++ b/tests/modules/misc/xdg/autostart-readonly.nix @@ -0,0 +1,41 @@ +{ pkgs, ... }: + +{ + xdg.autostart = { + enable = true; + readOnly = true; + entries = [ + "${pkgs.test1}/share/applications/test1.desktop" + "${pkgs.test2}/share/applications/test2.desktop" + ]; + }; + + test.stubs = { + test1 = { + outPath = null; + buildScript = '' + mkdir -p $out/share/applications + echo test1 > $out/share/applications/test1.desktop + ''; + }; + test2 = { + outPath = null; + buildScript = '' + mkdir -p $out/share/applications + echo test2 > $out/share/applications/test2.desktop + ''; + }; + }; + + nmt.script = '' + assertLinkExists home-files/.config/autostart + + assertFileExists home-files/.config/autostart/test1.desktop + assertFileContent home-files/.config/autostart/test1.desktop \ + ${pkgs.test1}/share/applications/test1.desktop + + assertFileExists home-files/.config/autostart/test2.desktop + assertFileContent home-files/.config/autostart/test2.desktop \ + ${pkgs.test2}/share/applications/test2.desktop + ''; +} diff --git a/tests/modules/misc/xdg/autostart.nix b/tests/modules/misc/xdg/autostart.nix index 754d11396..ff8649dc8 100644 --- a/tests/modules/misc/xdg/autostart.nix +++ b/tests/modules/misc/xdg/autostart.nix @@ -27,6 +27,8 @@ }; nmt.script = '' + assertDirectoryExists home-files/.config/autostart + assertFileExists home-files/.config/autostart/test1.desktop assertFileContent home-files/.config/autostart/test1.desktop \ ${pkgs.test1}/share/applications/test1.desktop diff --git a/tests/modules/misc/xdg/default.nix b/tests/modules/misc/xdg/default.nix index 13ebb7e10..9212694f5 100644 --- a/tests/modules/misc/xdg/default.nix +++ b/tests/modules/misc/xdg/default.nix @@ -3,4 +3,5 @@ xdg-default-locations = ./default-locations.nix; xdg-mime-disabled = ./mime-disabled.nix; xdg-autostart = ./autostart.nix; + xdg-autostart-readonly = ./autostart-readonly.nix; }