NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.9k stars 13.95k forks source link

PackageKit remounts /nix/store rw #177946

Open ElvishJerricco opened 2 years ago

ElvishJerricco commented 2 years ago

After setting up my new system with Gnome on NixOS unstable, I discovered that my /nix/store is writable. It appears to be due to Gnome. Plasma does not exhibit the same problem.

Steps To Reproduce

  1. Install NixOS with:
    xserver.enable = true;
    xserver.displayManager.gdm.enable = true;
    xserver.desktopManager.gnome.enable = true;
    services.packagekit.enable = true;
  2. Boot the system with the added cmdline paramter systemd.unit=multi-user.target to boot without the GUI.
  3. Run mount | grep /nix/store to observe the mount options for the /nix/store bind-mount before starting the GUI.
  4. Run systemctl start graphical.target to start the GUI.
  5. Run mount | grep /nix/store again to observe the mount options again.

Expected behavior

The mount options before and after starting the GUI should both say that the /nix/store bind-mount has the ro option.

Actual behavior

Instead, it is ro before the GUI is started, and rw after.

Additional context

At first I thought it was odd that I could stop display-manager.service, remount /nix/store as ro, and start graphical.target again, and the store would remain ro. But I tried instead using systemctl isolate multi-user.target to stop anything that I may have been missing as well. After doing that, starting graphical.target did cause the store to go rw. So it appears there is a unit pulled in by graphical.target that isn't display-manager.service that is causing this. EDIT: That unit is packagekit.

Also, it doesn't matter if /nix/store is its own file system or if it's just on the root file system.

Metadata

nix-info -m

ElvishJerricco commented 2 years ago

I started looking at what units get started when you start graphical.target, and found a suspiciously named one packagekit.service. https://www.freedesktop.org/software/PackageKit/pk-intro.html

Adding systemd.services.packagekit.enable = false; to my config has stopped it from remounting the store rw.

ElvishJerricco commented 2 years ago

Should PackageKit be disabled on NixOS outright?

MagicRB commented 2 years ago

Probably yes

MagicRB commented 2 years ago

https://github.com/PackageKit/PackageKit/tree/main/backends/nix Found this, im not in the stae of processing so much c++ code, but it doesnt make sense to remount rw unless they have a bug to not use the daemon but single-user even uf multi-user is available

symphorien commented 2 years ago

Totally unverified hypothesis: when running nix-shell as root, the store is remounted read only, because by default nix run as root does not go through the daemon. An explanation could be that this backend uses the same code path.

viraptor commented 2 years ago

Should PackageKit be disabled on NixOS outright?

Not necessarily. It can manage apps in flatpak/snap/others which are still valid ways of adding apps on nixos.

nixos-discourse commented 2 years ago

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

https://discourse.nixos.org/t/why-are-there-writable-files-in-nix-store/20352/8

Atemu commented 2 years ago

cc @matthewbauer

nixos-discourse commented 2 years ago

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

https://discourse.nixos.org/t/how-does-root-filesystem-work/21590/13

nixos-discourse commented 2 years ago

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

https://discourse.nixos.org/t/the-linux-experiment-every-linux-distro-should-have-these-features/21955/1

SuperSandro2000 commented 1 year ago

FYI @matthewbauer @bobby285271

nixos-discourse commented 1 year ago

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

https://discourse.nixos.org/t/archive-manager-only-know-one-on-archive/29019/4

leo60228 commented 1 year ago

PackageKit uses Nix as a library. From some searching, it looks like local stores are remounted as read-write under the assumption that unshare(CLONE_NEWNS) has been called in main, but PackageKit doesn't do that.

Thesola10 commented 4 months ago

Couldn't we just unshare the entire packagekit.service unit instead using PrivateMounts=yes? I don't see a situation where PackageKit would need to modify the global mount namespace.

ElvishJerricco commented 3 months ago

@Thesola10 Sure, but that's only a bandaid. packagekit.service shouldn't have a rw view of the store either.

Thesola10 commented 3 months ago

Wait, shouldn't the PackageKit integration communicate with the Nix daemon like the standard Nix command? If the daemon is doing the work then why is Nix trying to remount the store in the first place?

ElvishJerricco commented 3 months ago

When Nix runs as root, it doesn't go through the daemon by default. It doesn't have to; IIUC sqlite's own mechanisms ensure the DB is coherent between multiple processes directly working on it. So the fact that packagekit is run as root and links directly to Nix means that it's triggering the same namespacing code path as the daemon and giving itself a rw view.

Thesola10 commented 3 months ago

So the solution is to force the PackageKit Nix backend to use the daemon so it never remounts the Nix Store.