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

/nix/store is writable in a nix-shell started by root #4337

Closed
zhaofengli opened this issue Dec 9, 2020 · 7 comments · Fixed by #5391
Closed

/nix/store is writable in a nix-shell started by root #4337

zhaofengli opened this issue Dec 9, 2020 · 7 comments · Fixed by #5391

Comments

@zhaofengli
Copy link
Member

zhaofengli commented Dec 9, 2020

Describe the bug

/nix/store is read-write in a nix-shell started by root.

Steps To Reproduce

$ mount | grep store
rpool/nix on /nix/store type zfs (ro,relatime,xattr,posixacl) <-- no active nix-shell: ok
$ nix-shell

[nix-shell:~]$ mount | grep store
rpool/nix on /nix/store type zfs (ro,relatime,xattr,posixacl) <-- non-root nix-shell: ok

[nix-shell:~]$ exit
$ sudo nix-shell -p bash

[nix-shell:/home/zhaofeng]# mount | grep store
rpool/nix on /nix/store type zfs (rw,relatime,xattr,posixacl) <-- root nix-shell: why?

Expected behavior

/nix/store should stay read-only.

nix-env --version output

The machine above is running unstable with nix-env (Nix) 2.4pre20201201_5a6ddb3.
Also reproduced on a 20.09 machine with nix-env (Nix) 2.3.9.

Additional context

The behavior is not related to ZFS, and I was able to reproduce it on a machine with single-partition ext4.

Edit: Somehow I was under the impression that this would affect the mount namespace outside the nix-shell, but this is not the case with more testing. I have updated the description.

@zhaofengli zhaofengli added the bug label Dec 9, 2020
@Profpatsch
Copy link
Member

@regnat writes:

On opening the store, Nix enters a mount namespace with the store path re-mounted writable, and because nix-shell just calls execve(bash, …), it inherits this namespace

@thufschmitt
Copy link
Member

Note that it only happens because nix bypasses the daemon by default when running as root (see #4263). A workaround is to set NIX_REMOTE=daemon to force it to use the daemon − in which case the store will stay read-only:

$ sudo nix-shell -p mount --run mount | grep store
znvme/nix on /nix/store type zfs (rw,relatime,xattr,noacl)
$ sudo NIX_REMOTE=daemon nix-shell -p mount --run mount | grep store
znvme/nix on /nix/store type zfs (ro,relatime,xattr,noacl)

@robinbb
Copy link

robinbb commented Dec 9, 2020

This is clearly not desirable, as it is astonishing. The root user should be able to launch a Nix shell without unknowingly winding up with a writable Nix store.

@edolstra
Copy link
Member

edolstra commented Dec 9, 2020

We used to have code for restoring the original mount namespace before executing the shell (a0ef212), but I had to revert it (01d07b1).

@zhaofengli zhaofengli changed the title /nix/store becomes writable when a nix-shell started by root is active /nix/store is writable in a nix-shell started by root Dec 9, 2020
@zhaofengli
Copy link
Member Author

Somehow I was under the impression that this would affect the mount namespace outside the nix-shell, but this is not the case with more testing. I have updated the description.

@grahamc
Copy link
Member

grahamc commented Apr 22, 2021

[root@hyperchicken:~]# nix-shell -p hello
these paths will be fetched (0.04 MiB download, 0.20 MiB unpacked):
  /nix/store/0pisd259nldh8yfjvw663mspm60cn5v8-hello-2.10
copying path '/nix/store/0pisd259nldh8yfjvw663mspm60cn5v8-hello-2.10' from 'https://cache.nixos.org'...

[nix-shell:~]# exit

[root@hyperchicken:~]# nix-shell '<nixpkgs>' -A hello

[nix-shell:~]# touch $out/foo

[nix-shell:~]# exit


[grahamc@hyperchicken:~]$ ls /nix/store/0pisd259nldh8yfjvw663mspm60cn5v8-hello-2.10/
bin  foo  share

[grahamc@hyperchicken:~]$ nix-store --verify-path /nix/store/0pisd259nldh8yfjvw663mspm60cn5v8-hello-2.10/
path '/nix/store/0pisd259nldh8yfjvw663mspm60cn5v8-hello-2.10' was modified! expected hash 'sha256:1ngmy2cszc6277pdq146818xrzp698dygdpa49vj5jqapwhk4nrx', got 'sha256:17nr03ig02p7phdppvw5ssgygk0xv7i28rs6cqk2r2nx23x9lixb'



@stale
Copy link

stale bot commented Oct 22, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Oct 22, 2021
dramforever pushed a commit to dramforever/nix that referenced this issue Nov 27, 2021
This ensures any started processes can't write to /nix/store (except
during builds). This partially reverts 01d07b1, which happened because
of NixOS#2646.

The problem was only happening after nix downloads anything, causing
me to suspect the download thread. The problem turns out to be:
"A  process  can't  join a new mount namespace if it is sharing
filesystem-related attributes with another process", in this case this
process is the curl thread.

Ideally, we might kill it before spawning the shell process, but it's
inside a static variable in the getFileTransfer() function. So
instead, stop it from sharing FS state using unshare(). A strategy
such as the one from NixOS#5057 (single-threaded chroot helper binary) is
also very much on the table.

Fixes NixOS#4337.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants