aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/tools
diff options
context:
space:
mode:
authorGravatar Xin Gao <xingao@google.com>2016-12-20 12:20:36 +0000
committerGravatar Klaus Aehlig <aehlig@google.com>2016-12-20 13:35:16 +0000
commit18e6b410a7f4e24b67740978d101cd665edea6cc (patch)
tree2d59b53517cfb9946bffb48172982fa252b4a6e9 /src/main/tools
parent4fb378c0fa08131394dc5e815f6fe5597d007a66 (diff)
Add customized path mounting in Bazel sandbox.
RELNOTES: New flag --sandbox_add_mount_pair to specify customized source:target path pairs to bind mount inside the sandbox. -- Change-Id: Ifbacfc0e16bbaedcf5b6d3937799710f2cfa3d58 Reviewed-on: https://cr.bazel.build/7150 PiperOrigin-RevId: 142542381 MOS_MIGRATED_REVID=142542381
Diffstat (limited to 'src/main/tools')
-rw-r--r--src/main/tools/linux-sandbox-options.cc62
-rw-r--r--src/main/tools/linux-sandbox-options.h6
-rw-r--r--src/main/tools/linux-sandbox-pid1.cc13
3 files changed, 47 insertions, 34 deletions
diff --git a/src/main/tools/linux-sandbox-options.cc b/src/main/tools/linux-sandbox-options.cc
index 49e6eafeeb..8f8c15d5d9 100644
--- a/src/main/tools/linux-sandbox-options.cc
+++ b/src/main/tools/linux-sandbox-options.cc
@@ -69,7 +69,11 @@ static void Usage(char *program_name, const char *fmt, ...) {
" -i <file> make a file or directory inaccessible for the "
"sandboxed process\n"
" -e <dir> mount an empty tmpfs on a directory\n"
- " -b <dir> bind mount a file or directory inside the sandbox\n"
+ " -M/-m <source/target> directory to mount inside the sandbox\n"
+ " Multiple directories can be specified and each of them will be "
+ "mounted readonly.\n"
+ " 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"
" -D if set, debug info will be printed\n"
@@ -106,15 +110,24 @@ static int CheckNamespacesSupported() {
return EXIT_SUCCESS;
}
+static void ValidateIsAbsolutePath(char *path, char *program_name, char flag) {
+ if (path[0] != '/') {
+ Usage(program_name, "The -%c option must be used with absolute paths only.",
+ flag);
+ }
+}
+
// Parses command line flags from an argv array and puts the results into an
// Options structure passed in as an argument.
static void ParseCommandLine(unique_ptr<vector<char *>> args) {
extern char *optarg;
extern int optind, optopt;
int c;
+ bool source_specified;
while ((c = getopt(args->size(), args->data(),
- ":CS:W:T:t:l:L:w:i:e:b:NRD")) != -1) {
+ ":CS:W:T:t:l:L:w:i:e:M:m:NRD")) != -1) {
+ if (c != 'M' && c != 'm') source_specified = false;
switch (c) {
case 'C':
// Shortcut for the "does this system support sandboxing" check.
@@ -122,22 +135,16 @@ static void ParseCommandLine(unique_ptr<vector<char *>> args) {
break;
case 'S':
if (opt.sandbox_root_dir == NULL) {
- if (optarg[0] != '/') {
- Usage(args->front(),
- "The -r option must be used with absolute paths only.");
- }
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
opt.sandbox_root_dir = strdup(optarg);
} else {
Usage(args->front(),
- "Multiple root directories (-r) specified, expected one.");
+ "Multiple root directories (-S) specified, expected one.");
}
break;
case 'W':
if (opt.working_dir == NULL) {
- if (optarg[0] != '/') {
- Usage(args->front(),
- "The -W option must be used with absolute paths only.");
- }
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
opt.working_dir = strdup(optarg);
} else {
Usage(args->front(),
@@ -173,32 +180,33 @@ static void ParseCommandLine(unique_ptr<vector<char *>> args) {
}
break;
case 'w':
- if (optarg[0] != '/') {
- Usage(args->front(),
- "The -w option must be used with absolute paths only.");
- }
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
opt.writable_files.push_back(strdup(optarg));
break;
case 'i':
- if (optarg[0] != '/') {
- Usage(args->front(),
- "The -i option must be used with absolute paths only.");
- }
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
opt.inaccessible_files.push_back(strdup(optarg));
break;
case 'e':
- if (optarg[0] != '/') {
- Usage(args->front(),
- "The -e option must be used with absolute paths only.");
- }
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
opt.tmpfs_dirs.push_back(strdup(optarg));
break;
- case 'b':
- if (optarg[0] != '/') {
+ case 'M':
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
+ // Add the current source path to both source and target lists
+ opt.bind_mount_sources.push_back(strdup(optarg));
+ opt.bind_mount_targets.push_back(strdup(optarg));
+ source_specified = true;
+ break;
+ case 'm':
+ ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
+ if (!source_specified) {
Usage(args->front(),
- "The -b option must be used with absolute paths only.");
+ "The -m option must be strictly preceded by an -M option.");
}
- opt.bind_mounts.push_back(strdup(optarg));
+ opt.bind_mount_targets.pop_back();
+ opt.bind_mount_targets.push_back(strdup(optarg));
+ source_specified = false;
break;
case 'N':
opt.create_netns = true;
diff --git a/src/main/tools/linux-sandbox-options.h b/src/main/tools/linux-sandbox-options.h
index 5554f9e41f..5f33a0676f 100644
--- a/src/main/tools/linux-sandbox-options.h
+++ b/src/main/tools/linux-sandbox-options.h
@@ -40,8 +40,10 @@ struct Options {
std::vector<const char *> inaccessible_files;
// Directories where to mount an empty tmpfs (-e)
std::vector<const char *> tmpfs_dirs;
- // Files or directories to explicitly bind mount into the sandbox (-b)
- std::vector<const char *> bind_mounts;
+ // Source of files or directories to explicitly bind mount in the sandbox (-M)
+ std::vector<const char *> bind_mount_sources;
+ // Target of files or directories to explicitly bind mount in the sandbox (-m)
+ std::vector<const char *> bind_mount_targets;
// Create a new network namespace (-N)
bool create_netns;
// Pretend to be root inside the namespace (-R)
diff --git a/src/main/tools/linux-sandbox-pid1.cc b/src/main/tools/linux-sandbox-pid1.cc
index 4feedd9e02..5e0dff1a01 100644
--- a/src/main/tools/linux-sandbox-pid1.cc
+++ b/src/main/tools/linux-sandbox-pid1.cc
@@ -249,17 +249,20 @@ static void MountFilesystems() {
// Make sure that our working directory is a mount point. The easiest way to
// do this is by bind-mounting it upon itself.
PRINT_DEBUG("working dir: %s", opt.working_dir);
+ PRINT_DEBUG("sandbox root: %s", opt.sandbox_root_dir);
+
CreateTarget(opt.working_dir + 1, true);
if (mount(opt.working_dir, opt.working_dir + 1, NULL, MS_BIND, NULL) < 0) {
DIE("mount(%s, %s, NULL, MS_BIND, NULL)", opt.working_dir,
opt.working_dir + 1);
}
- for (const char *bind_mount : opt.bind_mounts) {
- PRINT_DEBUG("bind mount: %s", bind_mount);
- CreateTarget(bind_mount + 1, IsDirectory(bind_mount));
- if (mount(bind_mount, bind_mount + 1, NULL, MS_BIND, NULL) < 0) {
- DIE("mount(%s, %s, NULL, MS_BIND, NULL)", bind_mount, bind_mount + 1);
+ for (size_t i = 0; i < opt.bind_mount_sources.size(); i++) {
+ const char *source = opt.bind_mount_sources.at(i);
+ const char *target = opt.bind_mount_targets.at(i);
+ PRINT_DEBUG("bind mount: %s -> %s", source, target);
+ if (mount(source, target + 1, NULL, MS_BIND, NULL) < 0) {
+ DIE("mount(%s, %s, NULL, MS_BIND, NULL)", source, target + 1);
}
}