Skip to content

nixos/polkit: don't enable by default#156858

Merged
piegamesde merged 9 commits intoNixOS:masterfrom
mweinelt:polkit-mkenable
Mar 5, 2022
Merged

nixos/polkit: don't enable by default#156858
piegamesde merged 9 commits intoNixOS:masterfrom
mweinelt:polkit-mkenable

Conversation

@mweinelt
Copy link
Member

@mweinelt mweinelt commented Jan 26, 2022

Motivation for this change

SUID wrappers really shouldn't be enabled by default, unless a consumer
relies on them. So in my opinion this falls upon the desktop
environments if needed or a user to explicltly enable this if wanted.

Most desktop environments and services like CUPS already enable polkit
by default, that should really be sufficient.

Things done

Successfully ran the following tests:

  • gnome
  • gnome-xorg
  • pantheon
  • plasma5
  • sway (enabled polkit in module)
  • tinywl
  • vscodium
  • xfce

Working after dropping the polkit assertion in x11server.nix

  • domination
  • ft2-clone
  • herbstluftwm
  • i3wm
  • keepassxc
  • keymap
  • libinput
  • lightdm
  • musescore
  • plasma5-systemd-start
  • pt2-clone
  • shattered-pixel-dungeon
  • sddm
  • signal-desktop
  • soapui
  • systemd
  • tigervnc
  • tuxguitar
  • vengi-tools
  • wmderland
  • xautolock
  • xmonad
  • xrdp
  • xss-lock
  • xterm

Unrelated failures

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Jan 26, 2022
@mweinelt
Copy link
Member Author

@ofborg test gnome gnome-xorg xfce pantheon paslam5 plasma5-systemd-start dnscrypt-wrapper udisk2 prometheus-exporters.modemmanager xmonad lightdm

A bunch of things that rely in same way on polkit.

@mweinelt mweinelt added the 9.needs: changelog This PR needs a changelog entry label Jan 26, 2022
@mweinelt
Copy link
Member Author

❯ nix-build nixos/tests/lightdm.nix
error: 
Failed assertions:
- X11 requires Polkit to be enabled (‘security.polkit.enable = true’).
(use '--show-trace' to show detailed location information)

I guess it would be sane to mkDefault enable polkit in xserver.nix then. 🤷

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. labels Jan 26, 2022
@dasJ
Copy link
Member

dasJ commented Jan 26, 2022

Or remove the assertion? The commit that introduces it mentions that the xession script calls systemd-inhibit but I can't find that in the nixos/ tree

@jtojnar
Copy link
Member

jtojnar commented Jan 26, 2022

Note that systemd itself uses polkit so we should test if it works without it.

@Atemu
Copy link
Member

Atemu commented Jan 26, 2022

Flatpak also needs polkit for escalation prompts of apps.

@mweinelt
Copy link
Member Author

Note that systemd itself uses polkit so we should test if it works without it.

Looks like so:

$ systemctl stop 0
Failed to stop 0.service: Access denied
See system logs and 'systemctl status 0.service' for details.

instead of this:

❯ systemctl stop 0
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to stop '0.service'.
Authenticating as: hexa
Password: 

@mweinelt
Copy link
Member Author

Flatpak also needs polkit for escalation prompts of apps.

I don't see our module installing polkit rules though.

@mweinelt
Copy link
Member Author

mweinelt commented Jan 26, 2022

@primeos Not sure about the fix for the sway test. I don't see that sway strictly needs polkit, but the tests are not working without it. But maybe it's something in the tests requiring it?

@mweinelt
Copy link
Member Author

I'm now pretty sure that wayland requires polkit (to access loginctl, the tty, the DRI), so adding it to sway and cage is in fact correct.

@mweinelt mweinelt marked this pull request as ready for review January 26, 2022 22:12
@primeos
Copy link
Member

primeos commented Jan 26, 2022

@primeos Not sure about the fix for the sway test. I don't see that sway strictly needs polkit, but the tests are not working without it. But maybe it's something in the tests requiring it?

Right, it shouldn't be required for Sway itself. It looks like it might be required for some logind functionality though (doesn't systemd in general rely on Polkit btw? It's a while ago that I peeked into that part but IIRC there are quite some connections between the two, unfortunately (I didn't like it back then either so huge thanks for looking into disabling it!) - ideally Polkit is optional though).
Edit: I see this was already mentioned in other comments before. We definitely should have a closer look at systemd then.

I've dumped Sway's output and got this:

00:00:00.043 [DEBUG] [sway/server.c:50] Preparing Wayland server initialization
00:00:00.057 [INFO] [wlr] [libseat] [libseat/backend/seatd.c:80] Could not connect to socket /run/seatd.sock: No such file or directory
00:00:00.058 [INFO] [wlr] [libseat] [libseat/libseat.c:76] Backend 'seatd' failed to open seat, skipping
00:00:00.070 [ERROR] [wlr] [libseat] [libseat/backend/logind.c:310] Could not activate session: Permission denied
00:00:00.071 [INFO] [wlr] [libseat] [libseat/libseat.c:76] Backend 'logind' failed to open seat, skipping
00:00:00.071 [INFO] [wlr] [libseat] [seatd/seat.c:38] Created VT-bound seat seat0
00:00:00.072 [INFO] [wlr] [libseat] [seatd/server.c:139] New client connected (pid: 889, uid: 1000, gid: 100)
00:00:00.072 [ERROR] [wlr] [libseat] [common/terminal.c:149] Could not open target tty: Permission denied
00:00:00.073 [ERROR] [wlr] [libseat] [seatd/seat.c:60] Could not open tty0 to update VT: Permission denied
00:00:00.073 [INFO] [wlr] [libseat] [seatd/seat.c:169] Added client 0 to seat0
00:00:00.073 [ERROR] [wlr] [libseat] [common/terminal.c:149] Could not open target tty: Permission denied
00:00:00.073 [ERROR] [wlr] [libseat] [seatd/seat.c:71] Could not open terminal for VT 0: Permission denied
00:00:00.073 [ERROR] [wlr] [libseat] [seatd/seat.c:449] Could not open VT for client
00:00:00.074 [ERROR] [wlr] [libseat] [common/terminal.c:149] Could not open target tty: Permission denied
00:00:00.074 [ERROR] [wlr] [libseat] [seatd/seat.c:85] Could not open terminal to clean up VT 0: Permission denied
00:00:00.074 [INFO] [wlr] [libseat] [libseat/libseat.c:73] Seat opened with backend 'builtin'
00:00:00.074 [INFO] [wlr] [backend/session/session.c:110] Successfully loaded libseat session
00:00:00.074 [INFO] [wlr] [backend/backend.c:91] Waiting for a session to become active
00:00:10.085 [ERROR] [wlr] [backend/backend.c:114] Timeout waiting session to become active
00:00:10.085 [ERROR] [wlr] [backend/backend.c:352] Failed to start a DRM session
00:00:10.085 [ERROR] [sway/server.c:56] Unable to create backend
00:00:10.095 [ERROR] [wlr] [libseat] [common/terminal.c:149] Could not open target tty: Permission denied
00:00:10.095 [ERROR] [wlr] [libseat] [seatd/seat.c:85] Could not open terminal to clean up VT 0: Permission denied
00:00:10.095 [INFO] [wlr] [libseat] [seatd/seat.c:512] Closed client 0 on seat0
00:00:10.095 [INFO] [wlr] [libseat] [seatd/seat.c:191] Removed client 0 from seat0

The problem should be:

00:00:00.070 [ERROR] [wlr] [libseat] [libseat/backend/logind.c:310] Could not activate session: Permission denied

(Could not connect to socket /run/seatd.sock is to be expected.)

So the problem shouldn't be specific to Sway (dependency wise it's quite nested: sway -> wlroots -> seatd -> systemd/logind).
Unfortunately I haven't time for a closer look though :o

@primeos
Copy link
Member

primeos commented Jan 26, 2022

Ok, so regarding systemd: From a quick peek into the source-code it luckily seems to be optional :)

README:        polkit (optional)

NEWS:        * Various systemd components will now bypass polkit checks for
NEWS:          root and otherwise handle properly if polkit is not found to
NEWS:          be around. This should fix most issues for polkit-less
NEWS-          systems. Quite frankly this should have been this way since
NEWS-          day one. It is absolutely our intention to make systemd work
NEWS:          fine on polkit-less systems, and we consider it a bug if
NEWS:          something does not work as it should if polkit is not around.

We might be able to avoid these issues by building systemd without polkit support:

meson_options.txt:option('polkit', type : 'combo', choices : ['auto', 'true', 'false'],
meson_options.txt:       description : 'polkit support')

A few relevant excepts from the release notes to figure out which components/features might be impacted:

NEWS-        * systemd-logind will now validate access to the operation of changing
NEWS:          the virtual terminal via a polkit action. By default, only users
NEWS-          with at least one session on a local VT are granted permission.

NEWS:        * When systemd requests a polkit decision when managing units it
NEWS-          will now add additional fields to the request, including unit
NEWS:          name and desired operation. This enables more powerful polkit
NEWS-          policies, that make decisions depending on these parameters.

NEWS-        * systemd-machined, systemd-logind, systemd: most bus calls are
NEWS:          now accessible to unprivileged processes via polkit. Also,
NEWS-          systemd-logind will now allow users to kill their own sessions
NEWS-          without further privileges or authorization.

NEWS:        * A number of bus APIs of PID 1 now optionally consult polkit to
NEWS-          permit access for otherwise unprivileged clients under certain
NEWS-          conditions. Note that this currently doesn't support
NEWS-          interactive authentication yet, but this is expected to be
NEWS-          added eventually, too.

There are also things like https://github.com/systemd/systemd/blob/5efbd0bf897a990ebe43d7dc69141d87c404ac9a/src/network/systemd-networkd.rules (a complete grep through the source-code might be a good idea).

@mweinelt
Copy link
Member Author

So the problem shouldn't be specific to Sway (dependency wise it's quite nested: sway -> wlroots -> seatd -> systemd/logind).

No biggie, I think we're fine with enabling polkit in programs.sway for now then. The situation after this PR is strictly better than before.

Ok, so regarding systemd: From a quick peek into the source-code it luckily seems to be optional :)

This is also my experience from Debian setups that runs completely fine without polkit.

@github-actions github-actions bot added 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation labels Jan 26, 2022
@mweinelt
Copy link
Member Author

Added a short mention to the release notes.

@ajs124
Copy link
Member

ajs124 commented Jan 27, 2022

Or remove the assertion? The commit that introduces it mentions that the xession script calls systemd-inhibit but I can't find that in the nixos/ tree

This 85898da is probably the commit that dropped it.

SUID wrappers really shouldn't be enabled by default, unless a consumer
relies on them. So in my opinion this falls upon the desktop
environments if needed or a user to explicltly enable this if wanted.

Most desktop environments and services like CUPS already enable polkit
by default, that should really be sufficient.
Allows user in the networkmanager group to control the daemon.
@mweinelt
Copy link
Member Author

mweinelt commented Jan 28, 2022

I agree that we don't want to support multiple systemd flavors, and I'm not sure we need to, because systemd seems to handle missing polkit at runtime just fine. I checked several different distros and polkit is optional in their respective systemd packaging, so we're hardly creating a precedent here.

My servers also don't have udisks2 enabled, which at this point also gets enabled by several desktop managers. It's a common scenario to mount your USB devices manually, it's not a biggie really. Most of the machines I deploy are also VMs, where I couldn't even deploy a USB stick easily.

❯ rg "services\.udisks2\.enable = true" -l
tests/udisks2.nix
modules/services/x11/desktop-managers/enlightenment.nix
modules/services/x11/desktop-managers/xfce.nix
modules/services/x11/desktop-managers/plasma5.nix
modules/services/x11/desktop-managers/gnome.nix
modules/services/x11/desktop-managers/cinnamon.nix
modules/services/x11/desktop-managers/pantheon.nix
modules/services/misc/devmon.nix

Also for most of my server a simple truth is that they don't have any unprivileged interactive users, so I don't see the point in having a privilege elevation framework available, that no deployed service should ever be able to use.

@mweinelt
Copy link
Member Author

I don't understand the downside of compiling systemd with polkit

Quite obviously it breaks logind functionality. That's why the tests are suddenly broken. This isn't a Wayland or seatd issue - it's a logind regression. Do we really want to break the user login flow on desktop systems?

If you find another solution that's fine by me but I don't think we want a regression that prevents users from starting their graphical session (based on the tests that clearly seems to be the case - I didn't test this manually though).

I don't believe that is part of the fight I'm willing to fight in this PR. I recognize that polkit is useful in setups with interactive usage, especially desktop systems, which is why I added a polkit enabler to sway in 09798ce (#156858). If it doesn't come through sway, then it comes via cups or networkmanager.

Does that make sense from your POV?

@primeos
Copy link
Member

primeos commented Jan 29, 2022

Does that make sense from your POV?

Not not at all tbh. Either you're deliberately ignoring facts or I must somehow be speaking a foreign language or something like that.

because systemd seems to handle missing polkit at runtime just fine.

We have multiple tests that prove this wrong. This should be considered a systemd bug (unless it's due to our patches, configuration, etc.) but that doesn't automatically make it go away. Someone has to investigate it and report it to upstream.

I haven't spend much time on this but the results I posted earlier should be reproducible and clearly prove that systemd doesn't always handle missing Polkit fine at runtime (something in the logind code must be wrong - it shouldn't be too difficult to investigate that but it'll probably require a bit of extra time).

I recognize that polkit is useful in setups with interactive usage, especially desktop systems, which is why I added a polkit enabler to sway in 09798ce (#156858).

In case that wasn't clear from my previous comments: I don't rally want Polkit on my system (although disabling it can also make security worse because applications like systemd then have to implement some/more of the privilege escalation on their own) and I shouldn't need it (in theory). So I'd welcome this change but that isn't what my comments were about (I just want to clearly state here that I'm not against disabling Polkit). Sway does not require Polkit. Wayland does not require Polkit.

If it doesn't come through sway, then it comes via cups or networkmanager.

No. The VM test enables neither of them. The output clearly indicates that systemd/logind is the issue and not something else.
Based on the VM test we currently have the following facts that should be reproducible without any issues:

  • services.polkit.enable = true; -> Everything works as it used to
  • services.polkit.enable = false; -> The behaviour of systemd/logind changes and prevents gaining privileged access upon login on a virtual terminal (tty).
  • services.polkit.enable = false; AND systemd compiled without Polkit support -> The tests succeed as before. So why would it suddenly work again if the issue doesn't come from systemd/logind.

You can now either accept those facts and investigate accordingly or you can ignore them and this whole discussion will become pointless (and in that case I'll also refrain from responding as it simply makes no sense at that point).

Edit: I took a very brief look into the systemd source-code out of curiosity. The following looks like the relevant bit (the name chvt seems misleading as it's also used by the methods to activate a session):

src/login/logind-polkit.c:int check_polkit_chvt(sd_bus_message *message, Manager *manager, sd_bus_error *error) {
src/login/logind-polkit.c:#if ENABLE_POLKIT
src/login/logind-polkit.c:        return bus_verify_polkit_async(
src/login/logind-polkit.c-                        message,
src/login/logind-polkit.c-                        CAP_SYS_ADMIN,
src/login/logind-polkit.c-                        "org.freedesktop.login1.chvt",
src/login/logind-polkit.c-                        NULL,
src/login/logind-polkit.c-                        false,
src/login/logind-polkit.c-                        UID_INVALID,
src/login/logind-polkit.c:                        &manager->polkit_registry,
src/login/logind-polkit.c-                        error);
src/login/logind-polkit.c-#else
src/login/logind-polkit.c:        /* Allow chvt when polkit is not present. This allows a service to start a graphical session as a
src/login/logind-polkit.c:         * non-root user when polkit is not compiled in, more closely matching the default polkit policy */
src/login/logind-polkit.c-        return 1;
src/login/logind-polkit.c-#endif
src/login/logind-polkit.c-}

@Istvan91
Copy link
Contributor

Istvan91 commented Feb 1, 2022

tl;dr:

  • if systemd is compiled with polkit, some logind features have a some "hard" dependency on polkit
  • polkit-less GUI is not really possible without two systemd packages (i wouldn't consider SUID as an accaptable solution)
  • it is feasible to support polkit-less server/headless installation with systemd and compiled in polkit support (i think this PR does already a lot towords that goal)
  • making polkit forcefully mandatory seems misguided to me

because systemd seems to handle missing polkit at runtime just fine.

We have multiple tests that prove this wrong. This should be considered a systemd bug (unless it's due to our patches, configuration, etc.) but that doesn't automatically make it go away. Someone has to investigate it and report it to upstream.

Your expectation of "it should work" is wrong: systemd/logind does handle a missing polkit dependency gracefully: Access Denied for everything. Since polkit is basically systemd's only way for privilege escalation, that is the only sane behavior. Otherwise you could gain privileges via systemd/logind if the polkit service down. (You can't just allow everyone to do everything when your authorization server is down, or the case we are talking about: not installed)

So why does logind "just work" when it was compiled without polkit support? You've already found the relevant code in logind: it reads: "if polkit is disabled, we have absolutely no way to check your privileges, so we'll just hand them out to you". This is a rather ugly (insecure?) compromise to make graphical sessions work with logind and no polkit support (to be fair: this is the default polkit rule).

Sway does not require Polkit. Wayland does not require Polkit

sway/wayland does need some privileged permissions (i think the DRM stuff, but I'm not too informed about that), so we do need some kind of permission granting. Choice one of

  • making the binaries SUID
  • elogind with or without polkit support (I don't think that's possible on nixos?)
  • (maybe some selinux magic or setcap could work?)
  • logind without polkit support with a hardcoded permission grant
  • logind with polkit support: dynamically handing out the necessary permissions via polkit rules, but denying the grant if the polkit.service is not available

So the last case it does have an indirect dependency on polkit: sway -> wlroots -> libseat -> logind (with polkit support) -> polkit. To re-iterate myself: The working logind-without-compiled-support-for-polkit case is imho more of an half-hearted compromise than a solution. What is definitely not a bug: to error out with access denied when your only means for privilege escalation is not unavailable. The (imho proper) solution is to just add polkit as dependency to wlroots based wms (and everything else that depends on logind).

I don't see any way to have polkit-less GUI systems without a "split" between systemd with polkit and systemd without polkit. Polkit-less servers on the other hand should be feasible: AFAICT this PR already does most (everything?) to achieve that.

This just creates unnecessary divergence between desktop and non-desktop NixOS systems. Having NixOS systems without polkit essentially forks NixOS

Part of making a Linux distribution is making choices, and for NixOS one of those choices is that we use polkit, just like we use systemd, dbus, etc. I'm actually in favor of removing (or hiding) the security.polkit.enable option.
This is only true if systemd is compiled twice: with and without polkit support.

Assuming that we only support systemd with polkit support enabled (current status quo), polkit itself will still be optional for a lot (server/headless) installations. Except for some logind features there is nothing i'm aware of in systemd (with polkit support) which really needs polkit.
In this case there is no notable divergence between desktop and non-desktop NixOS systems. It is pointless to install polkit on systems if nothing will ever use it. The only notable difference is the missing permission prompt from systemctl et. al.

Setting services.polkit.enable = false by default and having the necessary packages (which depend on logind) enable it themselves is reasonable. Leaving services.polkit.enable = true is equally valid, but removing or hiding the services.polkit.enable option seems misguided to me.

Pretty much all applications (excluding the logind ones) can deal with missing/unavailable polkit: It is almost the same as a permission deny, and if they misbehave anyway, it is an upstream bug and shouldn't be treated differently than any other upstream bug. I don't think this should be factored into the decision about the support for polkit-less installations.

The actual question is whether the effort to identify and keep track of all the services which require polkit (optionally or in case of logind dependencies mandatory) is worth of making polkit optional. AFAICT most packages (which do not depend on polkit via logind) already keep indirectly track of the polkit dependency by adding polkit rules if services.polkit.enable = true. I think practically only the packages depending on logind need to be identified. Packages which require polkit as an optional dependency, seem to explicitly configure it already.

@dasJ dasJ reopened this Feb 1, 2022
@primeos
Copy link
Member

primeos commented Feb 2, 2022

Your expectation of "it should work" is wrong

Yes, I could've known better but I wrote that before I looked at the code and it was based on that excerpt:

Various systemd components will now bypass polkit checks for root and otherwise handle properly if polkit is not found to be around. This should fix most issues for polkit-less systems. Quite frankly this should have been this way since day one. It is absolutely our intention to make systemd work fine on polkit-less systems, and we consider it a bug if something does not work as it should if polkit is not around.

"if polkit is disabled, we have absolutely no way to check your privileges, so we'll just hand them out to you"

For the case where polkit does the same, by default, as you mention.

https://github.com/systemd/systemd/blob/5c10b983506c782ef2f2a72aae1d6713940574a7/src/login/org.freedesktop.login1.policy#L405-L413

sway/wayland does need some privileged permissions (i think the DRM stuff, but I'm not too informed about that), so we do need some kind of permission granting.

Sure. My point was just that they do not require or depend (code-wise) on Polkit.

So the last case it does have an indirect dependency on polkit

That's the issue I'm talking about, yes.

The (imho proper) solution is to just add polkit as dependency to wlroots based wms (and everything else that depends on logind).

THIS is the problem (that last part). We're not talking about wlroots or Wayland here. This "regression" isn't specific to them. It (potentially) affects every desktop system.

I don't see any way to have polkit-less GUI systems without a "split" between systemd with polkit and systemd without polkit.
Polkit-less servers on the other hand should be feasible: AFAICT this PR already does most (everything?) to achieve that.

Agreed. The problem is that this PR seems to focus on servers but the change isn't limited to them (via something like a server profile).

Setting services.polkit.enable = false by default and having the necessary packages (which depend on logind) enable it themselves is reasonable.

One problem is that we have a lot of software (probably mainly Wayland compositors) that doesn't come with a NixOS module (e.g. River). To me it seems unlikely that we'll catch all cases so at least some regressions/breakage will be left (might be acceptable though but I don't want to encourage regressions).

The actual question is whether the effort to identify and keep track of all the services which require polkit (optionally or in case of logind dependencies mandatory) is worth of making polkit optional.

Agreed. That should be time consuming, difficult to test/verify, and currently it looks like there isn't enough motivation (which is why a server profile or workaround might be better for now).

I think practically only the packages depending on logind need to be identified.

Our tests would hopefully catch other important cases (e.g. it might be required for networking.hostName = ""; but I forgot how that was implemented). It would certainly seem wise though to look through the systemd source-code to avoid surprises.

Anyway tl;dr: I like the idea behind this PR (especially disabling polkit on servers) but it seems like a (over)reaction to the recent polkit CVEs instead of a carefully considered / thought through approach (which is why I felt obliged to interject and spoil the fun as I've seen too many PRs like this that got merged too fast and caused severe regressions that annoyed users).

PS: I'm sorry if something sounds aggressive/offensive or is wrong. I just wrote this down very quickly due to lack of time/priority as some of my earlier statements may have come off wrong.

@colemickens
Copy link
Member

I'm reading all of this and the question keeps getting louder: where are things heading? Is there upstream appetite in systemd/logind or further moving away or avoiding from polkit? What if systemd's behavior were more easily controlled at runtime? wlroot's support for non-logind backends seems to indicate there's support for... avoiding certain components, maybe there's other efforts around this area?

It just feels like there might be a few options that involve some work outside NixOS that would give us better choices, and the wlroots ecosystem seems to move fast, and systemd can move fast on things too.

Having wrapped my head around the implications of package splits via nixpkgs.config while debugging why a good chunk of users were still having to rebuild things like webkit on top of nixos-unstable... I find it hard to imagine building two copies of everything that builds against systemd.

Also, can we explicitly list out the benefits of achieving polkit-less "server" builds vs just splitting off pkexec? I'm no fan of security critical sofware written in C, don't get me wrong and I think it also pulls in spidermonkey, but I'm a bit more jaded about the idea than when I first read the initial description (which still seems like a good ambition in the long-term, short of some sort of polkit rewrite in some other language 🦀)

@Atemu
Copy link
Member

Atemu commented Mar 1, 2022

I think if we enabled polkit when services.xserver.enable = true; we would cover all desktop setups that need it, right?

Once we (and upstream projects) have figured out who actually needs it, we can make it more fine-grained.

On non-GUI setups, the worst disabling polkit does is make systemd tools unable to escalate when there is insufficient privilege, right?

@Istvan91
Copy link
Contributor

Istvan91 commented Mar 2, 2022

I'm reading all of this and the question keeps getting louder: where are things heading? Is there upstream appetite in systemd/logind or further moving away or avoiding from polkit? What if systemd's behavior were more easily controlled at runtime? wlroot's support for non-logind backends seems to indicate there's support for... avoiding certain components, maybe there's other efforts around this area?

I don't see systemd moving away from polkit, and the current behaviour seems sane to me. The non-logind backends statically grant the necessary permissions to wlroots - there isn't that much from the wlroot side to support, it just needs something that will give it access to KMS/DRM.
The best I can think of is adding an option to logind to force the polkit-less behaviour when the polkit daemon is not available.

Also, can we explicitly list out the benefits of achieving polkit-less "server" builds vs just splitting off pkexec?

Less software to install + no possible privilege escalation: neither through bugs, nor through misconfiguration of component (which is not needed in the first place)

I think if we enabled polkit when services.xserver.enable = true; we would cover all desktop setups that need it, right?

Which is not intuitive if you are running a wayland only environment:. Those would currently affected most: Many rely either directly or indirectly on logind.

Splitting packages in nixpkgs to have a polkit and polkit-less variant is imho not feasible. So that leaves only two practical options:

  1. disable polkit by default and have it included via the module system if necessary
  2. leave everything as it is: polkit enabled by default let give the user the option to disable it

Option 1 does need some work though: Not all packages which require polkit have a module (e.g. "River" was mentioned earlier) and it would be a breaking change for users who depended on the automatic inclusion of polkit. As it is this patchset is currently not enough, because it only works for packages which are somehow represented as a module.

On non-GUI setups, the worst disabling polkit does is make systemd tools unable to escalate when there is insufficient privilege, right?

Well, there are some applications, which (optionally) use polkit and technically do not require any GUI. CUPS is the first thing which comes to my mind.
Also there are some use cases which are better solved by polkit than by sudo. But I guess in such cases people write their own polkit rules and would be able to enable it explicitly.

@Atemu
Copy link
Member

Atemu commented Mar 2, 2022

Which is not intuitive if you are running a wayland only environment:. Those would currently affected most: Many rely either directly or indirectly on logind.

services.xserver is a bit of a misnomer: #94799

Either way, enabling any wayland compositor should enable wayland support which should enable polkit.

@mweinelt
Copy link
Member Author

mweinelt commented Mar 2, 2022

I don't think this pull request necessarily needs to be complete, as the set of modules we need to touch is unclear and hard to determine. We need to take care of the things we know now and find out the hard way when this goes out to people via the unstable channel.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/breaking-changes-announcement-for-unstable/17574/10

@piegamesde
Copy link
Member

Unless somebody has some strong objections that haven't been addressed before, I'm inclined towards merging this.

@cole-h
Copy link
Member

cole-h commented Mar 4, 2022

Should we gate the "default-off" behavior on stateVersion? e.g. "if stateVersion is newer than XX.YY, default = false, else, default = true"

Otherwise, if people rely on polkit but don't use one of these small set of modules that have had the enable = true tacked on, they may be confused as to why it no longer works.

@Atemu
Copy link
Member

Atemu commented Mar 4, 2022

Otherwise, if people rely on polkit but don't use one of these small set of modules that have had the enable = true tacked on, they may be confused as to why it no longer works.

I believe that'd go contrary to the entire point of unleashing this upon nixos-unstable users.

@piegamesde
Copy link
Member

I'd be against gating this on the stateVersion as well. In that case, existing NixOS installations wouldn't benefit from it: The general rule is that one doesn't change the stateVersion, but in this case this would mean a lot of users miss a potential security/hardening improvement.

@piegamesde piegamesde merged commit cd7e516 into NixOS:master Mar 5, 2022
@mweinelt mweinelt deleted the polkit-mkenable branch March 5, 2022 13:56
ajs124 added a commit to helsinki-systems/nixpkgs that referenced this pull request Aug 11, 2022
This was enabled by default in 18a7ce7
with the reason that it would be "useful regardless of the desktop
environment.", which I'm not arguing against.

The reason why this should not be enabled by default is that there are a
lot of systems that NixOS runs on that are not desktop systems.
Users on such systems most likely do not want or need this feature and
could even consider this an antifeature.
Furthermore, it is surprising to them to find out that they have this
enabled on their systems.
They might be even more surprised to find that they have polkit enabled
by default, which was a default that was flipped in
a813be0. For some discussion as to why
see NixOS#156858.

Evidently, this default is not only surprising to users, but also module
developers, as most if not all modules for desktop environments already
explicity set services.udisks2.enable = true; which they don't need to
right now.
primeos added a commit to primeos/nixpkgs that referenced this pull request Sep 3, 2022
The udisks2 service was enabled to fix the test in (c5ebec7).
However, cagebreak doesn't require udisks2, just polkit (which the
udisks2 module enables and which is why the cagebreak test broke after
the udisks2 module was disabled by default).

I've documented why polkit is required in this PR:
NixOS#156858

In this case the "dependency" chain is basically cagebreak -> wlroots ->
libseat -> logind (with polkit support) -> polkit.
RaitoBezarius pushed a commit to RaitoBezarius/nixpkgs that referenced this pull request Sep 17, 2022
The udisks2 service was enabled to fix the test in (c5ebec7).
However, cagebreak doesn't require udisks2, just polkit (which the
udisks2 module enables and which is why the cagebreak test broke after
the udisks2 module was disabled by default).

I've documented why polkit is required in this PR:
NixOS#156858

In this case the "dependency" chain is basically cagebreak -> wlroots ->
libseat -> logind (with polkit support) -> polkit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation 8.has: module (update) This PR changes an existing module in `nixos/` 9.needs: changelog This PR needs a changelog entry 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.