Skip to content

Commit 671e048

Browse files
larsrc-googlekatre
authored andcommitted
Force source files to be readable before copying them from sandbox.
Rules can (and have) accidentally made outputs unreadable, which makes the sandbox copying fail only when moving across devices. Unreadable outputs make no sense, so we just force them to be readable. RELNOTES: None. PiperOrigin-RevId: 363668244
1 parent 451b296 commit 671e048

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java

+11
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,17 @@ public static MoveResult moveFile(Path from, Path to) throws IOException {
456456
try (InputStream in = from.getInputStream();
457457
OutputStream out = to.getOutputStream()) {
458458
copyLargeBuffer(in, out);
459+
} catch (FileAccessException e1) {
460+
// Rules can accidentally make output non-readable, let's fix that (b/150963503)
461+
if (!from.isReadable()) {
462+
from.setReadable(true);
463+
try (InputStream in = from.getInputStream();
464+
OutputStream out = to.getOutputStream()) {
465+
copyLargeBuffer(in, out);
466+
}
467+
} else {
468+
throw e1;
469+
}
459470
}
460471
to.setLastModifiedTime(stat.getLastModifiedTime()); // Preserve mtime.
461472
if (!from.isWritable()) {

src/test/java/com/google/devtools/build/lib/vfs/FileSystemUtilsTest.java

+40-19
Original file line numberDiff line numberDiff line change
@@ -364,26 +364,11 @@ public void testMoveFile() throws IOException {
364364

365365
@Test
366366
public void testMoveFileAcrossDevices() throws Exception {
367-
class MultipleDeviceFS extends InMemoryFileSystem {
368-
MultipleDeviceFS() {
369-
super(DigestHashFunction.SHA256);
370-
}
371-
372-
@Override
373-
public void renameTo(Path source, Path target) throws IOException {
374-
if (!source.startsWith(target.asFragment().subFragment(0, 1))) {
375-
throw new IOException("EXDEV");
376-
}
377-
super.renameTo(source, target);
378-
}
379-
}
380367
FileSystem fs = new MultipleDeviceFS();
381-
Path dev1 = fs.getPath("/fs1");
382-
dev1.createDirectory();
383-
Path dev2 = fs.getPath("/fs2");
384-
dev2.createDirectory();
385-
Path source = dev1.getChild("source");
386-
Path target = dev2.getChild("target");
368+
Path source = fs.getPath("/fs1/source");
369+
source.getParentDirectory().createDirectoryAndParents();
370+
Path target = fs.getPath("/fs2/target");
371+
target.getParentDirectory().createDirectoryAndParents();
387372

388373
FileSystemUtils.writeContent(source, UTF_8, "hello, world");
389374
source.setLastModifiedTime(142);
@@ -394,12 +379,34 @@ public void renameTo(Path source, Path target) throws IOException {
394379
assertThat(target.getLastModifiedTime()).isEqualTo(142);
395380

396381
source.createSymbolicLink(PathFragment.create("link-target"));
382+
397383
assertThat(FileSystemUtils.moveFile(source, target)).isEqualTo(MoveResult.FILE_COPIED);
384+
398385
assertThat(source.exists(Symlinks.NOFOLLOW)).isFalse();
399386
assertThat(target.isSymbolicLink()).isTrue();
400387
assertThat(target.readSymbolicLink()).isEqualTo(PathFragment.create("link-target"));
401388
}
402389

390+
@Test
391+
public void testMoveFileFixPermissions() throws Exception {
392+
FileSystem fs = new MultipleDeviceFS();
393+
Path source = fs.getPath("/fs1/source");
394+
source.getParentDirectory().createDirectoryAndParents();
395+
Path target = fs.getPath("/fs2/target");
396+
target.getParentDirectory().createDirectoryAndParents();
397+
398+
FileSystemUtils.writeContent(source, UTF_8, "linear-a");
399+
source.setLastModifiedTime(142);
400+
source.setReadable(false);
401+
402+
MoveResult moveResult = moveFile(source, target);
403+
404+
assertThat(moveResult).isEqualTo(MoveResult.FILE_COPIED);
405+
assertThat(source.exists(Symlinks.NOFOLLOW)).isFalse();
406+
assertThat(target.isFile(Symlinks.NOFOLLOW)).isTrue();
407+
assertThat(FileSystemUtils.readContent(target, UTF_8)).isEqualTo("linear-a");
408+
}
409+
403410
@Test
404411
public void testReadContentWithLimit() throws IOException {
405412
createTestDirectoryTree();
@@ -834,4 +841,18 @@ public void testCreateHardLinkForNonEmptyDirectory_success() throws Exception {
834841
assertThat(fileSystem.stat(linkPath3, false).getNodeId())
835842
.isEqualTo(fileSystem.stat(originalPath3, false).getNodeId());
836843
}
844+
845+
static class MultipleDeviceFS extends InMemoryFileSystem {
846+
MultipleDeviceFS() {
847+
super(DigestHashFunction.SHA256);
848+
}
849+
850+
@Override
851+
public void renameTo(Path source, Path target) throws IOException {
852+
if (!source.startsWith(target.asFragment().subFragment(0, 1))) {
853+
throw new IOException("EXDEV");
854+
}
855+
super.renameTo(source, target);
856+
}
857+
}
837858
}

0 commit comments

Comments
 (0)