Add allow-new-privileges option

This allows builds to call setuid binaries. This was previously
possible until we started using seccomp. Turns out that seccomp by
default disallows processes from acquiring new privileges. Generally,
any use of setuid binaries (except those created by the builder
itself) is by definition impure, but some people were relying on this
ability for certain tests.

Example:

  $ nix build '(with import <nixpkgs> {}; runCommand "foo" {} "/run/wrappers/bin/ping -c 1 8.8.8.8; exit 1")' --no-allow-new-privileges
  builder for ‘/nix/store/j0nd8kv85hd6r4kxgnwzvr0k65ykf6fv-foo.drv’ failed with exit code 1; last 2 log lines:
    cannot raise the capability into the Ambient set
    : Operation not permitted

  $ nix build '(with import <nixpkgs> {}; runCommand "foo" {} "/run/wrappers/bin/ping -c 1 8.8.8.8; exit 1")' --allow-new-privileges
  builder for ‘/nix/store/j0nd8kv85hd6r4kxgnwzvr0k65ykf6fv-foo.drv’ failed with exit code 1; last 6 log lines:
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=15.2 ms

Fixes #1429.
This commit is contained in:
Eelco Dolstra 2017-07-04 15:43:06 +02:00
parent ad8b96f1f2
commit 6cf23c3e8f
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
3 changed files with 26 additions and 0 deletions

View file

@ -643,6 +643,23 @@ password <replaceable>my-password</replaceable>
</varlistentry> </varlistentry>
<varlistentry xml:id="conf-allow-new-privileges"><term><literal>allow-new-privileges</literal></term>
<listitem><para>(Linux-specific.) By default, builders on Linux
cannot acquire new privileges by calling setuid/setgid programs or
programs that have file capabilities. For example, programs such
as <command>sudo</command> or <command>ping</command> will
fail. (Note that in sandbox builds, no such programs are available
unless you bind-mount them into the sandbox via the
<option>build-sandbox-paths</option> option.) You can allow the
use of such programs by enabling this option. This is impure and
usually undesirable, but may be useful in certain scenarios
(e.g. to spin up containers or set up userspace network interfaces
in tests).</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>

View file

@ -2340,6 +2340,9 @@ void setupSeccomp()
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0) seccomp_rule_add(ctx, SCMP_ACT_ERRNO(ENOTSUP), SCMP_SYS(fsetxattr), 0) != 0)
throw SysError("unable to add seccomp rule"); throw SysError("unable to add seccomp rule");
if (seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, settings.allowNewPrivileges ? 0 : 1) != 0)
throw SysError("unable to set 'no new privileges' seccomp attribute");
if (seccomp_load(ctx) != 0) if (seccomp_load(ctx) != 0)
throw SysError("unable to load seccomp BPF program"); throw SysError("unable to load seccomp BPF program");
#endif #endif

View file

@ -321,6 +321,12 @@ public:
Setting<std::string> userAgentSuffix{this, "", "user-agent-suffix", Setting<std::string> userAgentSuffix{this, "", "user-agent-suffix",
"String appended to the user agent in HTTP requests."}; "String appended to the user agent in HTTP requests."};
#if __linux__
Setting<bool> allowNewPrivileges{this, false, "allow-new-privileges",
"Whether builders can acquire new privileges by calling programs with "
"setuid/setgid bits or with file capabilities."};
#endif
}; };