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

Invoking nix in a derivation's build script violates the macOS sandbox in Nix 2.4 and later #5884

Closed
lilyball opened this issue Jan 7, 2022 · 11 comments · Fixed by #6812
Closed
Labels

Comments

@lilyball
Copy link
Member

lilyball commented Jan 7, 2022

Describe the bug

Starting with Nix 2.4 and later, attempting to run nix --version (or nix-env --version) from within the macOS sandbox aborts with an uncaught exception caused by a deny file-read-metadata. The particular path it fails on differs between Nix 2.4 and Nix 2.5.1 but both fail. Nix 2.4 is failing on trying to read /nix/var/nix/profiles/per-user/root/channels/nixpkgs

Steps To Reproduce

  1. Turn on the sandbox in /etc/nix/nix.conf (in my case I have sandbox = relaxed but true works too)
  2. nix build --impure --expr 'with import (builtins.getFlake "github:NixOS/nixpkgs/77fda7f672726e1a95c8cd200f27bccfc86c870b") {}; runCommand "foo" { nativeBuildInputs = [ nix ]; } "nix --version"' (the rev here is the current nixpkgs/nixpkgs-unstable)
  3. Also try nix build --impure --expr 'with import (builtins.getFlake "github:NixOS/nixpkgs/77fda7f672726e1a95c8cd200f27bccfc86c870b") {}; runCommand "foo" { nativeBuildInputs = [ nix_2_4 ]; } "nix --version"' for Nix 2.4

Nix 2.5.1

Output:

libc++abi: terminating with uncaught exception of type nix::SysError: error: getting status of /System/Library/LaunchDaemons/com.apple.oahd.plist: Operation not permitted
/private/tmp/nix-build-foo.drv-0/.attr-0l2nkwhif96f51f4amnlf414lhl4rv9vh8iffyp431v6s28gsr90: line 1: 91536 Abort trap: 6           nix --version

The system log lists a number of sandbox denies, but the final one is

error	16:29:03.475029-0800	kernel	Sandbox: nix(91536) deny(1) file-read-metadata /System/Library/LaunchDaemons/com.apple.oahd.plist

Nix 2.4

Output:

libc++abi: terminating with uncaught exception of type nix::SysError: error: getting status of /nix/var/nix/profiles/per-user/root/channels/nixpkgs: Operation not permitted
/private/tmp/nix-build-foo.drv-0/.attr-0l2nkwhif96f51f4amnlf414lhl4rv9vh8iffyp431v6s28gsr90: line 1: 91674 Abort trap: 6           nix --version

Again a number of denies in the system log, but the final one is

error	16:34:55.228713-0800	kernel	Sandbox: nix(91707) deny(1) file-read-metadata /nix/var/nix/profiles/per-user/root/channels

Expected behavior

This should work.

nix --version output

I've tested both with Nix 2.4 and Nix 2.5.1 as the driver, and the above repro steps use both Nix 2.4 and Nix 2.5.1 in the build command.

Additional context

I'm using a multi-user install on macOS. I don't know if anything differs in a single-user install.

@lilyball
Copy link
Member Author

Nix 2.5.1 appears to be checking for /System/Library/LaunchDaemons/com.apple.oahd.plist (and /Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist) to determine if Rosetta 2 is installed in order to adjust its default extraPlatforms. Given this, it really needs to include these paths in the default sandboxPaths for darwin, or perhaps unconditionally add them as extra paths (so that way me setting sandbox-paths doesn't break Rosetta 2 detection).

Adding that manually reproduces the Nix 2.4 failure, which I believe is due to nix-path now being a config option and having the default value include /nix/var/nix/profiles/per-user/root/channels{,/nixpkgs}.

In both cases, the actual solution may be to add these as __propagatedImpureHostDeps on the nix derivation and to update the default allowedImpureHostPrefixes accordingly. It already includes /System/Library, but not /Library/Apple/System/Library or /nix/var/nix/profiles/per-user/root/channels.

It's also worth considering if pathExists() should treat EPERM/EACCES (I'm not sure which particular errno is used for sandbox violations) the same as ENOENT. Otherwise a user could break Nix just by mucking with permissions appropriately e.g. by running sudo chmod o-rx /nix/var/nix/profiles/per-user/root (I just tested, this does indeed break Nix). My worry with doing this is it means any future sandbox violations may go unnoticed, but it's probably a good idea anyway so that way permissions problems don't break Nix.

@lilyball
Copy link
Member Author

lilyball commented Feb 2, 2022

This also breaks compiling Nix itself, as it invokes itself in order to build its manual.

@lilyball lilyball changed the title nix --version violates the macOS sandbox in Nix 2.4 and later Invoking nix in a derivation's build script violates the macOS sandbox in Nix 2.4 and later Feb 2, 2022
@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/nix-macos-sandbox-issues-in-nix-2-4-and-later/17475/1

@lilyball
Copy link
Member Author

lilyball commented Feb 2, 2022

Regarding __propagatedImpureHostDeps I think I misremembered how that works. Adding the paths Nix needs to that would be good of course, but it would need corresponding changes to the default allowed-impure-host-deps config setting for Darwin. Alternatively Nix could just punch a specific hole in the sandbox for any paths it needs (e.g. /System/Library/LaunchDaemons/com.apple.oahd.plist) regardless of config, but that feels ugly, much better to just put /Library/Apple into the default allowed-impure-host-deps and then have Nix declare that it needs (propagated) access to {/Library/Apple,}/System/Library/LaunchDaemons/com.apple.oahd.plist.

Also I'm not sure if Nix actually needs access to /nix/var/nix/profiles/per-user/root/channels for some reason, I'm guessing not, so that can probably be omitted here in favor of just having pathExists() not throw an exception on a permissions error.

@lilyball
Copy link
Member Author

This was marked as fixed due to #6812, but was anything done about the /nix/var/nix/profiles/per-user/root/channels issue?

@lilyball
Copy link
Member Author

I think that's still an issue. I just tested like so:

nix build --impure --expr 'with import (builtins.getFlake "github:NixOS/nixpkgs/nixpkgs-unstable") {}; runCommand "foo" { nativeBuildInputs = [ (builtins.getFlake "github:NixOS/nix").packages.${builtins.currentSystem}.default ]; } "nix --version"'
error: builder for '/nix/store/0ii2rqvqsgk343gg5b9a8z20qdvlpf8y-foo.drv' failed with exit code 134;
       last 2 log lines:
       > libc++abi: terminating with uncaught exception of type nix::SysError: error: getting status of /nix/var/nix/profiles/per-user/root/channels/nixpkgs: Operation not permitted
       > /private/tmp/nix-build-foo.drv-0/.attr-0l2nkwhif96f51f4amnlf414lhl4rv9vh8iffyp431v6s28gsr90: line 1: 11683 Abort trap: 6           nix --version
       For full logs, run 'nix log /nix/store/0ii2rqvqsgk343gg5b9a8z20qdvlpf8y-foo.drv'.

The Nix being run here is nix (Nix) 2.10.0pre20220728_86fcd4f so that includes #6812.

@mkenigs
Copy link
Contributor

mkenigs commented Sep 19, 2022

Also running into the /nix/var/nix/profiles/per-user/root/channels issue

@winterqt
Copy link
Member

I can also reproduce this. My "host" Nix is 2.12.0, while the Nix I'm executing (via tests) is 145e9a8.

@thufschmitt
Copy link
Member

Reopening since the fix PR didn't fix everything. Hopefully #5226 should fix at least most of it, but maybe not all.

@ncfavier
Copy link
Member

#7689 should also help by making it possible to turn off the default nix path using --restrict-eval.

@thufschmitt
Copy link
Member

#7689 should have fixed this, so I'll close. Feel free to comment/reopen if the issue still occurs.

Minion3665 pushed a commit to Minion3665/nix that referenced this issue Feb 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants