aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main
diff options
context:
space:
mode:
authorGravatar Philipp Wollermann <philwo@google.com>2017-03-24 12:05:07 +0000
committerGravatar Yue Gan <yueg@google.com>2017-03-24 12:20:37 +0000
commitd7b774bbef316a29c457771bd4309adc1a4bbdbd (patch)
tree1233c9c3339c9195bee1b966d9bb2ea85dad309b /src/main
parent7429648a3bf241becf38711f876201dd5c6c5cb5 (diff)
sandbox: No longer change the user to 'nobody' by default.
This can be reactivated by passing the --sandbox_fake_username flag to Bazel. Reasoning: 'nobody' has a non-existent home directory on many Linux distros, leading to issues when tools try to stat / read / write to the home directory. Related to #2688. RELNOTES: The Linux sandbox no longer changes the user to 'nobody' by default, instead the current user is used as is. The old behavior can be restored via the --sandbox_fake_username flag. -- PiperOrigin-RevId: 151115218 MOS_MIGRATED_REVID=151115218
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxRunner.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperRunner.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxOptions.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxRunner.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxStrategy.java3
-rw-r--r--src/main/tools/linux-sandbox-options.cc20
-rw-r--r--src/main/tools/linux-sandbox-options.h2
-rw-r--r--src/main/tools/linux-sandbox-pid1.cc13
-rw-r--r--src/main/tools/linux-sandbox.cc4
10 files changed, 67 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxRunner.java
index a297ebe4f9..471158a29e 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/DarwinSandboxRunner.java
@@ -108,7 +108,8 @@ final class DarwinSandboxRunner extends SandboxRunner {
Map<String, String> environment,
int timeout,
boolean allowNetwork,
- boolean useFakeHostname)
+ boolean useFakeHostname,
+ boolean useFakeUsername)
throws IOException {
writeConfig(allowNetwork);
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java
index 29d908415b..68d3f695bb 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxRunner.java
@@ -105,9 +105,10 @@ final class LinuxSandboxRunner extends SandboxRunner {
Map<String, String> env,
int timeout,
boolean allowNetwork,
- boolean useFakeHostname)
+ boolean useFakeHostname,
+ boolean useFakeUsername)
throws IOException {
- writeConfig(timeout, allowNetwork, useFakeHostname);
+ writeConfig(timeout, allowNetwork, useFakeHostname, useFakeUsername);
List<String> commandLineArgs = new ArrayList<>(3 + spawnArguments.size());
commandLineArgs.add(execRoot.getRelative("_bin/linux-sandbox").getPathString());
@@ -117,7 +118,8 @@ final class LinuxSandboxRunner extends SandboxRunner {
return new Command(commandLineArgs.toArray(new String[0]), env, sandboxExecRoot.getPathFile());
}
- private void writeConfig(int timeout, boolean allowNetwork, boolean useFakeHostname)
+ private void writeConfig(
+ int timeout, boolean allowNetwork, boolean useFakeHostname, boolean useFakeUsername)
throws IOException {
List<String> fileArgs = new ArrayList<>();
@@ -163,10 +165,15 @@ final class LinuxSandboxRunner extends SandboxRunner {
}
if (useFakeHostname) {
- // Use a fake hostname ("localhost") inside the sandbox when blocking network access.
+ // Use a fake hostname ("localhost") inside the sandbox.
fileArgs.add("-H");
}
+ if (useFakeUsername) {
+ // Use a fake username ("nobody") inside the sandbox.
+ fileArgs.add("-U");
+ }
+
FileSystemUtils.writeLinesAs(argumentsFilePath, StandardCharsets.ISO_8859_1, fileArgs);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperRunner.java
index b4102a7e22..f3ee9d14d1 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/ProcessWrapperRunner.java
@@ -58,7 +58,8 @@ final class ProcessWrapperRunner extends SandboxRunner {
Map<String, String> env,
int timeout,
boolean allowNetwork,
- boolean useFakeHostname) {
+ boolean useFakeHostname,
+ boolean useFakeUsername) {
List<String> commandLineArgs = new ArrayList<>(5 + spawnArguments.size());
commandLineArgs.add(execRoot.getRelative("_bin/process-wrapper").getPathString());
commandLineArgs.add(Integer.toString(timeout));
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxOptions.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxOptions.java
index 303ec0fc46..a7185f41fe 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxOptions.java
@@ -94,6 +94,14 @@ public class SandboxOptions extends OptionsBase {
public boolean sandboxFakeHostname;
@Option(
+ name = "sandbox_fake_username",
+ defaultValue = "false",
+ category = "strategy",
+ help = "Change the current username to 'nobody' for sandboxed actions."
+ )
+ public boolean sandboxFakeUsername;
+
+ @Option(
name = "sandbox_tmpfs_path",
allowMultiple = true,
defaultValue = "",
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxRunner.java
index 49d661d743..efa423e320 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxRunner.java
@@ -50,6 +50,7 @@ abstract class SandboxRunner {
* @param allowNetwork - whether networking should be allowed for the process.
* @param sandboxDebug - whether debugging message should be printed.
* @param useFakeHostname - whether the hostname should be set to 'localhost' inside the sandbox.
+ * @param useFakeUsername - whether the username should be set to 'nobody' inside the sandbox.
*/
void run(
List<String> arguments,
@@ -58,11 +59,14 @@ abstract class SandboxRunner {
int timeout,
boolean allowNetwork,
boolean sandboxDebug,
- boolean useFakeHostname)
+ boolean useFakeHostname,
+ boolean useFakeUsername)
throws ExecException {
Command cmd;
try {
- cmd = getCommand(arguments, environment, timeout, allowNetwork, useFakeHostname);
+ cmd =
+ getCommand(
+ arguments, environment, timeout, allowNetwork, useFakeHostname, useFakeUsername);
} catch (IOException e) {
throw new UserExecException("I/O error during sandboxed execution", e);
}
@@ -111,13 +115,15 @@ abstract class SandboxRunner {
* @param timeout - after how many seconds should the process be killed.
* @param allowNetwork - whether networking should be allowed for the process.
* @param useFakeHostname - whether the hostname should be set to 'localhost' inside the sandbox.
+ * @param useFakeUsername - whether the username should be set to 'nobody' inside the sandbox.
*/
protected abstract Command getCommand(
List<String> arguments,
Map<String, String> environment,
int timeout,
boolean allowNetwork,
- boolean useFakeHostname)
+ boolean useFakeHostname,
+ boolean useFakeUsername)
throws IOException;
/**
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxStrategy.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxStrategy.java
index ffa0ff4ee3..ba88c8fa54 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxStrategy.java
@@ -84,7 +84,8 @@ abstract class SandboxStrategy implements SandboxedSpawnActionContext {
Spawns.getTimeoutSeconds(spawn),
SandboxHelpers.shouldAllowNetwork(buildRequest, spawn),
sandboxOptions.sandboxDebug,
- sandboxOptions.sandboxFakeHostname);
+ sandboxOptions.sandboxFakeHostname,
+ sandboxOptions.sandboxFakeUsername);
} catch (ExecException e) {
execException = e;
}
diff --git a/src/main/tools/linux-sandbox-options.cc b/src/main/tools/linux-sandbox-options.cc
index 96354ec8ec..78831e6f03 100644
--- a/src/main/tools/linux-sandbox-options.cc
+++ b/src/main/tools/linux-sandbox-options.cc
@@ -73,7 +73,8 @@ static void Usage(char *program_name, const char *fmt, ...) {
" The -M option specifies which directory to mount, the -m option "
"specifies where to\n"
" -N if set, a new network namespace will be created\n"
- " -R if set, make the uid/gid be root, otherwise use nobody\n"
+ " -R if set, make the uid/gid be root\n"
+ " -U if set, make the uid/gid be nobody\n"
" -D if set, debug info will be printed\n"
" @FILE read newline-separated arguments from FILE\n"
" -- command to run inside sandbox, followed by arguments\n");
@@ -123,8 +124,8 @@ static void ParseCommandLine(unique_ptr<vector<char *>> args) {
int c;
bool source_specified;
- while ((c = getopt(args->size(), args->data(), ":CW:T:t:l:L:w:e:M:m:HNRD")) !=
- -1) {
+ while ((c = getopt(args->size(), args->data(),
+ ":CW:T:t:l:L:w:e:M:m:HNRUD")) != -1) {
if (c != 'M' && c != 'm') source_specified = false;
switch (c) {
case 'C':
@@ -200,8 +201,21 @@ static void ParseCommandLine(unique_ptr<vector<char *>> args) {
opt.create_netns = true;
break;
case 'R':
+ if (opt.fake_username) {
+ Usage(args->front(),
+ "The -R option cannot be used at the same time us the -U "
+ "option.");
+ }
opt.fake_root = true;
break;
+ case 'U':
+ if (opt.fake_root) {
+ Usage(args->front(),
+ "The -U option cannot be used at the same time us the -R "
+ "option.");
+ }
+ opt.fake_username = true;
+ break;
case 'D':
opt.debug = true;
break;
diff --git a/src/main/tools/linux-sandbox-options.h b/src/main/tools/linux-sandbox-options.h
index 5c78e46d31..daf1fd684e 100644
--- a/src/main/tools/linux-sandbox-options.h
+++ b/src/main/tools/linux-sandbox-options.h
@@ -46,6 +46,8 @@ struct Options {
bool create_netns;
// Pretend to be root inside the namespace (-R)
bool fake_root;
+ // Set the username inside the sandbox to 'nobody' (-U)
+ bool fake_username;
// Print debugging messages (-D)
bool debug;
// Command to run (--)
diff --git a/src/main/tools/linux-sandbox-pid1.cc b/src/main/tools/linux-sandbox-pid1.cc
index 76dccbad24..17a71432b9 100644
--- a/src/main/tools/linux-sandbox-pid1.cc
+++ b/src/main/tools/linux-sandbox-pid1.cc
@@ -120,8 +120,13 @@ static void SetupUserNamespace() {
}
}
- int inner_uid = 0, inner_gid = 0;
- if (!opt.fake_root) {
+ int inner_uid, inner_gid;
+ if (opt.fake_root) {
+ // Change our username to 'root'.
+ inner_uid = 0;
+ inner_gid = 0;
+ } else if (opt.fake_username) {
+ // Change our username to 'nobody'.
struct passwd *pwd = getpwnam("nobody");
if (pwd == NULL) {
DIE("unable to find passwd entry for user nobody")
@@ -129,6 +134,10 @@ static void SetupUserNamespace() {
inner_uid = pwd->pw_uid;
inner_gid = pwd->pw_gid;
+ } else {
+ // Do not change the username inside the sandbox.
+ inner_uid = global_outer_uid;
+ inner_gid = global_outer_gid;
}
WriteFile("/proc/self/uid_map", "%d %d 1\n", inner_uid, global_outer_uid);
diff --git a/src/main/tools/linux-sandbox.cc b/src/main/tools/linux-sandbox.cc
index 0d73174727..9d2fd01767 100644
--- a/src/main/tools/linux-sandbox.cc
+++ b/src/main/tools/linux-sandbox.cc
@@ -25,12 +25,14 @@
* - If the process takes longer than the timeout (-T), it will be killed with
* SIGTERM. If it does not exit within the grace period (-t), it all of its
* children will be killed with SIGKILL.
+ * - If option -R is passed, the process will run as user 'root'.
+ * - If option -U is passed, the process will run as user 'nobody'.
+ * - Otherwise, the process runs using the current uid / gid.
* - If linux-sandbox itself gets killed, the process and all of its children
* will be killed.
* - If linux-sandbox's parent dies, it will kill itself, the process and all
* the children.
* - Network access is allowed, but can be disabled via -N.
- * - The process runs as user "nobody", unless fakeroot is enabled (-R).
* - The hostname and domainname will be set to "sandbox".
* - The process runs in its own PID namespace, so other processes on the
* system are invisible.