Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC 0097] Unset read permission bit on /nix/store for other users #97

Merged
merged 12 commits into from
Feb 9, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions rfcs/0097-no-read-store-dir.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
feature: no-read-store-dir
start-date: 2021-07-04
author: Las Safin
co-authors:
shepherd-team:
L-as marked this conversation as resolved.
Show resolved Hide resolved
shepherd-leader:
related-issues:
---

# Summary
[summary]: #summary

Set the permissions for /nix/store to 1771 instead of 1775, disabling reading the directory for other users.
L-as marked this conversation as resolved.
Show resolved Hide resolved

# Motivation
[motivation]: #motivation

This means that you can not trivially see all the paths in the nix store, e.g. `ls` won't work
on /nix/store without sudo unless you're in the nixbld group.

Almost everything in NixOS needs access to /nix/store, which means that all your systemd services,
your flatpak programs, your manually [bubblewrap](https://github.com/containers/bubblewrap)ed programs
will almost certainly have access to /nix/store and see all of its contents.
That means they will see your NixOS configuration, initrd secrets (unless your bootloader has support for it),
all the programs you've built, and possibly also your important secrets if you
(unfortunately) had to put them in the store!

By simply removing the ability to read /nix/store (but not execute!), programs will only be able
to access the store paths *which they already know the hash and name of*. This is a huge boon to security
even if you don't have secrets in your store, as it will almost completely eliminate the above
problems. That isn't to say it's a complete solution to security, but it will *allow* much more
complete solutions to security, for example with bubblewrap, meaning that you can be sure that
your sandboxed game won't suddenly scrape your store and send it off to NSA.

# Detailed design
L-as marked this conversation as resolved.
Show resolved Hide resolved
[design]: #detailed-design

Set the 1775
in [nixpkgs/nixos/modules/system/boot/stage-2-init.sh](https://github.com/NixOS/nixpkgs/blob/8284fc30c84ea47e63209d1a892aca1dfcd6bdf3/nixos/modules/system/boot/stage-2-init.sh#L62),
in [nix/scripts/install-multi-user.sh](https://github.com/NixOS/nix/blob/cf1d4299a8fa8906f62271dcd878018cef84cc30/scripts/install-multi-user.sh#L577),
in [nix/src/libstore/globals.hh](https://github.com/NixOS/nix/blob/ba8b39c13003c8ddafb6bec308997e09b9851c46/src/libstore/globals.hh#L278),
in [nix/src/libstore/build/local-derivation-goal.cc](https://github.com/NixOS/nix/blob/6182ae689826554d915b4ed72e07f7978dc1d13c/src/libstore/build/local-derivation-goal.cc#L641), and
in [nix/src/libstore/local-store.cc](https://github.com/NixOS/nix/blob/0a535dd5ac93576f7152d786464e330ae3d46b50/src/libstore/local-store.cc#L181)
to 1771.

# Examples and Interactions
[examples-and-interactions]: #examples-and-interactions

Losing the read (r) bit means that you can't list the files inside the store.
The execute (x) bit allows us to `cd` to it and also access paths inside the store.

E.g. `ls "$(readlink /nix/var/nix/profiles/system)"` will still work, since this is a directory
inside the store, and not the store itself, but you can't without sudo do `ls /nix/store` to find your system configuration.
L-as marked this conversation as resolved.
Show resolved Hide resolved

Note: A program could still have some idea of how the host machine is used by checking each store path that Hydra has ever built,
then it could estimate whether the host machine has e.g. Tor on it.

# Drawbacks
L-as marked this conversation as resolved.
Show resolved Hide resolved
[drawbacks]: #drawbacks

It might be a slight annoyance since shell completion won't work in the /nix/store anymore, e.g.
L-as marked this conversation as resolved.
Show resolved Hide resolved
if you have some hash 48914, you can't type `/nix/store/48914<tab>` to get the full path anymore.

L-as marked this conversation as resolved.
Show resolved Hide resolved
External tooling that does a traversal of the nix store (`find`, `du -s`, `ncdu`) would need `sudo` or explicitly given permissions.

# Alternatives
[alternatives]: #alternatives

I had [this script](https://github.com/L-as/nix-misc/blob/e844a03ebf4cad4fc8eca0e52306788b70c2a60d/claybox.rb) that is a wrapper around bubblewrap before, but doing this
is a lot cleaner, is system-wide, and is a lot faster, since bind mounting each individual store path with bubblewrap can be quite slow
if you have many (it's O(n^2) IIRC).

Another alternative for users could be just doing `sudo unshare -m bash -c 'mount -o remount,rw /nix/store; chmod 1771 /nix/store'`,
but this doesn't work right now because all of the `nix` executables set it to 1775 again.

# Unresolved questions
L-as marked this conversation as resolved.
Show resolved Hide resolved
L-as marked this conversation as resolved.
Show resolved Hide resolved
[unresolved]: #unresolved-questions

There doesn't seem to be any.

# Future work
[future]: #future-work

There could be more work in the future toward properly sandboxing systemd services and such by default,
which could also make use of this vital change.