diff options
author | Philipp Wollermann <philwo@google.com> | 2016-06-20 11:37:45 +0000 |
---|---|---|
committer | Philipp Wollermann <philwo@google.com> | 2016-06-21 09:57:34 +0000 |
commit | 2ee0377d835af26a6488ad7b80291953860c4dce (patch) | |
tree | 973b6af303f13b30b000cbbd1eae0611cbdab6b7 /src | |
parent | 35452349fd1556200f26a9eac5b7a3fa6239398c (diff) |
sandbox: Mount input files and directories actually read-only.
Fixes #1364.
RELNOTES[INC]: Bazel's sandbox mounts input files read-only in this release. If your build suddenly fails due to tools not being able to write to files, then this is probably working as intended (you should never modify input files in your build), but please feel free to provide feedback.
--
MOS_MIGRATED_REVID=125324318
Diffstat (limited to 'src')
-rw-r--r-- | src/main/tools/namespace-sandbox.c | 30 | ||||
-rwxr-xr-x | src/test/shell/bazel/bazel_sandboxing_test.sh | 17 |
2 files changed, 46 insertions, 1 deletions
diff --git a/src/main/tools/namespace-sandbox.c b/src/main/tools/namespace-sandbox.c index 580225da91..3b082af032 100644 --- a/src/main/tools/namespace-sandbox.c +++ b/src/main/tools/namespace-sandbox.c @@ -617,8 +617,36 @@ static void SetupDirectories() { 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))); + + int mountFlags = MS_BIND; + if (S_ISDIR(sb.st_mode)) { + mountFlags |= MS_REC; + } + CHECK_CALL( + mount(opt.mount_sources[i], full_sandbox_path, NULL, mountFlags, NULL)); + + // Check whether we need additional mount flags for the remount. + int remountFlags = MS_BIND | MS_REMOUNT | MS_NODEV | MS_NOSUID | MS_RDONLY; + if (!S_ISDIR(sb.st_mode) && access(opt.mount_sources[i], X_OK) != 0) { + switch (errno) { + case EACCES: + remountFlags |= MS_NOEXEC; + break; + default: + perror("access(opt.mount_sources[i], X_OK)"); + exit(EXIT_FAILURE); + } + } + CHECK_CALL(mount(opt.mount_sources[i], full_sandbox_path, NULL, - MS_REC | MS_BIND | MS_RDONLY, NULL)); + remountFlags, NULL)); + + // Check that the target became read-only. + if (access(full_sandbox_path, W_OK) != -1 && errno != EACCES) { + perror("access(opt.mount_sources[i], W_OK)"); + exit(EXIT_FAILURE); + } + free(full_sandbox_path); } } diff --git a/src/test/shell/bazel/bazel_sandboxing_test.sh b/src/test/shell/bazel/bazel_sandboxing_test.sh index 9e6bc857d8..382b6936de 100755 --- a/src/test/shell/bazel/bazel_sandboxing_test.sh +++ b/src/test/shell/bazel/bazel_sandboxing_test.sh @@ -156,6 +156,15 @@ genrule( cmd = "ls -l $$(dirname \"$$(pwd)\") &> $@", ) +genrule( + name = "modifies_input_file", + srcs = ["readonly.txt"], + outs = ["modifies_input_file.txt"], + cmd = ( + "echo \"OWNED\" > $(location :readonly.txt);" + + "touch \"$@\"" + ) +) EOF cat << 'EOF' >> examples/genrule/datafile this is a datafile @@ -434,6 +443,14 @@ EOF expect_log "Sandboxed execution failed, which may be legitimate" } +function test_modifies_input_file() { + echo 'This is readonly' > examples/genrule/readonly.txt + bazel build examples/genrule:modifies_input_file &> $TEST_log \ + && fail "Expected failure: examples/genrule:modifies_input_file" || true + fgrep OWNED examples/genrule/readonly.txt \ + && fail "Sandboxed genrule was able to modify input file" || true +} + # The test shouldn't fail if the environment doesn't support running it. check_supported_platform || exit 0 check_sandbox_allowed || exit 0 |