aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar jmmv <jmmv@google.com>2018-04-13 06:50:55 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-13 06:52:26 -0700
commitb85820e6da0b6a35ead4c06f7aa4dd459427144e (patch)
tree0a70a0b9d21bdeeb2b6022a0b2a514fe47cf445a
parent489f0e89993c4c61ab6889abe2e8a05efc36c247 (diff)
Use a regular file when exposing empty files instead of /dev/null.
Exposing devices through a FUSE mount point is possible but accessing them requires the file system to be mounted -odev, which needs root privileges for security reasons. Because we cannot ask sandboxfs to be mounted this way, change our code to instead use a regular empty file when necessary. PiperOrigin-RevId: 192761352
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java
index 09b63f0054..1c6357ad28 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java
@@ -17,6 +17,7 @@ package com.google.devtools.build.lib.sandbox;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.devtools.build.lib.sandbox.SandboxfsProcess.Mapping;
+import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
@@ -37,9 +38,6 @@ import java.util.logging.Logger;
class SandboxfsSandboxedSpawn implements SandboxedSpawn {
private static final Logger log = Logger.getLogger(SandboxfsSandboxedSpawn.class.getName());
- /** An empty file to use when mappings don't specify their target. */
- private static final PathFragment EMPTY_FILE = PathFragment.create("/dev/null");
-
/** Sequence number to assign a unique subtree to each action within the mount point. */
private static final AtomicInteger lastId = new AtomicInteger();
@@ -176,10 +174,22 @@ class SandboxfsSandboxedSpawn implements SandboxedSpawn {
.setWritable(true)
.build());
+ // Path to the empty file used as the target of mappings that don't provide one. This is
+ // lazily created and initialized only when we need such a mapping. It's safe to share the
+ // same empty file across all such mappings because this file is exposed as read-only.
+ //
+ // We cannot use /dev/null, as we used to do in the past, because exposing devices via a
+ // FUSE file system (which sandboxfs is) requires root privileges.
+ Path emptyFile = null;
+
for (Entry<PathFragment, Path> entry : inputs.entrySet()) {
PathFragment target;
if (entry.getValue() == null) {
- target = EMPTY_FILE;
+ if (emptyFile == null) {
+ emptyFile = sandboxScratchDir.getRelative("empty");
+ FileSystemUtils.createEmptyFile(emptyFile);
+ }
+ target = emptyFile.asFragment();
} else if (entry.getValue().isSymbolicLink()) {
// If an input is a symlink, we don't necessarily have its target as an input as well. To
// ensure the target is reachable within the sandbox, we have two choices: we can either