aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java6
-rw-r--r--src/main/tools/namespace-sandbox.c278
-rw-r--r--src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java3
4 files changed, 161 insertions, 150 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
index 989190554c..cc9acf66d9 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
@@ -70,33 +70,30 @@ import java.util.concurrent.atomic.AtomicInteger;
public class LinuxSandboxedStrategy implements SpawnActionContext {
private final ExecutorService backgroundWorkers;
+ private final SandboxOptions sandboxOptions;
private final ImmutableMap<String, String> clientEnv;
private final BlazeDirectories blazeDirs;
private final Path execRoot;
private final boolean verboseFailures;
- private final boolean sandboxDebug;
private final boolean unblockNetwork;
- private final List<String> sandboxAddPath;
private final UUID uuid = UUID.randomUUID();
private final AtomicInteger execCounter = new AtomicInteger();
private final String productName;
public LinuxSandboxedStrategy(
+ SandboxOptions options,
Map<String, String> clientEnv,
BlazeDirectories blazeDirs,
ExecutorService backgroundWorkers,
boolean verboseFailures,
- boolean sandboxDebug,
- List<String> sandboxAddPath,
boolean unblockNetwork,
String productName) {
+ this.sandboxOptions = options;
this.clientEnv = ImmutableMap.copyOf(clientEnv);
this.blazeDirs = blazeDirs;
this.execRoot = blazeDirs.getExecRoot();
this.backgroundWorkers = Preconditions.checkNotNull(backgroundWorkers);
this.verboseFailures = verboseFailures;
- this.sandboxDebug = sandboxDebug;
- this.sandboxAddPath = sandboxAddPath;
this.unblockNetwork = unblockNetwork;
this.productName = productName;
}
@@ -136,9 +133,9 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
Path sandboxPath =
execRoot.getRelative(productName + "-sandbox").getRelative(execId);
+ // Gather all necessary mounts for the sandbox.
ImmutableMap<Path, Path> mounts;
try {
- // Gather all necessary mounts for the sandbox.
mounts = getMounts(spawn, actionExecutionContext);
} catch (IllegalArgumentException | IOException e) {
throw new EnvironmentalExecException("Could not prepare mounts for sandbox execution", e);
@@ -148,7 +145,7 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
int timeout = getTimeout(spawn);
- ImmutableSet.Builder<PathFragment> outputFiles = ImmutableSet.<PathFragment>builder();
+ ImmutableSet.Builder<PathFragment> outputFiles = ImmutableSet.builder();
for (PathFragment optionalOutput : spawn.getOptionalOutputFiles()) {
Preconditions.checkArgument(!optionalOutput.isAbsolute());
outputFiles.add(optionalOutput);
@@ -160,7 +157,12 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
try {
final NamespaceSandboxRunner runner =
new NamespaceSandboxRunner(
- execRoot, sandboxPath, mounts, createDirs, verboseFailures, sandboxDebug);
+ execRoot,
+ sandboxPath,
+ mounts,
+ createDirs,
+ verboseFailures,
+ sandboxOptions.sandboxDebug);
try {
runner.run(
spawn.getArguments(),
@@ -529,7 +531,7 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
ImmutableList<Path> exclude =
ImmutableList.of(blazeDirs.getWorkspace(), blazeDirs.getOutputBase());
- for (String pathStr : sandboxAddPath) {
+ for (String pathStr : sandboxOptions.sandboxAddPath) {
Path path = fs.getPath(pathStr);
// Check if path is in {workspace, outputBase}
@@ -611,6 +613,6 @@ public class LinuxSandboxedStrategy implements SpawnActionContext {
@Override
public boolean shouldPropagateExecException() {
- return verboseFailures && sandboxDebug;
+ return verboseFailures && sandboxOptions.sandboxDebug;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
index a1f6134ff0..e6e462318a 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
@@ -23,7 +23,6 @@ import com.google.devtools.build.lib.exec.ExecutionOptions;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.util.OS;
-import java.util.List;
import java.util.concurrent.ExecutorService;
/**
@@ -37,24 +36,21 @@ public class SandboxActionContextProvider extends ActionContextProvider {
public SandboxActionContextProvider(
CommandEnvironment env, BuildRequest buildRequest, ExecutorService backgroundWorkers) {
boolean verboseFailures = buildRequest.getOptions(ExecutionOptions.class).verboseFailures;
- boolean sandboxDebug = buildRequest.getOptions(SandboxOptions.class).sandboxDebug;
boolean unblockNetwork =
buildRequest
.getOptions(BuildConfiguration.Options.class)
.testArguments
.contains("--wrapper_script_flag=--debug");
- List<String> sandboxAddPath = buildRequest.getOptions(SandboxOptions.class).sandboxAddPath;
Builder<ActionContext> strategies = ImmutableList.builder();
if (OS.getCurrent() == OS.LINUX) {
strategies.add(
new LinuxSandboxedStrategy(
+ buildRequest.getOptions(SandboxOptions.class),
env.getClientEnv(),
env.getDirectories(),
backgroundWorkers,
verboseFailures,
- sandboxDebug,
- sandboxAddPath,
unblockNetwork,
env.getRuntime().getProductName()));
}
diff --git a/src/main/tools/namespace-sandbox.c b/src/main/tools/namespace-sandbox.c
index 3206ad5510..580225da91 100644
--- a/src/main/tools/namespace-sandbox.c
+++ b/src/main/tools/namespace-sandbox.c
@@ -39,40 +39,44 @@
#define PRINT_DEBUG(...) \
do { \
- if (global_debug) { \
+ if (opt.debug) { \
fprintf(stderr, __FILE__ ":" S__LINE__ ": " __VA_ARGS__); \
} \
} while (0)
-static bool global_debug = false;
-static double global_kill_delay;
-static int global_child_pid;
-static volatile sig_atomic_t global_signal;
-
// The username of 'nobody'.
static const char *kNobodyUsername = "nobody";
// Options parsing result.
struct Options {
- double timeout_secs; // How long to wait before killing the child (-T)
- double kill_delay_secs; // How long to wait before sending SIGKILL in case of
- // timeout (-t)
- const char *stdout_path; // Where to redirect stdout (-l)
- const char *stderr_path; // Where to redirect stderr (-L)
- char *const *args; // Command to run (--)
const char *sandbox_root; // Sandbox root (-S)
const char *working_dir; // Working directory (-W)
+ double timeout_secs; // How long to wait before killing the child (-T)
+ double kill_delay_secs; // How long to wait before sending SIGKILL in case of
+ // timeout (-t)
+
+ char **create_dirs; // empty dirs to create (-d)
+ size_t create_dirs_size; // How many elements in create_dirs
+ int num_create_dirs; // How many empty dirs to create were specified
+
char **mount_sources; // Map of directories to mount, from (-M)
char **mount_targets; // sources -> targets (-m)
size_t mount_map_sizes; // How many elements in mount_{sources,targets}
int num_mounts; // How many mounts were specified
- char **create_dirs; // empty dirs to create (-d)
- size_t create_dirs_size; // How many elements in create_dirs
- int num_create_dirs; // How many empty dirs to create were specified
- int fake_root; // Pretend to be root inside the namespace.
- int create_netns; // If 1, create a new network namespace.
+
+ int create_netns; // If 1, create a new network namespace (-n)
+ int fake_root; // Pretend to be root inside the namespace (-r)
+ bool debug; // Whether to print debugging messages (-D)
+ const char *stdout_path; // Where to redirect stdout (-l)
+ const char *stderr_path; // Where to redirect stderr (-L)
+ char *const *args; // Command to run (--)
};
+static int global_child_pid;
+static volatile sig_atomic_t global_signal;
+
+static struct Options opt;
+
// Child function used by CheckNamespacesSupported() in call to clone().
static int CheckNamespacesSupportedChild(void *arg) { return 0; }
@@ -151,54 +155,56 @@ static void Usage(int argc, char *const *argv, const char *fmt, ...) {
// Deals with an unfinished (source but no target) mapping in opt.
// Also adds a new unfinished mapping if source is not NULL.
-static void AddMountSource(char *source, struct Options *opt) {
+static void AddMountSource(char *source) {
// The last -M flag wasn't followed by an -m flag, so assume that the source
// should be mounted in the sandbox in the same path as outside.
- if (opt->mount_sources[opt->num_mounts] != NULL) {
- opt->mount_targets[opt->num_mounts] = opt->mount_sources[opt->num_mounts];
- opt->num_mounts++;
+ if (opt.mount_sources[opt.num_mounts] != NULL) {
+ opt.mount_targets[opt.num_mounts] = opt.mount_sources[opt.num_mounts];
+ opt.num_mounts++;
}
+
if (source != NULL) {
- if (opt->num_mounts >= opt->mount_map_sizes - 1) {
- opt->mount_sources = realloc(opt->mount_sources,
- opt->mount_map_sizes * sizeof(char *) * 2);
- if (opt->mount_sources == NULL) {
+ if (opt.num_mounts >= opt.mount_map_sizes - 1) {
+ opt.mount_sources =
+ realloc(opt.mount_sources, opt.mount_map_sizes * sizeof(char *) * 2);
+ if (opt.mount_sources == NULL) {
DIE("realloc failed\n");
}
- memset(opt->mount_sources + opt->mount_map_sizes, 0,
- opt->mount_map_sizes * sizeof(char *));
- opt->mount_targets = realloc(opt->mount_targets,
- opt->mount_map_sizes * sizeof(char *) * 2);
- if (opt->mount_targets == NULL) {
+ memset(opt.mount_sources + opt.mount_map_sizes, 0,
+ opt.mount_map_sizes * sizeof(char *));
+ opt.mount_targets =
+ realloc(opt.mount_targets, opt.mount_map_sizes * sizeof(char *) * 2);
+ if (opt.mount_targets == NULL) {
DIE("realloc failed\n");
}
- memset(opt->mount_targets + opt->mount_map_sizes, 0,
- opt->mount_map_sizes * sizeof(char *));
- opt->mount_map_sizes *= 2;
+ memset(opt.mount_targets + opt.mount_map_sizes, 0,
+ opt.mount_map_sizes * sizeof(char *));
+ opt.mount_map_sizes *= 2;
}
- opt->mount_sources[opt->num_mounts] = source;
+ opt.mount_sources[opt.num_mounts] = source;
}
}
-static void AddCreateDir(char *create_dir, struct Options *opt) {
- if (opt->num_create_dirs > opt->create_dirs_size - 1) {
- opt->create_dirs =
- realloc(opt->create_dirs, opt->create_dirs_size * sizeof(char *) * 2);
- if (opt->create_dirs == NULL) {
+static void AddCreateDir(char *create_dir) {
+ if (opt.num_create_dirs > opt.create_dirs_size - 1) {
+ opt.create_dirs =
+ realloc(opt.create_dirs, opt.create_dirs_size * sizeof(char *) * 2);
+ if (opt.create_dirs == NULL) {
DIE("realloc failed\n");
}
- memset(opt->create_dirs + opt->create_dirs_size, 0,
- opt->create_dirs_size * sizeof(char *));
- opt->create_dirs_size *= 2;
+ memset(opt.create_dirs + opt.create_dirs_size, 0,
+ opt.create_dirs_size * sizeof(char *));
+ opt.create_dirs_size *= 2;
}
- opt->create_dirs[opt->num_create_dirs++] = create_dir;
+
+ opt.create_dirs[opt.num_create_dirs++] = create_dir;
}
-static void ParseCommandLine(int argc, char *const *argv, struct Options *opt);
+static void ParseCommandLine(int argc, char *const *argv);
// Parses command line flags from a file named filename.
// Expects optind to be initialized to 0 before being called.
-static void ParseOptionsFile(const char *filename, struct Options *opt) {
+static void ParseOptionsFile(const char *filename) {
FILE *const options_file = fopen(filename, "rb");
if (options_file == NULL) {
DIE("opening argument file %s failed\n", filename);
@@ -247,24 +253,25 @@ static void ParseOptionsFile(const char *filename, struct Options *opt) {
}
sub_argv[sub_argc] = NULL;
- ParseCommandLine(sub_argc, sub_argv, opt);
+ ParseCommandLine(sub_argc, sub_argv);
}
-// Parse the command line flags and return the result in an Options structure
-// passed as argument.
-static void ParseCommandLine(int argc, char *const *argv, struct Options *opt) {
+// Parses command line flags from an argv array and puts the results into an
+// Options structure
+// passed in as an argument.
+static void ParseCommandLine(int argc, char *const *argv) {
extern char *optarg;
extern int optind, optopt;
int c;
- while ((c = getopt(argc, argv, ":CDd:l:L:m:M:nrt:T:S:W:")) != -1) {
+ while ((c = getopt(argc, argv, ":CS:W:T:t:d:M:m:nrDl:L:")) != -1) {
switch (c) {
case 'C':
// Shortcut for the "does this system support sandboxing" check.
exit(CheckNamespacesSupported());
break;
case 'S':
- if (opt->sandbox_root == NULL) {
+ if (opt.sandbox_root == NULL) {
char *sandbox_root = strdup(optarg);
// Make sure that the sandbox_root path has no trailing slash.
@@ -272,33 +279,32 @@ static void ParseCommandLine(int argc, char *const *argv, struct Options *opt) {
sandbox_root[strlen(sandbox_root) - 1] = 0;
}
- opt->sandbox_root = sandbox_root;
+ opt.sandbox_root = sandbox_root;
} else {
Usage(argc, argv,
"Multiple sandbox roots (-S) specified, expected one.");
}
break;
case 'W':
- if (opt->working_dir == NULL) {
- opt->working_dir = optarg;
+ if (opt.working_dir == NULL) {
+ opt.working_dir = strdup(optarg);
} else {
Usage(argc, argv,
- "Multiple working directories (-W) specified, expected at most "
- "one.");
- }
- break;
- case 't':
- if (sscanf(optarg, "%lf", &opt->kill_delay_secs) != 1 ||
- opt->kill_delay_secs < 0) {
- Usage(argc, argv, "Invalid kill delay (-t) value: %lf",
- opt->kill_delay_secs);
+ "Multiple working directories (-W) specified, expected one.");
}
break;
case 'T':
- if (sscanf(optarg, "%lf", &opt->timeout_secs) != 1 ||
- opt->timeout_secs < 0) {
+ if (sscanf(optarg, "%lf", &opt.timeout_secs) != 1 ||
+ opt.timeout_secs < 0) {
Usage(argc, argv, "Invalid timeout (-T) value: %lf",
- opt->timeout_secs);
+ opt.timeout_secs);
+ }
+ break;
+ case 't':
+ if (sscanf(optarg, "%lf", &opt.kill_delay_secs) != 1 ||
+ opt.kill_delay_secs < 0) {
+ Usage(argc, argv, "Invalid kill delay (-t) value: %lf",
+ opt.kill_delay_secs);
}
break;
case 'd':
@@ -306,45 +312,45 @@ static void ParseCommandLine(int argc, char *const *argv, struct Options *opt) {
Usage(argc, argv,
"The -d option must be used with absolute paths only.");
}
- AddCreateDir(optarg, opt);
+ AddCreateDir(optarg);
break;
case 'M':
if (optarg[0] != '/') {
Usage(argc, argv,
"The -M option must be used with absolute paths only.");
}
- AddMountSource(optarg, opt);
+ AddMountSource(optarg);
break;
case 'm':
if (optarg[0] != '/') {
Usage(argc, argv,
"The -m option must be used with absolute paths only.");
}
- if (opt->mount_sources[opt->num_mounts] == NULL) {
+ if (opt.mount_sources[opt.num_mounts] == NULL) {
Usage(argc, argv, "The -m option must be preceded by an -M option.");
}
- opt->mount_targets[opt->num_mounts++] = optarg;
+ opt.mount_targets[opt.num_mounts++] = optarg;
break;
case 'n':
- opt->create_netns = 1;
+ opt.create_netns = 1;
break;
case 'r':
- opt->fake_root = 1;
+ opt.fake_root = 1;
break;
case 'D':
- global_debug = true;
+ opt.debug = true;
break;
case 'l':
- if (opt->stdout_path == NULL) {
- opt->stdout_path = optarg;
+ if (opt.stdout_path == NULL) {
+ opt.stdout_path = optarg;
} else {
Usage(argc, argv,
"Cannot redirect stdout to more than one destination.");
}
break;
case 'L':
- if (opt->stderr_path == NULL) {
- opt->stderr_path = optarg;
+ if (opt.stderr_path == NULL) {
+ opt.stderr_path = optarg;
} else {
Usage(argc, argv,
"Cannot redirect stderr to more than one destination.");
@@ -359,25 +365,47 @@ static void ParseCommandLine(int argc, char *const *argv, struct Options *opt) {
}
}
- AddMountSource(NULL, opt);
+ AddMountSource(NULL);
while (optind < argc && argv[optind][0] == '@') {
const char *filename = argv[optind] + 1;
const int old_optind = optind;
optind = 0;
- ParseOptionsFile(filename, opt);
+ ParseOptionsFile(filename);
optind = old_optind + 1;
}
if (argc > optind) {
- if (opt->args == NULL) {
- opt->args = argv + optind;
+ if (opt.args == NULL) {
+ opt.args = argv + optind;
} else {
Usage(argc, argv, "Merging commands not supported.");
}
}
}
+// Handles parsing all command line flags and populates the global opt struct.
+static void ParseOptions(int argc, char *const argv[]) {
+ memset(&opt, 0, sizeof(opt));
+ // 16 elements is a sane default, will be realloc'd as needed anyway.
+ opt.mount_sources = calloc(16, sizeof(char *));
+ opt.mount_targets = calloc(16, sizeof(char *));
+ opt.mount_map_sizes = 16;
+ // We'll need at least two slots for homedir_from_env and homedir.
+ opt.create_dirs = calloc(2, sizeof(char *));
+ opt.create_dirs_size = 2;
+
+ ParseCommandLine(argc, argv);
+
+ if (opt.args == NULL) {
+ Usage(argc, argv, "No command specified.");
+ }
+
+ if (opt.sandbox_root == NULL) {
+ Usage(argc, argv, "Sandbox root (-S) must be specified");
+ }
+}
+
static void CreateNamespaces(int create_netns) {
// This weird workaround is necessary due to unshare seldomly failing with
// EINVAL due to a race condition in the Linux kernel (see
@@ -486,26 +514,26 @@ static int rmrf(const char *fpath, const struct stat *sb, int typeflag,
}
}
-static void SetupDirectories(struct Options *opt) {
+static void SetupDirectories() {
// If in sandbox_debug mode and debugging, create the sandbox root dir first
- if (global_debug && isatty(fileno(stdin))) {
+ if (opt.debug && isatty(fileno(stdin))) {
// Enter sandbox_debug mode a second time, delete old sandbox
struct stat sb;
- int err = stat(opt->sandbox_root, &sb);
+ int err = stat(opt.sandbox_root, &sb);
if (err == 0) {
- CHECK_CALL(nftw(opt->sandbox_root, *rmrf, sysconf(_SC_OPEN_MAX),
+ CHECK_CALL(nftw(opt.sandbox_root, *rmrf, sysconf(_SC_OPEN_MAX),
FTW_DEPTH | FTW_PHYS));
} else if (errno != ENOENT) {
CHECK_CALL(err);
}
- CHECK_CALL(mkdir(opt->sandbox_root, 0755));
+ CHECK_CALL(mkdir(opt.sandbox_root, 0755));
}
// Mount the sandbox and go there.
- CHECK_CALL(mount(opt->sandbox_root, opt->sandbox_root, NULL,
+ CHECK_CALL(mount(opt.sandbox_root, opt.sandbox_root, NULL,
MS_BIND | MS_NOSUID, NULL));
- CHECK_CALL(chdir(opt->sandbox_root));
+ CHECK_CALL(chdir(opt.sandbox_root));
// This is used as the base for hardlinking the input files.
CHECK_CALL(CreateTarget("tmp", true));
@@ -526,7 +554,7 @@ static void SetupDirectories(struct Options *opt) {
homedir_from_env);
}
if (strcmp(homedir_from_env, "/") != 0) {
- AddCreateDir(homedir_from_env, opt);
+ AddCreateDir(homedir_from_env);
}
}
@@ -548,48 +576,48 @@ static void SetupDirectories(struct Options *opt) {
homedir);
}
if (strcmp(homedir, "/") != 0) {
- AddCreateDir(homedir, opt);
+ AddCreateDir(homedir);
}
}
// Create needed directories.
- for (int i = 0; i < opt->num_create_dirs; i++) {
- if (global_debug) {
- PRINT_DEBUG("createdir: %s\n", opt->create_dirs[i]);
+ for (int i = 0; i < opt.num_create_dirs; i++) {
+ if (opt.debug) {
+ PRINT_DEBUG("createdir: %s\n", opt.create_dirs[i]);
}
- CHECK_CALL(CreateTarget(opt->create_dirs[i] + 1, true));
+ CHECK_CALL(CreateTarget(opt.create_dirs[i] + 1, true));
}
// Mount all mounts.
- for (int i = 0; i < opt->num_mounts; i++) {
+ for (int i = 0; i < opt.num_mounts; i++) {
struct stat sb;
- stat(opt->mount_sources[i], &sb);
+ stat(opt.mount_sources[i], &sb);
- if (global_debug) {
- if (strcmp(opt->mount_sources[i], opt->mount_targets[i]) == 0) {
+ if (opt.debug) {
+ if (strcmp(opt.mount_sources[i], opt.mount_targets[i]) == 0) {
// The file is mounted to the same path inside the sandbox, as outside
// (e.g. /home/user -> <sandbox>/home/user), so we'll just show a
// simplified version of the mount command.
- PRINT_DEBUG("mount: %s\n", opt->mount_sources[i]);
+ PRINT_DEBUG("mount: %s\n", opt.mount_sources[i]);
} else {
// The file is mounted to a custom location inside the sandbox.
// Create a user-friendly string for the sandboxed path and show it.
char *user_friendly_mount_target =
- malloc(strlen("<sandbox>") + strlen(opt->mount_targets[i]) + 1);
+ malloc(strlen("<sandbox>") + strlen(opt.mount_targets[i]) + 1);
strcpy(user_friendly_mount_target, "<sandbox>");
- strcat(user_friendly_mount_target, opt->mount_targets[i]);
- PRINT_DEBUG("mount: %s -> %s\n", opt->mount_sources[i],
+ strcat(user_friendly_mount_target, opt.mount_targets[i]);
+ PRINT_DEBUG("mount: %s -> %s\n", opt.mount_sources[i],
user_friendly_mount_target);
free(user_friendly_mount_target);
}
}
char *full_sandbox_path =
- malloc(strlen(opt->sandbox_root) + strlen(opt->mount_targets[i]) + 1);
- strcpy(full_sandbox_path, opt->sandbox_root);
- strcat(full_sandbox_path, opt->mount_targets[i]);
+ malloc(strlen(opt.sandbox_root) + strlen(opt.mount_targets[i]) + 1);
+ strcpy(full_sandbox_path, opt.sandbox_root);
+ strcat(full_sandbox_path, opt.mount_targets[i]);
CHECK_CALL(CreateTarget(full_sandbox_path, S_ISDIR(sb.st_mode)));
- CHECK_CALL(mount(opt->mount_sources[i], full_sandbox_path, NULL,
+ CHECK_CALL(mount(opt.mount_sources[i], full_sandbox_path, NULL,
MS_REC | MS_BIND | MS_RDONLY, NULL));
free(full_sandbox_path);
}
@@ -647,7 +675,7 @@ static void SetupUserNamespaceForNobody(int uid, int gid) {
SetupUserNamespace(uid, gid, pwd->pw_uid, pwd->pw_gid);
}
-static void ChangeRoot(struct Options *opt) {
+static void ChangeRoot() {
// move the real root to old_root, then detach it
char old_root[16] = "old-root-XXXXXX";
if (mkdtemp(old_root) == NULL) {
@@ -661,8 +689,8 @@ static void ChangeRoot(struct Options *opt) {
CHECK_CALL(umount2(old_root, MNT_DETACH));
CHECK_CALL(rmdir(old_root));
- if (opt->working_dir != NULL) {
- CHECK_CALL(chdir(opt->working_dir));
+ if (opt.working_dir != NULL) {
+ CHECK_CALL(chdir(opt.working_dir));
}
}
@@ -678,11 +706,11 @@ void OnSignal(int sig) {
if (sig == SIGALRM) {
// SIGALRM represents a timeout, so we should give the process a bit of
// time to die gracefully if it needs it.
- KillEverything(global_child_pid, true, global_kill_delay);
+ KillEverything(global_child_pid, true, opt.kill_delay_secs);
} else {
// Signals should kill the process quickly, as it's typically blocking
// the return of the prompt after a user hits "Ctrl-C".
- KillEverything(global_child_pid, false, global_kill_delay);
+ KillEverything(global_child_pid, false, opt.kill_delay_secs);
}
}
@@ -726,7 +754,7 @@ static void SpawnCommand(char *const *argv, double timeout_secs,
UnHandle(global_signal);
raise(global_signal);
} else if (WIFEXITED(status)) {
- if (global_debug && !isFallback && isatty(fileno(stdin)) &&
+ if (opt.debug && !isFallback && isatty(fileno(stdin)) &&
WEXITSTATUS(status) > 0) {
char **cmdList = calloc(2, sizeof(char *));
cmdList[0] = "/bin/bash";
@@ -743,24 +771,7 @@ static void SpawnCommand(char *const *argv, double timeout_secs,
}
int main(int argc, char *const argv[]) {
- struct Options opt;
- memset(&opt, 0, sizeof(opt));
- // 16 elements is a sane default, will be realloc'd as needed anyway.
- opt.mount_sources = calloc(16, sizeof(char *));
- opt.mount_targets = calloc(16, sizeof(char *));
- opt.mount_map_sizes = 16;
- // We'll need at least two slots for homedir_from_env and homedir.
- opt.create_dirs = calloc(2, sizeof(char *));
- opt.create_dirs_size = 2;
-
- ParseCommandLine(argc, argv, &opt);
- if (opt.args == NULL) {
- Usage(argc, argv, "No command specified.");
- }
- if (opt.sandbox_root == NULL) {
- Usage(argc, argv, "Sandbox root (-S) must be specified");
- }
- global_kill_delay = opt.kill_delay_secs;
+ ParseOptions(argc, argv);
int uid = SwitchToEuid();
int gid = SwitchToEgid();
@@ -773,6 +784,7 @@ int main(int argc, char *const argv[]) {
(opt.working_dir != NULL) ? opt.working_dir : "/ (default)");
CreateNamespaces(opt.create_netns);
+
if (opt.create_netns) {
// Enable the loopback interface because some application may want
// to use it.
@@ -783,13 +795,15 @@ int main(int argc, char *const argv[]) {
// outside environment.
CHECK_CALL(mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL));
+ SetupDirectories();
+
if (opt.fake_root) {
SetupUserNamespace(uid, gid, 0, 0);
} else {
SetupUserNamespaceForNobody(uid, gid);
}
- SetupDirectories(&opt);
- ChangeRoot(&opt);
+
+ ChangeRoot();
SpawnCommand(opt.args, opt.timeout_secs, false);
diff --git a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java
index efafd3b8a2..0d18caa550 100644
--- a/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategyTestCase.java
@@ -103,13 +103,12 @@ public class LinuxSandboxedStrategyTestCase {
ImmutableMap.<String, SpawnActionContext>of(
"",
new LinuxSandboxedStrategy(
+ optionsParser.getOptions(SandboxOptions.class),
ImmutableMap.<String, String>of(),
blazeDirs,
MoreExecutors.newDirectExecutorService(),
true,
false,
- ImmutableList.<String>of(),
- false,
TestConstants.PRODUCT_NAME)),
ImmutableList.<ActionContextProvider>of());
}