diff options
author | Xin Gao <xingao@google.com> | 2016-12-20 12:20:36 +0000 |
---|---|---|
committer | Klaus Aehlig <aehlig@google.com> | 2016-12-20 13:35:16 +0000 |
commit | 18e6b410a7f4e24b67740978d101cd665edea6cc (patch) | |
tree | 2d59b53517cfb9946bffb48172982fa252b4a6e9 /src/main/tools | |
parent | 4fb378c0fa08131394dc5e815f6fe5597d007a66 (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.cc | 62 | ||||
-rw-r--r-- | src/main/tools/linux-sandbox-options.h | 6 | ||||
-rw-r--r-- | src/main/tools/linux-sandbox-pid1.cc | 13 |
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); } } |