Why does nixos patch rather than rely on namespacing?

Right now it’s probably too late, but historically, why didn’t NixOS rely on namespace (like buildFHSUserEnv - mount all dependencies bin files into your /usr/bin, lib into /usr/lib and /home/me into /home/me ) over patching?

Advantages of namespaces:

  1. Patching is brittle: For example, something like:

    #!/usr/bin/env python3.6
    
    from os import system
    let command1 = "w"
    let command2 = "g"
    let command3 = "e"
    let command4 = "t"
    system(command1 + command2 + command3 + command4 + "https://www.nixos.org")
    

    This is a blatant (and bad) example. But there are places where commands are built from strings, or programs that assume that commands are in path. And it makes packaging complicated software much easier and reliable - you don’t have to be scared that a patch broke firefox in an edge case - as far as firefox is concerned, you’re running a normal, FHS compliant system.

  2. It’s easier to ensure purity - For example, I can write a package that looks like:

    #!/usr/bin/env python3.6
    
    from os import system
    system("wget")
    

    which will work as long as wget is in systemPackages (and probably isn’t what you want).

  3. Security - Once packages are in a namespace, it should be easy to set a configuration of what directories to mount. Don’t want firefox to see “/home”? Easy, just don’t mount it in the namespace. Don’t want apache to see anything? Easy, don’t mount anything.

The only dis advantage that I see is that namespacing takes a bit of time. But on the other hand, on my system, a failed chroot takes 0.002 seconds.

Right now it’s probably too late, but historically, why didn’t NixOS rely on namespace (like buildFHSUserEnv - mount all dependencies bin files into your /usr/bin, lib into /usr/lib and /home/me into /home/me ) over patching?

  1. I think Nix is older than reliable namespace support in Linux

  2. Unprivileged namespaces are still not available on many Linux distributions where Nix works with patching approach

  3. At all time Nix supported some non-Linux platforms

Advantages of namespaces:

  1. Patching is brittle: For example, something like:

Namespacing is also brittle once two different dependencies would want to shell out to different commands with the same name. With patching we have a chance to succeed.

  1. It’s easier to ensure purity - For example, I can write a package that looks like:

I defeinitely agree.

  1. Security - Once packages are in a namespace, it should be easy to set a configuration of what directories to mount. Don’t want firefox to see “/home”? Easy, just don’t mount it in the namespace. Don’t want apache to see anything? Easy, don’t mount anything.

We ship firejail, nsjail and more — if you want to use namespaces for sandboxing, you are welcome to do it (I do use nsjail for that). Once you want to configure the sandbox on the user level, what benefit do you have from the packages also providing some sandboxing (that needs to avoid breakage when combined with user-configured level of sandboxing)?

1 Like

This one is especially important. Darwin is a first-class platform for Nix, and Darwin does not support namespacing. There are other supported platforms without namespacing too, but Nix explictly advertises macOS support.

That being said, we do depend a lot of small launcher scripts to pin runtime dependencies. They play a similar-but-not-as-precise role as the sandboxes. (wrapProgram has 1000+ entries in nixpkgs). It would be cool if the wrapper scripts had a --please-sandbox flag that would also do the whole unshare mount namespacing thing.