summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorAyush Ranjan <ayushranjan@google.com>2021-02-05 17:14:59 -0800
committergVisor bot <gvisor-bot@google.com>2021-02-05 17:17:30 -0800
commit09afd68326898f783927c65f86f813d815d8c16c (patch)
tree4cea9f27b4d37f15441aadae7c1bc5f5f5a9ec8a /test
parent24416032ab848cff7696b3f37e4c18220aeee2c0 (diff)
[vfs] Handle `.` and `..` as last path component names in kernfs Rename.
According to vfs.FilesystemImpl.RenameAt documentation: - If the last path component in rp is "." or "..", and opts.Flags contains RENAME_NOREPLACE, RenameAt returns EEXIST. - If the last path component in rp is "." or "..", and opts.Flags does not contain RENAME_NOREPLACE, RenameAt returns EBUSY. Reported-by: syzbot+6189786e64fe13fe43f8@syzkaller.appspotmail.com PiperOrigin-RevId: 355959266
Diffstat (limited to 'test')
-rw-r--r--test/syscalls/linux/rename.cc33
1 files changed, 33 insertions, 0 deletions
diff --git a/test/syscalls/linux/rename.cc b/test/syscalls/linux/rename.cc
index 5458f54ad..22c8c19cf 100644
--- a/test/syscalls/linux/rename.cc
+++ b/test/syscalls/linux/rename.cc
@@ -391,6 +391,39 @@ TEST(RenameTest, FileWithOpenFd) {
EXPECT_EQ(absl::string_view(buf, sizeof(buf) - 1), kContents);
}
+// Tests that calling rename with file path ending with . or .. causes EBUSY.
+TEST(RenameTest, PathEndingWithDots) {
+ TempPath root_dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
+ TempPath dir1 =
+ ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDirIn(root_dir.path()));
+ TempPath dir2 =
+ ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDirIn(root_dir.path()));
+
+ // Try to move dir1 into dir2 but mess up the paths.
+ auto dir1Dot = JoinPath(dir1.path(), ".");
+ auto dir2Dot = JoinPath(dir2.path(), ".");
+ auto dir1DotDot = JoinPath(dir1.path(), "..");
+ auto dir2DotDot = JoinPath(dir2.path(), "..");
+ ASSERT_THAT(rename(dir1.path().c_str(), dir2Dot.c_str()),
+ SyscallFailsWithErrno(EBUSY));
+ ASSERT_THAT(rename(dir1.path().c_str(), dir2DotDot.c_str()),
+ SyscallFailsWithErrno(EBUSY));
+ ASSERT_THAT(rename(dir1Dot.c_str(), dir2.path().c_str()),
+ SyscallFailsWithErrno(EBUSY));
+ ASSERT_THAT(rename(dir1DotDot.c_str(), dir2.path().c_str()),
+ SyscallFailsWithErrno(EBUSY));
+}
+
+// Calling rename with file path ending with . or .. causes EBUSY in sysfs.
+TEST(RenameTest, SysfsPathEndingWithDots) {
+ // If a non-root user tries to rename inside /sys then we get EPERM.
+ SKIP_IF(geteuid() != 0);
+ ASSERT_THAT(rename("/sys/devices/system/cpu/online", "/sys/."),
+ SyscallFailsWithErrno(EBUSY));
+ ASSERT_THAT(rename("/sys/devices/system/cpu/online", "/sys/.."),
+ SyscallFailsWithErrno(EBUSY));
+}
+
} // namespace
} // namespace testing