Skip to content

Commit cab42c6

Browse files
ayushr2gvisor-bot
authored andcommitted
overlayfs: Clear RENAME_NOREPLACE before calling into layers.
This is consistent with what Linux does; see fs/overlayfs/dir.c:ovl_rename(). Fixes #11794 PiperOrigin-RevId: 769849304
1 parent c6c0e52 commit cab42c6

File tree

4 files changed

+26
-19
lines changed

4 files changed

+26
-19
lines changed

pkg/sentry/fsimpl/overlay/filesystem.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,10 @@ func (fs *filesystem) RenameAt(ctx context.Context, rp *vfs.ResolvingPath, oldPa
12671267
}
12681268
}
12691269

1270+
// Clear the RENAME_NOREPLACE flag. We already verified above that replaced
1271+
// is nil if this flag is set. Other filesystem implementations are not aware
1272+
// of whiteouts and may fail with EEXIST if a whiteout exists at newName.
1273+
opts.Flags &^= linux.RENAME_NOREPLACE
12701274
// Essentially no gVisor filesystem supports RENAME_WHITEOUT, so just do a
12711275
// regular rename and create the whiteout at the origin manually. Unlike
12721276
// RENAME_WHITEOUT, this isn't atomic with respect to other users of the

test/syscalls/linux/rename.cc

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -464,25 +464,6 @@ TEST(RenameTest, SysfsDirectoryToSelf) {
464464
EXPECT_THAT(rename(path.c_str(), path.c_str()), SyscallSucceeds());
465465
}
466466

467-
#ifndef SYS_renameat2
468-
#if defined(__x86_64__)
469-
#define SYS_renameat2 316
470-
#elif defined(__aarch64__)
471-
#define SYS_renameat2 276
472-
#else
473-
#error "Unknown architecture"
474-
#endif
475-
#endif // SYS_renameat2
476-
477-
#ifndef RENAME_NOREPLACE
478-
#define RENAME_NOREPLACE (1 << 0)
479-
#endif // RENAME_NOREPLACE
480-
481-
int renameat2(int olddirfd, const char* oldpath, int newdirfd,
482-
const char* newpath, unsigned int flags) {
483-
return syscall(SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
484-
}
485-
486467
TEST(Renameat2Test, NoReplaceSuccess) {
487468
auto f = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
488469
std::string const newpath = NewTempAbsPath();

test/util/fs_util.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,5 +737,10 @@ ::testing::Matcher<mode_t> PermissionIs(mode_t want) {
737737
return MakeMatcher(new ModePermissionMatcher(want));
738738
}
739739

740+
int renameat2(int olddirfd, const char* oldpath, int newdirfd,
741+
const char* newpath, unsigned int flags) {
742+
return syscall(SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
743+
}
744+
740745
} // namespace testing
741746
} // namespace gvisor

test/util/fs_util.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,23 @@ constexpr int kOLargeFile = 00400000;
4343
// build environments.
4444
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
4545

46+
#ifndef SYS_renameat2
47+
#if defined(__x86_64__)
48+
#define SYS_renameat2 316
49+
#elif defined(__aarch64__)
50+
#define SYS_renameat2 276
51+
#else
52+
#error "Unknown architecture"
53+
#endif
54+
#endif // SYS_renameat2
55+
56+
#ifndef RENAME_NOREPLACE
57+
#define RENAME_NOREPLACE (1 << 0)
58+
#endif // RENAME_NOREPLACE
59+
60+
int renameat2(int olddirfd, const char* oldpath, int newdirfd,
61+
const char* newpath, unsigned int flags);
62+
4663
// Returns a status or the current working directory.
4764
PosixErrorOr<std::string> GetCWD();
4865

0 commit comments

Comments
 (0)