diff options
Diffstat (limited to 'base/file_util_unittest.cc')
-rw-r--r-- | base/file_util_unittest.cc | 213 |
1 files changed, 168 insertions, 45 deletions
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc index b76938e..8ac1076 100644 --- a/base/file_util_unittest.cc +++ b/base/file_util_unittest.cc @@ -1867,7 +1867,9 @@ class VerifyPathControlledByUserTest : public FileUtilTest { struct stat stat_buf; ASSERT_EQ(0, stat(base_dir_.value().c_str(), &stat_buf)); uid_ = stat_buf.st_uid; - gid_ = stat_buf.st_gid; + ok_gids_.insert(stat_buf.st_gid); + bad_gids_.insert(stat_buf.st_gid + 1); + ASSERT_EQ(uid_, getuid()); // This process should be the owner. // To ensure that umask settings do not cause the initial state @@ -1892,7 +1894,9 @@ class VerifyPathControlledByUserTest : public FileUtilTest { FilePath sub_dir_; FilePath text_file_; uid_t uid_; - gid_t gid_; + + std::set<gid_t> ok_gids_; + std::set<gid_t> bad_gids_; }; TEST_F(VerifyPathControlledByUserTest, BadPaths) { @@ -1900,23 +1904,25 @@ TEST_F(VerifyPathControlledByUserTest, BadPaths) { FilePath does_not_exist = base_dir_.AppendASCII("does") .AppendASCII("not") .AppendASCII("exist"); - EXPECT_FALSE( file_util::VerifyPathControlledByUser( - base_dir_, does_not_exist, uid_, gid_)); + base_dir_, does_not_exist, uid_, ok_gids_)); // |base| not a subpath of |path|. EXPECT_FALSE( - file_util::VerifyPathControlledByUser(sub_dir_, base_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, base_dir_, uid_, ok_gids_)); // An empty base path will fail to be a prefix for any path. FilePath empty; EXPECT_FALSE( - file_util::VerifyPathControlledByUser(empty, base_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + empty, base_dir_, uid_, ok_gids_)); // Finding that a bad call fails proves nothing unless a good call succeeds. EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); } TEST_F(VerifyPathControlledByUserTest, Symlinks) { @@ -1928,9 +1934,11 @@ TEST_F(VerifyPathControlledByUserTest, Symlinks) { << "Failed to create symlink."; EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, file_link, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, file_link, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(file_link, file_link, uid_, gid_)); + file_util::VerifyPathControlledByUser( + file_link, file_link, uid_, ok_gids_)); // Symlink from one directory to another within the path. FilePath link_to_sub_dir = base_dir_.AppendASCII("link_to_sub_dir"); @@ -1942,25 +1950,22 @@ TEST_F(VerifyPathControlledByUserTest, Symlinks) { EXPECT_FALSE( file_util::VerifyPathControlledByUser( - base_dir_, file_path_with_link, uid_, gid_)); + base_dir_, file_path_with_link, uid_, ok_gids_)); EXPECT_FALSE( file_util::VerifyPathControlledByUser( - link_to_sub_dir, file_path_with_link, uid_, gid_)); + link_to_sub_dir, file_path_with_link, uid_, ok_gids_)); // Symlinks in parents of base path are allowed. EXPECT_TRUE( file_util::VerifyPathControlledByUser( - file_path_with_link, file_path_with_link, uid_, gid_)); + file_path_with_link, file_path_with_link, uid_, ok_gids_)); } TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) { // Get a uid that is not the uid of files we create. uid_t bad_uid = uid_ + 1; - // Get a gid that is not ours. - gid_t bad_gid = gid_ + 1; - // Make all files and directories non-world-writable. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); @@ -1971,33 +1976,130 @@ TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) { // We control these paths. EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Another user does not control these paths. EXPECT_FALSE( file_util::VerifyPathControlledByUser( - base_dir_, sub_dir_, bad_uid, gid_)); + base_dir_, sub_dir_, bad_uid, ok_gids_)); EXPECT_FALSE( file_util::VerifyPathControlledByUser( - base_dir_, text_file_, bad_uid, gid_)); + base_dir_, text_file_, bad_uid, ok_gids_)); EXPECT_FALSE( file_util::VerifyPathControlledByUser( - sub_dir_, text_file_, bad_uid, gid_)); + sub_dir_, text_file_, bad_uid, ok_gids_)); // Another group does not control the paths. EXPECT_FALSE( file_util::VerifyPathControlledByUser( - base_dir_, sub_dir_, uid_, bad_gid)); + base_dir_, sub_dir_, uid_, bad_gids_)); + EXPECT_FALSE( + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, bad_gids_)); + EXPECT_FALSE( + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, bad_gids_)); +} + +TEST_F(VerifyPathControlledByUserTest, GroupWriteTest) { + // Make all files and directories writable only by their owner. + ASSERT_NO_FATAL_FAILURE( + ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH|S_IWGRP)); + ASSERT_NO_FATAL_FAILURE( + ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH|S_IWGRP)); + ASSERT_NO_FATAL_FAILURE( + ChangePosixFilePermissions(text_file_, 0u, S_IWOTH|S_IWGRP)); + + // Any group is okay because the path is not group-writable. + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); + + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, bad_gids_)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, bad_gids_)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, bad_gids_)); + + // No group is okay, because we don't check the group + // if no group can write. + std::set<gid_t> no_gids; // Empty set of gids. + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, no_gids)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, no_gids)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, no_gids)); + + + // Make all files and directories writable by their group. + ASSERT_NO_FATAL_FAILURE( + ChangePosixFilePermissions(base_dir_, S_IWGRP, 0u)); + ASSERT_NO_FATAL_FAILURE( + ChangePosixFilePermissions(sub_dir_, S_IWGRP, 0u)); + ASSERT_NO_FATAL_FAILURE( + ChangePosixFilePermissions(text_file_, S_IWGRP, 0u)); + + // Now |ok_gids_| works, but |bad_gids_| fails. + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); + + EXPECT_FALSE( + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, bad_gids_)); EXPECT_FALSE( file_util::VerifyPathControlledByUser( - base_dir_, text_file_, uid_, bad_gid)); + base_dir_, text_file_, uid_, bad_gids_)); EXPECT_FALSE( file_util::VerifyPathControlledByUser( - sub_dir_, text_file_, uid_, bad_gid)); + sub_dir_, text_file_, uid_, bad_gids_)); + + // Because any group in the group set is allowed, + // the union of good and bad gids passes. + + std::set<gid_t> multiple_gids; + std::set_union( + ok_gids_.begin(), ok_gids_.end(), + bad_gids_.begin(), bad_gids_.end(), + std::inserter(multiple_gids, multiple_gids.begin())); + + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, multiple_gids)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, multiple_gids)); + EXPECT_TRUE( + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, multiple_gids)); + } TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) { @@ -2011,72 +2113,93 @@ TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) { // Initialy, we control all parts of the path. EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Make base_dir_ world-writable. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Make sub_dir_ world writable. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Make text_file_ world writable. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(text_file_, S_IWOTH, 0u)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Make sub_dir_ non-world writable. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Make base_dir_ non-world-writable. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_FALSE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); // Back to the initial state: Nothing is writable, so every path // should pass. ASSERT_NO_FATAL_FAILURE( ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, sub_dir_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + base_dir_, text_file_, uid_, ok_gids_)); EXPECT_TRUE( - file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); + file_util::VerifyPathControlledByUser( + sub_dir_, text_file_, uid_, ok_gids_)); } #endif // defined(OS_POSIX) |