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

Run test to determine if sandboxing is available #3006

Merged
merged 4 commits into from
Aug 27, 2019

Conversation

matthewbauer
Copy link
Member

adds smEnabledIfAvailable option that will run a check where possible
to determine if user namespaces are supported.

Copy link
Member

@edolstra edolstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the exact use case for this? If it's systems that lack CLONE_NEWUSER, it's probably better to disable only CLONE_NEWUSER, rather than all sandboxing. So you could check whether clone succeeds with and without CLONE_NEWUSER.


int flags = CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD;
size_t stackSize = 1;
char* stack = malloc(stackSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to use std::make_unique<unsigned char[]>(stackSize);. Leaked mallocs pollute valgrind runs.

if (child == -1) {
printError("warning: test cloning failed, sandboxing is disabled");
useChroot = false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this whole test be done inside an std::once? Now we're forking an extra child process for every build.

@@ -11,7 +11,7 @@

namespace nix {

typedef enum { smEnabled, smRelaxed, smDisabled } SandboxMode;
typedef enum { smEnabled, smEnabledIfAvailable, smRelaxed, smDisabled } SandboxMode;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should be a separate flag, because you may want to use relaxed mode and disable the sandbox if unavailable.

kill(child, SIGKILL);

if (child == -1) {
printError("warning: test cloning failed, sandboxing is disabled");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a warn function since recently.

@matthewbauer
Copy link
Member Author

matthewbauer commented Jul 25, 2019

What's the exact use case for this? If it's systems that lack CLONE_NEWUSER, it's probably better to disable only CLONE_NEWUSER, rather than all sandboxing. So you could check whether clone succeeds with and without CLONE_NEWUSER.

That sounds like a better idea, if it works right. As a plus that would avoid having an extra "sandbox" setting as sandboxing would still be enabled (just without CLONE_NEWUSER). There are at least 3 patches for this in the wild that I can find:

It looks like they all only effect CLONE_NEWUSER. Some systems also disable CLONE_NEWNS.

Some kernels disable "unpriveleged user namespaces". This is
unfortunate, but we can still use mount namespaces. Anyway, since each
builder has its own nixbld user, we already have most of the benefits
of user namespaces.
When sandbox-fallback = true (the default), the Nix builder will fall
back to disabled sandbox mode when the kernel doesn’t allow users to
set it up. This prevents hard errors from occuring in tricky places,
especially the initial installer. To restore the previous behavior,
users can set:

  sandbox-fallback = false

in their /etc/nix/nix.conf configuration.
@edolstra
Copy link
Member

Looks good but I would be more comfortable with sandbox-fallback defaulting to false. The special handling for missing user namespaces is more important anyway.

@matthewbauer
Copy link
Member Author

matthewbauer commented Jul 30, 2019

Looks good but I would be more comfortable with sandbox-fallback defaulting to false. The special handling for missing user namespaces is more important anyway.

My main concern with sandbox-fallback = false is that we continue to have a lot of users not able to install Nix because the default sandbox doesn't work on their computers. See #2662, #2636, #2632, #2318

startProcess does not appear to send the exit code to the helper
correctly. Not sure why this is, but it is probably safe to just
fallback on all sandbox errors.
@grahamc
Copy link
Member

grahamc commented Jul 30, 2019

I also reported #3000 which is along the same lines. I'll run this PR through my nix install matrix.

@matthewbauer
Copy link
Member Author

matthewbauer commented Jul 30, 2019

This looks like it should be handled (WSL2), but I'm not sure how:

error: while setting up the build environment: mounting /proc: Operation not permitted
./install: unable to install Nix into your default profile

@grahamc
Copy link
Member

grahamc commented Jul 30, 2019

Note that #3000 actually isn't related to WSL.

@grahamc
Copy link
Member

grahamc commented Jul 31, 2019

2.2.2's default to enable the sandbox broke installation for:

  • centos6
  • centos7
  • debian8
  • debian9
  • gentoo
  • ubuntu12.04

each of these failed with one of two messages:

centos-6-install    installing 'nix-2.2.2'
centos-6-install    error: cloning builder process: Invalid argument
centos-6-install    error: unable to start build process
centos-6-install    /tmp/nix-binary-tarball-unpack.0e2oQ1HL9U/unpack/nix-2.2.2-x86_64-linux/install: unable to install Nix into your default profile

or:

debian-8-install    installing 'nix-2.2.2'
debian-8-install    error: cloning builder process: Operation not permitted
debian-8-install    error: unable to start build process
debian-8-install    /tmp/nix-binary-tarball-unpack.N6AiK3XbCd/unpack/nix-2.2.2-x86_64-linux/install: unable to install Nix into your default profile

After this PR, neither of these errors come up, but all six now fail with another error:

centos-7-install    installing 'nix-2.3pre6828_9a0855b'
centos-7-install    warning: Nix search path entry '/home/vagrant/.nix-defexpr/channels' does not exist, ignoring
centos-7-install    error: while setting up the build environment: changing into '/tmp/nix-build-user-environment.drv-0': No such file or directory
centos-7-install    ./nix/install: unable to install Nix into your default profile

Here are the install matrix's reports:

@grahamc
Copy link
Member

grahamc commented Aug 27, 2019

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

Successfully merging this pull request may close these issues.

3 participants