Home | History | Annotate | Download | only in src
      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
      3 // found in the LICENSE file.
      4 
      5 #include <algorithm>
      6 #include <cctype>
      7 
      8 #include <windows.h>
      9 #include <winioctl.h>
     10 
     11 #include "base/win/scoped_handle.h"
     12 #include "sandbox/win/src/nt_internals.h"
     13 #include "sandbox/win/src/sandbox.h"
     14 #include "sandbox/win/src/sandbox_factory.h"
     15 #include "sandbox/win/src/sandbox_policy.h"
     16 #include "sandbox/win/src/win_utils.h"
     17 #include "sandbox/win/tests/common/controller.h"
     18 #include "sandbox/win/tests/common/test_utils.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 #define BINDNTDLL(name) \
     22   name ## Function name = reinterpret_cast<name ## Function>( \
     23     ::GetProcAddress(::GetModuleHandle(L"ntdll.dll"), #name))
     24 
     25 namespace sandbox {
     26 
     27 const ULONG kSharing = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
     28 
     29 // Creates a file using different desired access. Returns if the call succeeded
     30 // or not.  The first argument in argv is the filename. If the second argument
     31 // is "read", we try read only access. Otherwise we try read-write access.
     32 SBOX_TESTS_COMMAND int File_Create(int argc, wchar_t **argv) {
     33   if (argc != 2)
     34     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
     35 
     36   bool read = (_wcsicmp(argv[0], L"Read") == 0);
     37 
     38   if (read) {
     39     base::win::ScopedHandle file1(CreateFile(
     40         argv[1], GENERIC_READ, kSharing, NULL, OPEN_EXISTING, 0, NULL));
     41     base::win::ScopedHandle file2(CreateFile(
     42         argv[1], FILE_EXECUTE, kSharing, NULL, OPEN_EXISTING, 0, NULL));
     43 
     44     if (file1.Get() && file2.Get())
     45       return SBOX_TEST_SUCCEEDED;
     46     return SBOX_TEST_DENIED;
     47   } else {
     48     base::win::ScopedHandle file1(CreateFile(
     49         argv[1], GENERIC_ALL, kSharing, NULL, OPEN_EXISTING, 0, NULL));
     50     base::win::ScopedHandle file2(CreateFile(
     51         argv[1], GENERIC_READ | FILE_WRITE_DATA, kSharing, NULL, OPEN_EXISTING,
     52         0, NULL));
     53 
     54     if (file1.Get() && file2.Get())
     55       return SBOX_TEST_SUCCEEDED;
     56     return SBOX_TEST_DENIED;
     57   }
     58 }
     59 
     60 SBOX_TESTS_COMMAND int File_Win32Create(int argc, wchar_t **argv) {
     61   if (argc != 1) {
     62     SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
     63   }
     64 
     65   std::wstring full_path = MakePathToSys(argv[0], false);
     66   if (full_path.empty()) {
     67     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
     68   }
     69 
     70   HANDLE file = ::CreateFileW(full_path.c_str(), GENERIC_READ, kSharing,
     71                               NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     72 
     73   if (INVALID_HANDLE_VALUE != file) {
     74     ::CloseHandle(file);
     75     return SBOX_TEST_SUCCEEDED;
     76   } else {
     77     if (ERROR_ACCESS_DENIED == ::GetLastError()) {
     78       return SBOX_TEST_DENIED;
     79     } else {
     80       return SBOX_TEST_FAILED;
     81     }
     82   }
     83   return SBOX_TEST_SUCCEEDED;
     84 }
     85 
     86 // Creates the file in parameter using the NtCreateFile api and returns if the
     87 // call succeeded or not.
     88 SBOX_TESTS_COMMAND int File_CreateSys32(int argc, wchar_t **argv) {
     89   BINDNTDLL(NtCreateFile);
     90   BINDNTDLL(RtlInitUnicodeString);
     91   if (!NtCreateFile || !RtlInitUnicodeString)
     92     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
     93 
     94   if (argc != 1)
     95     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
     96 
     97   std::wstring file(argv[0]);
     98   if (0 != _wcsnicmp(file.c_str(), kNTObjManPrefix, kNTObjManPrefixLen))
     99     file = MakePathToSys(argv[0], true);
    100 
    101   UNICODE_STRING object_name;
    102   RtlInitUnicodeString(&object_name, file.c_str());
    103 
    104   OBJECT_ATTRIBUTES obj_attributes = {0};
    105   InitializeObjectAttributes(&obj_attributes, &object_name,
    106                              OBJ_CASE_INSENSITIVE, NULL, NULL);
    107 
    108   HANDLE handle;
    109   IO_STATUS_BLOCK io_block = {0};
    110   NTSTATUS status = NtCreateFile(&handle, FILE_READ_DATA, &obj_attributes,
    111                                  &io_block, NULL, 0, kSharing, FILE_OPEN,
    112                                  0, NULL, 0);
    113   if (NT_SUCCESS(status)) {
    114     ::CloseHandle(handle);
    115     return SBOX_TEST_SUCCEEDED;
    116   } else if (STATUS_ACCESS_DENIED == status) {
    117     return SBOX_TEST_DENIED;
    118   } else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
    119     return SBOX_TEST_NOT_FOUND;
    120   }
    121   return SBOX_TEST_FAILED;
    122 }
    123 
    124 // Opens the file in parameter using the NtOpenFile api and returns if the
    125 // call succeeded or not.
    126 SBOX_TESTS_COMMAND int File_OpenSys32(int argc, wchar_t **argv) {
    127   BINDNTDLL(NtOpenFile);
    128   BINDNTDLL(RtlInitUnicodeString);
    129   if (!NtOpenFile || !RtlInitUnicodeString)
    130     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    131 
    132   if (argc != 1)
    133     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    134 
    135   std::wstring file = MakePathToSys(argv[0], true);
    136   UNICODE_STRING object_name;
    137   RtlInitUnicodeString(&object_name, file.c_str());
    138 
    139   OBJECT_ATTRIBUTES obj_attributes = {0};
    140   InitializeObjectAttributes(&obj_attributes, &object_name,
    141                              OBJ_CASE_INSENSITIVE, NULL, NULL);
    142 
    143   HANDLE handle;
    144   IO_STATUS_BLOCK io_block = {0};
    145   NTSTATUS status = NtOpenFile(&handle, FILE_READ_DATA, &obj_attributes,
    146                                &io_block, kSharing, 0);
    147   if (NT_SUCCESS(status)) {
    148     ::CloseHandle(handle);
    149     return SBOX_TEST_SUCCEEDED;
    150   } else if (STATUS_ACCESS_DENIED == status) {
    151     return SBOX_TEST_DENIED;
    152   } else if (STATUS_OBJECT_NAME_NOT_FOUND == status) {
    153     return SBOX_TEST_NOT_FOUND;
    154   }
    155   return SBOX_TEST_FAILED;
    156 }
    157 
    158 SBOX_TESTS_COMMAND int File_GetDiskSpace(int argc, wchar_t **argv) {
    159   std::wstring sys_path = MakePathToSys(L"", false);
    160   if (sys_path.empty()) {
    161     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    162   }
    163   ULARGE_INTEGER free_user = {0};
    164   ULARGE_INTEGER total = {0};
    165   ULARGE_INTEGER free_total = {0};
    166   if (::GetDiskFreeSpaceExW(sys_path.c_str(), &free_user, &total,
    167                             &free_total)) {
    168     if ((total.QuadPart != 0) && (free_total.QuadPart !=0)) {
    169       return SBOX_TEST_SUCCEEDED;
    170     }
    171   } else {
    172     if (ERROR_ACCESS_DENIED == ::GetLastError()) {
    173       return SBOX_TEST_DENIED;
    174     } else {
    175       return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    176     }
    177   }
    178   return SBOX_TEST_SUCCEEDED;
    179 }
    180 
    181 // Move a file using the MoveFileEx api and returns if the call succeeded or
    182 // not.
    183 SBOX_TESTS_COMMAND int File_Rename(int argc, wchar_t **argv) {
    184   if (argc != 2)
    185     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    186 
    187   if (::MoveFileEx(argv[0], argv[1], 0))
    188     return SBOX_TEST_SUCCEEDED;
    189 
    190   if (::GetLastError() != ERROR_ACCESS_DENIED)
    191     return SBOX_TEST_FAILED;
    192 
    193   return SBOX_TEST_DENIED;
    194 }
    195 
    196 // Query the attributes of file in parameter using the NtQueryAttributesFile api
    197 // and NtQueryFullAttributesFile and returns if the call succeeded or not. The
    198 // second argument in argv is "d" or "f" telling if we expect the attributes to
    199 // specify a file or a directory. The expected attribute has to match the real
    200 // attributes for the call to be successful.
    201 SBOX_TESTS_COMMAND int File_QueryAttributes(int argc, wchar_t **argv) {
    202   BINDNTDLL(NtQueryAttributesFile);
    203   BINDNTDLL(NtQueryFullAttributesFile);
    204   BINDNTDLL(RtlInitUnicodeString);
    205   if (!NtQueryAttributesFile || !NtQueryFullAttributesFile ||
    206       !RtlInitUnicodeString)
    207     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    208 
    209   if (argc != 2)
    210     return SBOX_TEST_FAILED_TO_EXECUTE_COMMAND;
    211 
    212   bool expect_directory = (L'd' == argv[1][0]);
    213 
    214   UNICODE_STRING object_name;
    215   std::wstring file = MakePathToSys(argv[0], true);
    216   RtlInitUnicodeString(&object_name, file.c_str());
    217 
    218   OBJECT_ATTRIBUTES obj_attributes = {0};
    219   InitializeObjectAttributes(&obj_attributes, &object_name,
    220                              OBJ_CASE_INSENSITIVE, NULL, NULL);
    221 
    222   FILE_BASIC_INFORMATION info = {0};
    223   FILE_NETWORK_OPEN_INFORMATION full_info = {0};
    224   NTSTATUS status1 = NtQueryAttributesFile(&obj_attributes, &info);
    225   NTSTATUS status2 = NtQueryFullAttributesFile(&obj_attributes, &full_info);
    226 
    227   if (status1 != status2)
    228     return SBOX_TEST_FAILED;
    229 
    230   if (NT_SUCCESS(status1)) {
    231     if (info.FileAttributes != full_info.FileAttributes)
    232       return SBOX_TEST_FAILED;
    233 
    234     bool is_directory1 = (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
    235     if (expect_directory == is_directory1)
    236       return SBOX_TEST_SUCCEEDED;
    237   } else if (STATUS_ACCESS_DENIED == status1) {
    238     return SBOX_TEST_DENIED;
    239   } else if (STATUS_OBJECT_NAME_NOT_FOUND == status1) {
    240     return SBOX_TEST_NOT_FOUND;
    241   }
    242 
    243   return SBOX_TEST_FAILED;
    244 }
    245 
    246 TEST(FilePolicyTest, DenyNtCreateCalc) {
    247   TestRunner runner;
    248   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY,
    249                                   L"calc.exe"));
    250 
    251   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_CreateSys32 calc.exe"));
    252 
    253   runner.SetTestState(BEFORE_REVERT);
    254   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe"));
    255 }
    256 
    257 TEST(FilePolicyTest, AllowNtCreateCalc) {
    258   TestRunner runner;
    259   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"calc.exe"));
    260 
    261   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe"));
    262 
    263   runner.SetTestState(BEFORE_REVERT);
    264   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_CreateSys32 calc.exe"));
    265 }
    266 
    267 TEST(FilePolicyTest, AllowNtCreateWithNativePath) {
    268   std::wstring calc = MakePathToSys(L"calc.exe", false);
    269   std::wstring nt_path;
    270   ASSERT_TRUE(GetNtPathFromWin32Path(calc, &nt_path));
    271   TestRunner runner;
    272   runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY, nt_path.c_str());
    273 
    274   wchar_t buff[MAX_PATH];
    275   ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str());
    276   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff));
    277 
    278   std::transform(nt_path.begin(), nt_path.end(), nt_path.begin(), std::tolower);
    279   ::wsprintfW(buff, L"File_CreateSys32 %s", nt_path.c_str());
    280   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(buff));
    281 }
    282 
    283 TEST(FilePolicyTest, AllowReadOnly) {
    284   TestRunner runner;
    285 
    286   // Create a temp file because we need write access to it.
    287   wchar_t temp_directory[MAX_PATH];
    288   wchar_t temp_file_name[MAX_PATH];
    289   ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
    290   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u);
    291 
    292   EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY,
    293                                temp_file_name));
    294 
    295   wchar_t command_read[MAX_PATH + 20] = {0};
    296   wsprintf(command_read, L"File_Create Read \"%ls\"", temp_file_name);
    297   wchar_t command_write[MAX_PATH + 20] = {0};
    298   wsprintf(command_write, L"File_Create Write \"%ls\"", temp_file_name);
    299 
    300   // Verify that we have read access after revert.
    301   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_read));
    302 
    303   // Verify that we don't have write access after revert.
    304   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command_write));
    305 
    306   // Verify that we really have write access to the file.
    307   runner.SetTestState(BEFORE_REVERT);
    308   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_write));
    309 
    310   DeleteFile(temp_file_name);
    311 }
    312 
    313 TEST(FilePolicyTest, AllowWildcard) {
    314   TestRunner runner;
    315 
    316   // Create a temp file because we need write access to it.
    317   wchar_t temp_directory[MAX_PATH];
    318   wchar_t temp_file_name[MAX_PATH];
    319   ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
    320   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u);
    321 
    322   wcscat_s(temp_directory, MAX_PATH, L"*");
    323   EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_directory));
    324 
    325   wchar_t command_write[MAX_PATH + 20] = {0};
    326   wsprintf(command_write, L"File_Create Write \"%ls\"", temp_file_name);
    327 
    328   // Verify that we have write access after revert.
    329   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_write));
    330 
    331   DeleteFile(temp_file_name);
    332 }
    333 
    334 TEST(FilePolicyTest, AllowNtCreatePatternRule) {
    335   TestRunner runner;
    336   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"App*.dll"));
    337 
    338   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    339             runner.RunTest(L"File_OpenSys32 appmgmts.dll"));
    340   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_OpenSys32 appwiz.cpl"));
    341 
    342   runner.SetTestState(BEFORE_REVERT);
    343   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    344             runner.RunTest(L"File_OpenSys32 appmgmts.dll"));
    345   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_OpenSys32 appwiz.cpl"));
    346 }
    347 
    348 TEST(FilePolicyTest, CheckNotFound) {
    349   TestRunner runner;
    350   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"n*.dll"));
    351 
    352   EXPECT_EQ(SBOX_TEST_NOT_FOUND,
    353             runner.RunTest(L"File_OpenSys32 notfound.dll"));
    354 }
    355 
    356 TEST(FilePolicyTest, CheckNoLeak) {
    357   TestRunner runner;
    358   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_CreateSys32 notfound.exe"));
    359 }
    360 
    361 TEST(FilePolicyTest, TestQueryAttributesFile) {
    362   TestRunner runner;
    363   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY,
    364                                   L"appmgmts.dll"));
    365   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY,
    366                                   L"notfound.exe"));
    367   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY, L"drivers"));
    368   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_QUERY,
    369                                   L"ipconfig.exe"));
    370 
    371   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    372             runner.RunTest(L"File_QueryAttributes drivers d"));
    373 
    374   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    375             runner.RunTest(L"File_QueryAttributes appmgmts.dll f"));
    376 
    377   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    378             runner.RunTest(L"File_QueryAttributes ipconfig.exe f"));
    379 
    380   EXPECT_EQ(SBOX_TEST_DENIED,
    381             runner.RunTest(L"File_QueryAttributes ftp.exe f"));
    382 
    383   EXPECT_EQ(SBOX_TEST_NOT_FOUND,
    384             runner.RunTest(L"File_QueryAttributes notfound.exe f"));
    385 }
    386 
    387 // Makes sure that we don't leak information when there is not policy to allow
    388 // a path.
    389 TEST(FilePolicyTest, TestQueryAttributesFileNoPolicy) {
    390   TestRunner runner;
    391   EXPECT_EQ(SBOX_TEST_DENIED,
    392             runner.RunTest(L"File_QueryAttributes ftp.exe f"));
    393 
    394   EXPECT_EQ(SBOX_TEST_DENIED,
    395             runner.RunTest(L"File_QueryAttributes notfound.exe f"));
    396 }
    397 
    398 TEST(FilePolicyTest, TestRename) {
    399   TestRunner runner;
    400 
    401   // Give access to the temp directory.
    402   wchar_t temp_directory[MAX_PATH];
    403   wchar_t temp_file_name1[MAX_PATH];
    404   wchar_t temp_file_name2[MAX_PATH];
    405   wchar_t temp_file_name3[MAX_PATH];
    406   wchar_t temp_file_name4[MAX_PATH];
    407   wchar_t temp_file_name5[MAX_PATH];
    408   wchar_t temp_file_name6[MAX_PATH];
    409   wchar_t temp_file_name7[MAX_PATH];
    410   wchar_t temp_file_name8[MAX_PATH];
    411   ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
    412   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name1), 0u);
    413   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name2), 0u);
    414   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name3), 0u);
    415   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name4), 0u);
    416   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name5), 0u);
    417   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name6), 0u);
    418   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name7), 0u);
    419   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name8), 0u);
    420 
    421 
    422   // Add rules to make file1->file2 succeed.
    423   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name1));
    424   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name2));
    425 
    426   // Add rules to make file3->file4 fail.
    427   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name3));
    428   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY,
    429                                temp_file_name4));
    430 
    431   // Add rules to make file5->file6 fail.
    432   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY,
    433                                temp_file_name5));
    434   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name6));
    435 
    436   // Add rules to make file7->no_pol_file fail.
    437   ASSERT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY, temp_file_name7));
    438 
    439   // Delete the files where the files are going to be renamed to.
    440   ::DeleteFile(temp_file_name2);
    441   ::DeleteFile(temp_file_name4);
    442   ::DeleteFile(temp_file_name6);
    443   ::DeleteFile(temp_file_name8);
    444 
    445 
    446   wchar_t command[MAX_PATH*2 + 20] = {0};
    447   wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name1,
    448            temp_file_name2);
    449   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command));
    450 
    451   wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name3,
    452            temp_file_name4);
    453   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    454 
    455   wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name5,
    456            temp_file_name6);
    457   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    458 
    459   wsprintf(command, L"File_Rename \"%ls\" \"%ls\"", temp_file_name7,
    460            temp_file_name8);
    461   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
    462 
    463 
    464   // Delete all the files in case they are still there.
    465   ::DeleteFile(temp_file_name1);
    466   ::DeleteFile(temp_file_name2);
    467   ::DeleteFile(temp_file_name3);
    468   ::DeleteFile(temp_file_name4);
    469   ::DeleteFile(temp_file_name5);
    470   ::DeleteFile(temp_file_name6);
    471   ::DeleteFile(temp_file_name7);
    472   ::DeleteFile(temp_file_name8);
    473 }
    474 
    475 TEST(FilePolicyTest, OpenSys32FilesDenyBecauseOfDir) {
    476   TestRunner runner;
    477   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY,
    478                                   L"notepad.exe"));
    479 
    480   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_Win32Create notepad.exe"));
    481 
    482   runner.SetTestState(BEFORE_REVERT);
    483   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    484             runner.RunTest(L"File_Win32Create notepad.exe"));
    485 }
    486 
    487 TEST(FilePolicyTest, OpenSys32FilesAllowNotepad) {
    488   TestRunner runner;
    489   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_ANY,
    490                                   L"notepad.exe"));
    491 
    492   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    493             runner.RunTest(L"File_Win32Create notepad.exe"));
    494 
    495   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_Win32Create calc.exe"));
    496 
    497   runner.SetTestState(BEFORE_REVERT);
    498   EXPECT_EQ(SBOX_TEST_SUCCEEDED,
    499             runner.RunTest(L"File_Win32Create notepad.exe"));
    500   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_Win32Create calc.exe"));
    501 }
    502 
    503 TEST(FilePolicyTest, FileGetDiskSpace) {
    504   TestRunner runner;
    505   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_GetDiskSpace"));
    506   runner.SetTestState(BEFORE_REVERT);
    507   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_GetDiskSpace"));
    508 
    509   // Add an 'allow' rule in the windows\system32 such that GetDiskFreeSpaceEx
    510   // succeeds (it does an NtOpenFile) but windows\system32\notepad.exe is
    511   // denied since there is no wild card in the rule.
    512   EXPECT_TRUE(runner.AddRuleSys32(TargetPolicy::FILES_ALLOW_DIR_ANY, L""));
    513   runner.SetTestState(BEFORE_REVERT);
    514   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_GetDiskSpace"));
    515 
    516   runner.SetTestState(AFTER_REVERT);
    517   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"File_GetDiskSpace"));
    518   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"File_Win32Create notepad.exe"));
    519 }
    520 
    521 // http://crbug.com/146944
    522 TEST(FilePolicyTest, DISABLED_TestReparsePoint) {
    523   TestRunner runner;
    524 
    525   // Create a temp file because we need write access to it.
    526   wchar_t temp_directory[MAX_PATH];
    527   wchar_t temp_file_name[MAX_PATH];
    528   ASSERT_NE(::GetTempPath(MAX_PATH, temp_directory), 0u);
    529   ASSERT_NE(::GetTempFileName(temp_directory, L"test", 0, temp_file_name), 0u);
    530 
    531   // Delete the file and create a directory instead.
    532   ASSERT_TRUE(::DeleteFile(temp_file_name));
    533   ASSERT_TRUE(::CreateDirectory(temp_file_name, NULL));
    534 
    535   // Create a temporary file in the subfolder.
    536   std::wstring subfolder = temp_file_name;
    537   std::wstring temp_file_title = subfolder.substr(subfolder.rfind(L"\\") + 1);
    538   std::wstring temp_file = subfolder + L"\\file_" + temp_file_title;
    539 
    540   HANDLE file = ::CreateFile(temp_file.c_str(), FILE_ALL_ACCESS,
    541                              FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    542                              CREATE_ALWAYS, 0, NULL);
    543   ASSERT_TRUE(INVALID_HANDLE_VALUE != file);
    544   ASSERT_TRUE(::CloseHandle(file));
    545 
    546   // Create a temporary file in the temp directory.
    547   std::wstring temp_dir = temp_directory;
    548   std::wstring temp_file_in_temp = temp_dir + L"file_" + temp_file_title;
    549   file = ::CreateFile(temp_file_in_temp.c_str(), FILE_ALL_ACCESS,
    550                       FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    551                       CREATE_ALWAYS, 0, NULL);
    552   ASSERT_TRUE(file != NULL);
    553   ASSERT_TRUE(::CloseHandle(file));
    554 
    555   // Give write access to the temp directory.
    556   std::wstring temp_dir_wildcard = temp_dir + L"*";
    557   EXPECT_TRUE(runner.AddFsRule(TargetPolicy::FILES_ALLOW_ANY,
    558                                temp_dir_wildcard.c_str()));
    559 
    560   // Prepare the command to execute.
    561   std::wstring command_write;
    562   command_write += L"File_Create Write \"";
    563   command_write += temp_file;
    564   command_write += L"\"";
    565 
    566   // Verify that we have write access to the original file
    567   EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(command_write.c_str()));
    568 
    569   // Replace the subfolder by a reparse point to %temp%.
    570   ::DeleteFile(temp_file.c_str());
    571   HANDLE dir = ::CreateFile(subfolder.c_str(), FILE_ALL_ACCESS,
    572                             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    573                             OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    574   EXPECT_TRUE(INVALID_HANDLE_VALUE != dir);
    575 
    576   std::wstring temp_dir_nt;
    577   temp_dir_nt += L"\\??\\";
    578   temp_dir_nt += temp_dir;
    579   EXPECT_TRUE(SetReparsePoint(dir, temp_dir_nt.c_str()));
    580   EXPECT_TRUE(::CloseHandle(dir));
    581 
    582   // Try to open the file again.
    583   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command_write.c_str()));
    584 
    585   // Remove the reparse point.
    586   dir = ::CreateFile(subfolder.c_str(), FILE_ALL_ACCESS,
    587                      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
    588                      FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
    589                      NULL);
    590   EXPECT_TRUE(INVALID_HANDLE_VALUE != dir);
    591   EXPECT_TRUE(DeleteReparsePoint(dir));
    592   EXPECT_TRUE(::CloseHandle(dir));
    593 
    594   // Cleanup.
    595   EXPECT_TRUE(::DeleteFile(temp_file_in_temp.c_str()));
    596   EXPECT_TRUE(::RemoveDirectory(subfolder.c_str()));
    597 }
    598 
    599 }  // namespace sandbox
    600