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