aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/sandbox
diff options
context:
space:
mode:
authorGravatar jmmv <jmmv@google.com>2018-04-10 12:18:59 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-04-10 12:20:17 -0700
commit0a1388e7e4e9a61c8a12b1f3e7bef5a2bbef2ba5 (patch)
treeff330e5d67c9e4b77ef9ae327105d1570cdf3350 /src/main/java/com/google/devtools/build/lib/sandbox
parent5a35e72f9e97c06540c479f8c31512fb4656202f (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.java20
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());
}