diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java index c783990564e575..3d9b9baafda411 100644 --- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java +++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.sandbox; import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.devtools.build.lib.sandbox.LinuxSandboxCommandLineBuilder.NetworkNamespace.NETNS_WITH_LOOPBACK; import static com.google.devtools.build.lib.sandbox.LinuxSandboxCommandLineBuilder.NetworkNamespace.NO_NETNS; @@ -59,8 +60,10 @@ import java.time.Duration; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; +import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nullable; @@ -384,7 +387,7 @@ public String getName() { protected ImmutableSet getWritableDirs( Path sandboxExecRoot, Path withinSandboxExecRoot, Map env) throws IOException { - ImmutableSet.Builder writableDirs = ImmutableSet.builder(); + Set writableDirs = new TreeSet<>(); writableDirs.addAll(super.getWritableDirs(sandboxExecRoot, withinSandboxExecRoot, env)); if (getSandboxOptions().memoryLimitMb > 0) { CgroupsInfo cgroupsInfo = CgroupsInfo.getInstance(); @@ -394,7 +397,23 @@ protected ImmutableSet getWritableDirs( writableDirs.add(fs.getPath("/dev/shm").resolveSymbolicLinks()); writableDirs.add(fs.getPath("/tmp")); - return writableDirs.build(); + if (sandboxExecRoot.equals(withinSandboxExecRoot)) { + return ImmutableSet.copyOf(writableDirs); + } + + // If a writable directory is under the sandbox exec root, transform it so that its path will + // be the one that it will be available at after processing the bind mounts (this is how the + // sandbox interprets the corresponding arguments) + // + // Notably, this is usually the case for $TEST_TMPDIR because its default value is under the + // execroot. + return writableDirs.stream() + .map( + d -> + d.startsWith(sandboxExecRoot) + ? withinSandboxExecRoot.getRelative(d.relativeTo(sandboxExecRoot)) + : d) + .collect(toImmutableSet()); } private ImmutableList prepareAndGetBindMounts(