OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windows.h> | 8 #include <windows.h> |
9 #include <shellapi.h> | 9 #include <shellapi.h> |
10 #include <shlobj.h> | 10 #include <shlobj.h> |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 REPARSE_DATA_BUFFER data = {0}; | 103 REPARSE_DATA_BUFFER data = {0}; |
104 data.ReparseTag = 0xa0000003; | 104 data.ReparseTag = 0xa0000003; |
105 if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0, | 105 if (!DeviceIoControl(source, FSCTL_DELETE_REPARSE_POINT, &data, 8, NULL, 0, |
106 &returned, NULL)) { | 106 &returned, NULL)) { |
107 return false; | 107 return false; |
108 } | 108 } |
109 return true; | 109 return true; |
110 } | 110 } |
111 #endif | 111 #endif |
112 | 112 |
| 113 #if defined(OS_POSIX) |
| 114 // Provide a simple way to change the permissions bits on |path| in tests. |
| 115 // ASSERT failures will return, but not stop the test. Caller should wrap |
| 116 // calls to this function in ASSERT_NO_FATAL_FAILURE(). |
| 117 void ChangePosixFilePermissions(const FilePath& path, |
| 118 mode_t mode_bits_to_set, |
| 119 mode_t mode_bits_to_clear) { |
| 120 ASSERT_FALSE(mode_bits_to_set & mode_bits_to_clear) |
| 121 << "Can't set and clear the same bits."; |
| 122 |
| 123 struct stat stat_buf; |
| 124 ASSERT_EQ(0, stat(path.value().c_str(), &stat_buf)); |
| 125 |
| 126 mode_t updated_mode_bits = stat_buf.st_mode; |
| 127 updated_mode_bits |= mode_bits_to_set; |
| 128 updated_mode_bits &= ~mode_bits_to_clear; |
| 129 |
| 130 ASSERT_EQ(0, chmod(path.value().c_str(), updated_mode_bits)); |
| 131 } |
| 132 #endif // defined(OS_POSIX) |
| 133 |
113 const wchar_t bogus_content[] = L"I'm cannon fodder."; | 134 const wchar_t bogus_content[] = L"I'm cannon fodder."; |
114 | 135 |
115 const file_util::FileEnumerator::FileType FILES_AND_DIRECTORIES = | 136 const file_util::FileEnumerator::FileType FILES_AND_DIRECTORIES = |
116 static_cast<file_util::FileEnumerator::FileType>( | 137 static_cast<file_util::FileEnumerator::FileType>( |
117 file_util::FileEnumerator::FILES | | 138 file_util::FileEnumerator::FILES | |
118 file_util::FileEnumerator::DIRECTORIES); | 139 file_util::FileEnumerator::DIRECTORIES); |
119 | 140 |
120 // file_util winds up using autoreleased objects on the Mac, so this needs | 141 // file_util winds up using autoreleased objects on the Mac, so this needs |
121 // to be a PlatformTest | 142 // to be a PlatformTest |
122 class FileUtilTest : public PlatformTest { | 143 class FileUtilTest : public PlatformTest { |
(...skipping 1683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 | 1827 |
1807 EXPECT_TRUE(file_util::IsDirectoryEmpty(empty_dir)); | 1828 EXPECT_TRUE(file_util::IsDirectoryEmpty(empty_dir)); |
1808 | 1829 |
1809 FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt"))); | 1830 FilePath foo(empty_dir.Append(FILE_PATH_LITERAL("foo.txt"))); |
1810 std::string bar("baz"); | 1831 std::string bar("baz"); |
1811 ASSERT_TRUE(file_util::WriteFile(foo, bar.c_str(), bar.length())); | 1832 ASSERT_TRUE(file_util::WriteFile(foo, bar.c_str(), bar.length())); |
1812 | 1833 |
1813 EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir)); | 1834 EXPECT_FALSE(file_util::IsDirectoryEmpty(empty_dir)); |
1814 } | 1835 } |
1815 | 1836 |
| 1837 #if defined(OS_POSIX) |
| 1838 |
| 1839 // Testing VerifyPathControlledByAdmin() is hard, because there is no |
| 1840 // way a test can make a file owned by root, or change file paths |
| 1841 // at the root of the file system. VerifyPathControlledByAdmin() |
| 1842 // is implemented as a call to VerifyPathControlledByUser, which gives |
| 1843 // us the ability to test with paths under the test's temp directory, |
| 1844 // using a user id we control. |
| 1845 // Pull tests of VerifyPathControlledByUserTest() into a separate test class |
| 1846 // with a common SetUp() method. |
| 1847 class VerifyPathControlledByUserTest : public FileUtilTest { |
| 1848 protected: |
| 1849 virtual void SetUp() { |
| 1850 FileUtilTest::SetUp(); |
| 1851 |
| 1852 // Create a basic structure used by each test. |
| 1853 // base_dir_ |
| 1854 // |-> sub_dir_ |
| 1855 // |-> text_file_ |
| 1856 |
| 1857 base_dir_ = temp_dir_.path().AppendASCII("base_dir"); |
| 1858 ASSERT_TRUE(file_util::CreateDirectory(base_dir_)); |
| 1859 |
| 1860 sub_dir_ = base_dir_.AppendASCII("sub_dir"); |
| 1861 ASSERT_TRUE(file_util::CreateDirectory(sub_dir_)); |
| 1862 |
| 1863 text_file_ = sub_dir_.AppendASCII("file.txt"); |
| 1864 CreateTextFile(text_file_, L"This text file has some text in it."); |
| 1865 |
| 1866 // Our user and group id. |
| 1867 uid_ = getuid(); |
| 1868 gid_ = getgid(); |
| 1869 |
| 1870 // To ensure that umask settings do not cause the initial state |
| 1871 // of permissions to be different from what we expect, explicitly |
| 1872 // set permissions on the directories we create. |
| 1873 // Make all files and directories non-world-writable. |
| 1874 mode_t enabled_permissions = |
| 1875 S_IRWXU | // User can read, write, traverse |
| 1876 S_IRWXG; // Group can read, write, traverse |
| 1877 mode_t disabled_permissions = |
| 1878 S_IRWXO; // Other users can't read, write, traverse. |
| 1879 |
| 1880 ASSERT_NO_FATAL_FAILURE( |
| 1881 ChangePosixFilePermissions( |
| 1882 base_dir_, enabled_permissions, disabled_permissions)); |
| 1883 ASSERT_NO_FATAL_FAILURE( |
| 1884 ChangePosixFilePermissions( |
| 1885 sub_dir_, enabled_permissions, disabled_permissions)); |
| 1886 } |
| 1887 |
| 1888 FilePath base_dir_; |
| 1889 FilePath sub_dir_; |
| 1890 FilePath text_file_; |
| 1891 uid_t uid_; |
| 1892 gid_t gid_; |
| 1893 }; |
| 1894 |
| 1895 TEST_F(VerifyPathControlledByUserTest, BadPaths) { |
| 1896 // File does not exist. |
| 1897 FilePath does_not_exist = base_dir_.AppendASCII("does") |
| 1898 .AppendASCII("not") |
| 1899 .AppendASCII("exist"); |
| 1900 |
| 1901 EXPECT_FALSE( |
| 1902 file_util::VerifyPathControlledByUser( |
| 1903 base_dir_, does_not_exist, uid_, gid_)); |
| 1904 |
| 1905 // |base| not a subpath of |path|. |
| 1906 EXPECT_FALSE( |
| 1907 file_util::VerifyPathControlledByUser(sub_dir_, base_dir_, uid_, gid_)); |
| 1908 |
| 1909 // An empty base path will fail to be a prefix for any path. |
| 1910 FilePath empty; |
| 1911 EXPECT_FALSE( |
| 1912 file_util::VerifyPathControlledByUser(empty, base_dir_, uid_, gid_)); |
| 1913 |
| 1914 // Finding that a bad call fails proves nothing unless a good call succeeds. |
| 1915 EXPECT_TRUE( |
| 1916 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 1917 } |
| 1918 |
| 1919 TEST_F(VerifyPathControlledByUserTest, Symlinks) { |
| 1920 // Symlinks in the path should cause failure. |
| 1921 |
| 1922 // Symlink to the file at the end of the path. |
| 1923 FilePath file_link = base_dir_.AppendASCII("file_link"); |
| 1924 ASSERT_TRUE(file_util::CreateSymbolicLink(text_file_, file_link)) |
| 1925 << "Failed to create symlink."; |
| 1926 |
| 1927 EXPECT_FALSE( |
| 1928 file_util::VerifyPathControlledByUser(base_dir_, file_link, uid_, gid_)); |
| 1929 EXPECT_FALSE( |
| 1930 file_util::VerifyPathControlledByUser(file_link, file_link, uid_, gid_)); |
| 1931 |
| 1932 // Symlink from one directory to another within the path. |
| 1933 FilePath link_to_sub_dir = base_dir_.AppendASCII("link_to_sub_dir"); |
| 1934 ASSERT_TRUE(file_util::CreateSymbolicLink(sub_dir_, link_to_sub_dir)) |
| 1935 << "Failed to create symlink."; |
| 1936 |
| 1937 FilePath file_path_with_link = link_to_sub_dir.AppendASCII("file.txt"); |
| 1938 ASSERT_TRUE(file_util::PathExists(file_path_with_link)); |
| 1939 |
| 1940 EXPECT_FALSE( |
| 1941 file_util::VerifyPathControlledByUser( |
| 1942 base_dir_, file_path_with_link, uid_, gid_)); |
| 1943 |
| 1944 EXPECT_FALSE( |
| 1945 file_util::VerifyPathControlledByUser( |
| 1946 link_to_sub_dir, file_path_with_link, uid_, gid_)); |
| 1947 |
| 1948 // Symlinks in parents of base path are allowed. |
| 1949 EXPECT_TRUE( |
| 1950 file_util::VerifyPathControlledByUser( |
| 1951 file_path_with_link, file_path_with_link, uid_, gid_)); |
| 1952 } |
| 1953 |
| 1954 TEST_F(VerifyPathControlledByUserTest, OwnershipChecks) { |
| 1955 // Get a uid that is not the uid of files we create. |
| 1956 uid_t bad_uid = uid_ + 1; |
| 1957 |
| 1958 // Get a gid that is not ours. |
| 1959 gid_t bad_gid = gid_ + 1; |
| 1960 |
| 1961 // Make all files and directories non-world-writable. |
| 1962 ASSERT_NO_FATAL_FAILURE( |
| 1963 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); |
| 1964 ASSERT_NO_FATAL_FAILURE( |
| 1965 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); |
| 1966 ASSERT_NO_FATAL_FAILURE( |
| 1967 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); |
| 1968 |
| 1969 // We control these paths. |
| 1970 EXPECT_TRUE( |
| 1971 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 1972 EXPECT_TRUE( |
| 1973 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 1974 EXPECT_TRUE( |
| 1975 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 1976 |
| 1977 // Another user does not control these paths. |
| 1978 EXPECT_FALSE( |
| 1979 file_util::VerifyPathControlledByUser( |
| 1980 base_dir_, sub_dir_, bad_uid, gid_)); |
| 1981 EXPECT_FALSE( |
| 1982 file_util::VerifyPathControlledByUser( |
| 1983 base_dir_, text_file_, bad_uid, gid_)); |
| 1984 EXPECT_FALSE( |
| 1985 file_util::VerifyPathControlledByUser( |
| 1986 sub_dir_, text_file_, bad_uid, gid_)); |
| 1987 |
| 1988 // Another group does not control the paths. |
| 1989 EXPECT_FALSE( |
| 1990 file_util::VerifyPathControlledByUser( |
| 1991 base_dir_, sub_dir_, uid_, bad_gid)); |
| 1992 EXPECT_FALSE( |
| 1993 file_util::VerifyPathControlledByUser( |
| 1994 base_dir_, text_file_, uid_, bad_gid)); |
| 1995 EXPECT_FALSE( |
| 1996 file_util::VerifyPathControlledByUser( |
| 1997 sub_dir_, text_file_, uid_, bad_gid)); |
| 1998 } |
| 1999 |
| 2000 TEST_F(VerifyPathControlledByUserTest, WriteBitChecks) { |
| 2001 // Make all files and directories non-world-writable. |
| 2002 ASSERT_NO_FATAL_FAILURE( |
| 2003 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); |
| 2004 ASSERT_NO_FATAL_FAILURE( |
| 2005 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); |
| 2006 ASSERT_NO_FATAL_FAILURE( |
| 2007 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); |
| 2008 |
| 2009 // Initialy, we control all parts of the path. |
| 2010 EXPECT_TRUE( |
| 2011 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2012 EXPECT_TRUE( |
| 2013 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2014 EXPECT_TRUE( |
| 2015 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2016 |
| 2017 // Make base_dir_ world-writable. |
| 2018 ASSERT_NO_FATAL_FAILURE( |
| 2019 ChangePosixFilePermissions(base_dir_, S_IWOTH, 0u)); |
| 2020 EXPECT_FALSE( |
| 2021 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2022 EXPECT_FALSE( |
| 2023 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2024 EXPECT_TRUE( |
| 2025 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2026 |
| 2027 // Make sub_dir_ world writable. |
| 2028 ASSERT_NO_FATAL_FAILURE( |
| 2029 ChangePosixFilePermissions(sub_dir_, S_IWOTH, 0u)); |
| 2030 EXPECT_FALSE( |
| 2031 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2032 EXPECT_FALSE( |
| 2033 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2034 EXPECT_FALSE( |
| 2035 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2036 |
| 2037 // Make text_file_ world writable. |
| 2038 ASSERT_NO_FATAL_FAILURE( |
| 2039 ChangePosixFilePermissions(text_file_, S_IWOTH, 0u)); |
| 2040 EXPECT_FALSE( |
| 2041 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2042 EXPECT_FALSE( |
| 2043 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2044 EXPECT_FALSE( |
| 2045 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2046 |
| 2047 // Make sub_dir_ non-world writable. |
| 2048 ASSERT_NO_FATAL_FAILURE( |
| 2049 ChangePosixFilePermissions(sub_dir_, 0u, S_IWOTH)); |
| 2050 EXPECT_FALSE( |
| 2051 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2052 EXPECT_FALSE( |
| 2053 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2054 EXPECT_FALSE( |
| 2055 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2056 |
| 2057 // Make base_dir_ non-world-writable. |
| 2058 ASSERT_NO_FATAL_FAILURE( |
| 2059 ChangePosixFilePermissions(base_dir_, 0u, S_IWOTH)); |
| 2060 EXPECT_TRUE( |
| 2061 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2062 EXPECT_FALSE( |
| 2063 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2064 EXPECT_FALSE( |
| 2065 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2066 |
| 2067 // Back to the initial state: Nothing is writable, so every path |
| 2068 // should pass. |
| 2069 ASSERT_NO_FATAL_FAILURE( |
| 2070 ChangePosixFilePermissions(text_file_, 0u, S_IWOTH)); |
| 2071 EXPECT_TRUE( |
| 2072 file_util::VerifyPathControlledByUser(base_dir_, sub_dir_, uid_, gid_)); |
| 2073 EXPECT_TRUE( |
| 2074 file_util::VerifyPathControlledByUser(base_dir_, text_file_, uid_, gid_)); |
| 2075 EXPECT_TRUE( |
| 2076 file_util::VerifyPathControlledByUser(sub_dir_, text_file_, uid_, gid_)); |
| 2077 } |
| 2078 |
| 2079 #endif // defined(OS_POSIX) |
| 2080 |
1816 } // namespace | 2081 } // namespace |
OLD | NEW |