summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2021-01-14 13:41:25 -0800
committergVisor bot <gvisor-bot@google.com>2021-01-14 13:43:10 -0800
commitdbe4176565b56d9e2f5395e410468a4c98aafd37 (patch)
treec63600c37a26af38fb8e0b3a6eac80c13440e610 /test/syscalls
parentf1ce97294bfc835a488a1607ad1b36ed349b474e (diff)
Check for existence before permissions
Return EEXIST when overwritting a file as long as the caller has exec permission on the parent directory, even if the caller doesn't have write permission. Also reordered the mount write check, which happens before permission is checked. Closes #5164 PiperOrigin-RevId: 351868123
Diffstat (limited to 'test/syscalls')
-rw-r--r--test/syscalls/linux/mkdir.cc33
1 files changed, 33 insertions, 0 deletions
diff --git a/test/syscalls/linux/mkdir.cc b/test/syscalls/linux/mkdir.cc
index 27758203d..11fbfa5c5 100644
--- a/test/syscalls/linux/mkdir.cc
+++ b/test/syscalls/linux/mkdir.cc
@@ -82,6 +82,39 @@ TEST_F(MkdirTest, FailsOnDirWithoutWritePerms) {
SyscallFailsWithErrno(EACCES));
}
+TEST_F(MkdirTest, DirAlreadyExists) {
+ // Drop capabilities that allow us to override file and directory permissions.
+ ASSERT_NO_ERRNO(SetCapability(CAP_DAC_OVERRIDE, false));
+ ASSERT_NO_ERRNO(SetCapability(CAP_DAC_READ_SEARCH, false));
+
+ ASSERT_THAT(mkdir(dirname_.c_str(), 0777), SyscallSucceeds());
+ auto dir = JoinPath(dirname_.c_str(), "foo");
+ EXPECT_THAT(mkdir(dir.c_str(), 0777), SyscallSucceeds());
+
+ struct {
+ int mode;
+ int err;
+ } tests[] = {
+ {.mode = 0000, .err = EACCES}, // No perm
+ {.mode = 0100, .err = EEXIST}, // Exec only
+ {.mode = 0200, .err = EACCES}, // Write only
+ {.mode = 0300, .err = EEXIST}, // Write+exec
+ {.mode = 0400, .err = EACCES}, // Read only
+ {.mode = 0500, .err = EEXIST}, // Read+exec
+ {.mode = 0600, .err = EACCES}, // Read+write
+ {.mode = 0700, .err = EEXIST}, // All
+ };
+ for (const auto& t : tests) {
+ printf("mode: 0%o\n", t.mode);
+ EXPECT_THAT(chmod(dirname_.c_str(), t.mode), SyscallSucceeds());
+ EXPECT_THAT(mkdir(dir.c_str(), 0777), SyscallFailsWithErrno(t.err));
+ }
+
+ // Clean up.
+ EXPECT_THAT(chmod(dirname_.c_str(), 0777), SyscallSucceeds());
+ ASSERT_THAT(rmdir(dir.c_str()), SyscallSucceeds());
+}
+
TEST_F(MkdirTest, MkdirAtEmptyPath) {
ASSERT_THAT(mkdir(dirname_.c_str(), 0777), SyscallSucceeds());
auto fd =