diff options
author | 2018-04-10 12:18:59 -0700 | |
---|---|---|
committer | 2018-04-10 12:20:17 -0700 | |
commit | 0a1388e7e4e9a61c8a12b1f3e7bef5a2bbef2ba5 (patch) | |
tree | ff330e5d67c9e4b77ef9ae327105d1570cdf3350 /src/main/java/com/google/devtools/build/lib/sandbox | |
parent | 5a35e72f9e97c06540c479f8c31512fb4656202f (diff) |
Fix handling of relative symlinks within sandboxfs.
If an action expresses a symlink as an input, the target of the symlink does
not necessarily appear as a file to map within the sandbox. This is a
problem when the target of the symlink is relative because sandboxfs would
expose the link verbatim and the target would be missing later on during
resolution.
To fix this, special-case the handling of symlinks: when trying to expose
them via a sandboxfs mount point, resolve their final target instead of
respecting the original contents. This loses the fact that the file was a
symlink when running within the sandboxfs sandbox, but is easier to
implement and slightly faster at runtime. We can reconsider this choice
if this causes problems.
RELNOTES: None.
PiperOrigin-RevId: 192325932
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/sandbox')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/sandbox/SandboxfsSandboxedSpawn.java | 20 |
1 files changed, 18 insertions, 2 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 a33785f648..09b63f0054 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 @@ -165,8 +165,9 @@ class SandboxfsSandboxedSpawn implements SandboxedSpawn { * as a map of mapped path to target path. The target path may be null, in which case an empty * read-only file is mapped. * @return the collection of mappings to use for reconfiguration + * @throws IOException if we fail to resolve symbolic links */ - private List<Mapping> createMappings(Map<PathFragment, Path> inputs) { + private List<Mapping> createMappings(Map<PathFragment, Path> inputs) throws IOException { List<Mapping> mappings = new ArrayList<>(); mappings.add(Mapping.builder() @@ -176,9 +177,24 @@ class SandboxfsSandboxedSpawn implements SandboxedSpawn { .build()); for (Entry<PathFragment, Path> entry : inputs.entrySet()) { + PathFragment target; + if (entry.getValue() == null) { + target = EMPTY_FILE; + } 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 + // expose the target in the sandbox and respect the symlink, or we can resolve what the + // actual target is and point the mapping there. The former has higher fidelity, as the + // sandbox will respect the file's type as a symlink. The latter is easier to implement + // and is slightly faster, as we avoid having to resolve symlinks later via sandboxfs. + // Therefore, do the latter until proven insufficient. + target = entry.getValue().resolveSymbolicLinks().asFragment(); + } else { + target = entry.getValue().asFragment(); + } mappings.add(Mapping.builder() .setPath(innerExecRoot.getRelative(entry.getKey())) - .setTarget(entry.getValue() == null ? EMPTY_FILE : entry.getValue().asFragment()) + .setTarget(target) .setWritable(false) .build()); } |