| Index: base/file_util_unittest.cc
|
| diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
|
| index c44b804f00949c85b4fd877c261e85f45a9155a6..b81985fdd7dadd477164bd40083fa7fdc331c318 100644
|
| --- a/base/file_util_unittest.cc
|
| +++ b/base/file_util_unittest.cc
|
| @@ -110,6 +110,27 @@ bool DeleteReparsePoint(HANDLE source) {
|
| }
|
| #endif
|
|
|
| +#if defined(OS_POSIX)
|
| +// Provide a simple way to change the permissions bits on |path| in tests.
|
| +// ASSERT failures will return, but not stop the test. Caller should wrap
|
| +// calls to this function in ASSERT_NO_FATAL_FAILURE().
|
| +void ChangePosixFilePermissions(const FilePath& path,
|
| + mode_t mode_bits_to_set,
|
| + mode_t mode_bits_to_clear) {
|
| + ASSERT_EQ(0u, mode_bits_to_set & mode_bits_to_clear)
|
| + << "Can't set and clear the same bit.";
|
| +
|
| + struct stat stat_buf;
|
| + ASSERT_EQ(0, stat(path.value().c_str(), &stat_buf));
|
| +
|
| + mode_t new_mode_bits = stat_buf.st_mode;
|
| + new_mode_bits |= mode_bits_to_set;
|
| + new_mode_bits &= ~mode_bits_to_clear;
|
| +
|
| + ASSERT_EQ(0, chmod(path.value().c_str(), new_mode_bits));
|
| +}
|
| +#endif // defined(OS_POSIX)
|
| +
|
| const wchar_t bogus_content[] = L"I'm cannon fodder.";
|
|
|
| const file_util::FileEnumerator::FileType FILES_AND_DIRECTORIES =
|
| @@ -1813,4 +1834,104 @@ TEST_F(FileUtilTest, IsDirectoryEmpty) {
|
| EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir));
|
| }
|
|
|
| +#if defined(OS_POSIX)
|
| +TEST_F(FileUtilTest, IsPathControlledByUser) {
|
| + // Testing IsPathControlledByAdmin() is hard, because there is no
|
| + // way a test can make a file owned by root, or change file paths
|
| + // at the root of the file system. IsPathControlledByAdmin()
|
| + // is implemented as a call to IsPathControlledByUser, which gives
|
| + // us the ability to test with paths under the test's temp directory,
|
| + // using a user id we control.
|
| +
|
| + FilePath base_dir = temp_dir_.path().AppendASCII("base_dir");
|
| + ASSERT_TRUE(file_util::CreateDirectory(base_dir));
|
| +
|
| + FilePath sub_dir = base_dir.AppendASCII("sub_dir");
|
| + ASSERT_TRUE(file_util::CreateDirectory(sub_dir));
|
| +
|
| + FilePath text_file = sub_dir.AppendASCII("file.txt");
|
| + CreateTextFile(text_file, L"This text file has some text in it.");
|
| +
|
| + // Get our uid, and another uid, so that we can test both a
|
| + // matching and non-matching uid.
|
| + uid_t our_uid = getuid();
|
| + uid_t not_our_uid = our_uid + 1;
|
| +
|
| + // Make all files and directories non-world-writable.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(base_dir, 0u, S_IWOTH));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(sub_dir, 0u, S_IWOTH));
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(text_file, 0u, S_IWOTH));
|
| +
|
| + // We control these paths.
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, our_uid));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, our_uid));
|
| +
|
| + // Another user does not control these paths.
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, not_our_uid ));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, not_our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, not_our_uid));
|
| +
|
| + // Make base_dir world-writable. No change, because the base dir should
|
| + // not be tested.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(base_dir, S_IWOTH, 0u));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, our_uid));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, our_uid));
|
| +
|
| + // Make sub_dir world writable.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(sub_dir, S_IWOTH, 0u));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, our_uid));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, our_uid));
|
| +
|
| + // Make text_file world writable.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(text_file, S_IWOTH, 0u));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, our_uid));
|
| +
|
| + // Make sub_dir non-world writable.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(sub_dir, 0u, S_IWOTH));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, our_uid));
|
| +
|
| + // Make base_dir non-world-writable.
|
| + ASSERT_NO_FATAL_FAILURE(
|
| + ChangePosixFilePermissions(base_dir, 0u, S_IWOTH));
|
| + ASSERT_TRUE(
|
| + file_util::IsPathControlledByUser(base_dir, sub_dir, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(base_dir, text_file, our_uid));
|
| + ASSERT_FALSE(
|
| + file_util::IsPathControlledByUser(sub_dir, text_file, our_uid));
|
| +}
|
| +#endif // defined(OS_POSIX)
|
| +
|
| } // namespace
|
|
|