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

Inconsistent treatment of /usr/bin/env in build sandbox vs. NixOS #1205

Open
copumpkin opened this issue Jan 25, 2017 · 26 comments
Open

Inconsistent treatment of /usr/bin/env in build sandbox vs. NixOS #1205

copumpkin opened this issue Jan 25, 2017 · 26 comments
Assignees
Labels
UX The way in which users interact with Nix. Higher level than UI.

Comments

@copumpkin
Copy link
Member

copumpkin commented Jan 25, 2017

I always assumed that since NixOS went out of its way to create a /usr/bin/env, that it would be available inside a sandboxed build as well, but that appears not to be the case.

It seems like we should have a "Nix contract", basically stating things like: you can expect to have GNU coreutils, find, sed, impure /bin/sh, /dev/null, etc.

Then we make NixOS satisfy that contract (by adding /bin/sh) and we make the sandboxed builder environment satisfy it too. It's unclear to me whether /usr/bin/env belongs in that contract or not, but it does seem pretty confusing that it's in one place and not the other.

cc @edolstra @shlevy

@shlevy
Copy link
Member

shlevy commented Jan 26, 2017

IMO this isn't a nix issue. It's part of your stdenv what kinds of things you expect to be available (and ideally your sandbox could be configured at least in part accordingly). But I do agree we should have a specification here.

@bjornfor
Copy link
Contributor

Relevant: NixOS/nixpkgs#6227 ("chroot environments have no /usr/bin/env?").

@LnL7
Copy link
Member

LnL7 commented Jan 17, 2018

Is there a reason not to add it by default, like we do for /bin/sh? https://github.com/NixOS/nixpkgs/blob/08bf000fe2e385f2253428eef77f952e3dc187c5/nixos/modules/services/misc/nix-daemon.nix#L45

@copumpkin
Copy link
Member Author

I'd probably err on the side of making it consistent first (so adding /usr/bin/env to both), then perhaps making a separate effort to whittle down the impurities.

@timokau
Copy link
Member

timokau commented Jan 24, 2018

Does somebody know how it can be that /usr/bin/env seems to be available during sandboxed build on my machine, but not on others?

I'm currently trying to debug sage (NixOS/nixpkgs#31714). But I can't test it myself, since the build (with the same commands @siddharthist uses, including sandbox) works for me. Is that a bug?

@jtojnar
Copy link
Member

jtojnar commented Jan 25, 2018

@timokau I heard somewhere it is not possible to enable sandboxing using --option. Edit: See #1670

@vcunat
Copy link
Member

vcunat commented Feb 17, 2018

Purity idea: make the derivation primitive accept options that allow overriding /bin/sh value (perhaps also /usr/bin/env and others), and then we can just make stdenv pass them automatically, getting rid of this ugly impurity in nixpkgs. (They are almost always in build-time closure anyway.)

@matthewbauer
Copy link
Member

This is pretty annoying to hit. Because /usr/bin/env just runs what's in PATH, it seems like it should be safe to add. Can we just make it a default for sandboxPaths?

@infinisil
Copy link
Member

FWIW, NixOS has the (hidden) option environment.usrbinenv, with which you can turn off having an /usr/bin/env (by setting the option to null). Doing this makes NixOS less convenient, but it does prevent some impurities (e.g. a user packaging some python script for nixpkgs could easily forget to patch its /usr/bin/env python because they have python in their PATH)

@Ayplow
Copy link

Ayplow commented Oct 23, 2019

This seriously defeats the purpose of nix-shell --pure. Is it possible to make the pure option block it out?

@stale
Copy link

stale bot commented Feb 15, 2021

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

@stale stale bot added the stale label Feb 15, 2021
@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/what-is-the-patchshebangs-command-in-nix-build-expressions/12656/2

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/what-is-the-patchshebangs-command-in-nix-build-expressions/12656/1

@Radvendii
Copy link
Contributor

This is pretty annoying to hit. Because /usr/bin/env just runs what's in PATH, it seems like it should be safe to add. Can we just make it a default for sandboxPaths?

Indeed. Does anyone know why access to /usr/bin/env would cause impurities? I've asked in a couple of places and only gotten vague half-answers. It seems like not having it necessitates a lot of manual patchShebanging in preConfigure hooks.

@stale stale bot removed the stale label Apr 27, 2021
@grahamc
Copy link
Member

grahamc commented Apr 27, 2021

For starters, there is no reason that Nix should do what NixOS does, and visa versa. They're two independent projects.

Second, env is not a universal constant. Different envs behave differently. The macOS env and GNU env and busybox env and toybox env all behave differently with different features.

I'm -1 on providing env in the sandbox as an exception to the sandboxing rules.

@Radvendii
Copy link
Contributor

For starters, there is no reason that Nix should do what NixOS does, and visa versa.

Fair enough. There are plenty of things that NixOS has that I don't expect in a sandboxed environment. My reason for wanting it is just to simplify packages.

Second, env is not a universal constant. Different envs behave differently. The macOS env and GNU env and busybox env and toybox env all behave differently with different features.

I see. Is this not the case also for difference C compilers though? stdenv on Mac uses clang and on linux uses gcc. Are those more similar in terms of features / beahviour than different envs? Or is it just a question of trying to minimize those differences (a C compiler is necessary, env is evidently not, since we've gotten on without it).

Also, the use-case I'm thinking of (and it seems other people are also) is just simple shebangs. Could we put in a bare-bones env that searches $PATH for executables, but if you try to use it in more advanced ways that wouldn't be compatible between different envs, it fails with a helpful error message?

(I hope this doesn't come off as pushy, I'm just trying to problem-solve. At the end of the day I'm happy to defer to others' expertise.)

@grahamc
Copy link
Member

grahamc commented Apr 27, 2021 via email

@Radvendii
Copy link
Contributor

Radvendii commented Apr 27, 2021

It is the same as with C compilers, but Nix does not provide a C compiler impurely: Nixpkgs does, purely.

Ah. I think I understand the issue now. The Nix sandbox actually provides access to extremely few binaries on it's own, everything is brought in through nixpkgs (or something else, in theory). For instance, even if we wanted to, it wouldn't be possible to provide a symlink to ${coreutils}/bin/env because Nix doesn't know about coreutils. (this is what NixOS does to create /usr/bin/env)

Thanks.

@grahamc
Copy link
Member

grahamc commented Apr 27, 2021

Exactly!

@kevincox
Copy link

So it seems that we would need to add support to Nix to add paths to the sandbox. Then we can get rid of the hack in https://github.com/NixOS/nixpkgs/blob/08bf000fe2e385f2253428eef77f952e3dc187c5/nixos/modules/services/misc/nix-daemon.nix#L45. I guess the main concern is how this would work without sandboxing. Can we still create a mount namespace?

@grahamc
Copy link
Member

grahamc commented Apr 28, 2021

Then we can get rid of the hack

I'm not sure we can get rid of that, since at some point I think we need something like that for bootstrapping. Although perhaps being able to specify symlinks outside of /nix/store for the build sandbox might be interesting... but also I feel a can of worms that we might not want to open.

@kevincox
Copy link

since at some point I think we need something like that for bootstrapping

I don't see why. I'm not super familiar with the bootstrap cycle but it seems like we probably need a bash to build everything anyways. And the build shouldn't really se the difference between the host /bin/sh and a /bin/sh provided by the build itself.

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/what-is-sandboxing-and-what-does-it-entail/15533/1

@stale
Copy link

stale bot commented Apr 16, 2022

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

@stale stale bot added the stale label Apr 16, 2022
@fricklerhandwerk fricklerhandwerk added the UX The way in which users interact with Nix. Higher level than UI. label Sep 12, 2022
@bergkvist
Copy link
Member

bergkvist commented Jun 11, 2024

For those annoyed at having to patch shebangs in third party scripts, you can always do something like this to provide your own /usr/bin/env to your build sandbox instead.

{ pkgs ? import <nixpkgs> {}
}:
let
  usrBinEnvHook = pkgs.makeSetupHook { name = "usr-bin-env-hook"; } (pkgs.writeText "create-usr-bin-env.sh" ''
    mkdir -m 0755 -p /usr/bin
    ln -sfn "${pkgs.coreutils}/bin/env" /usr/bin/env
  '');
in
pkgs.runCommand "example" { buildInputs = [ usrBinEnvHook ]; } ''
  mkdir -p $out && cd $out
  ${./some-script-that-uses-usr-bin-env.sh}
''

I wonder, could it maybe make sense to provide this as part of nixpkgs? For example pkgs.usrBinEnvHook, pkgs.coreutils.usrBinEnvHook or pkgs.stdenv.usrBinEnvHook.

@nixos-discourse
Copy link

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

https://discourse.nixos.org/t/building-openwrt-as-derivation/39936/6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
UX The way in which users interact with Nix. Higher level than UI.
Projects
None yet
Development

No branches or pull requests