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