OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 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 "sandbox/src/registry_interception.h" | |
6 | |
7 #include "sandbox/src/crosscall_client.h" | |
8 #include "sandbox/src/ipc_tags.h" | |
9 #include "sandbox/src/sandbox_factory.h" | |
10 #include "sandbox/src/sandbox_nt_util.h" | |
11 #include "sandbox/src/sharedmem_ipc_client.h" | |
12 #include "sandbox/src/target_services.h" | |
13 | |
14 namespace sandbox { | |
15 | |
16 NTSTATUS WINAPI TargetNtCreateKey(NtCreateKeyFunction orig_CreateKey, | |
17 PHANDLE key, ACCESS_MASK desired_access, | |
18 POBJECT_ATTRIBUTES object_attributes, | |
19 ULONG title_index, PUNICODE_STRING class_name, | |
20 ULONG create_options, PULONG disposition) { | |
21 // Check if the process can create it first. | |
22 NTSTATUS status = orig_CreateKey(key, desired_access, object_attributes, | |
23 title_index, class_name, create_options, | |
24 disposition); | |
25 if (NT_SUCCESS(status)) | |
26 return status; | |
27 | |
28 // We don't trust that the IPC can work this early. | |
29 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) | |
30 return status; | |
31 | |
32 do { | |
33 if (!ValidParameter(key, sizeof(HANDLE), WRITE)) | |
34 break; | |
35 | |
36 if (disposition && !ValidParameter(disposition, sizeof(ULONG), WRITE)) | |
37 break; | |
38 | |
39 // At this point we don't support class_name. | |
40 if (class_name && class_name->Buffer && class_name->Length) | |
41 break; | |
42 | |
43 // We don't support creating link keys, volatile keys and backup/restore. | |
44 if (create_options) | |
45 break; | |
46 | |
47 void* memory = GetGlobalIPCMemory(); | |
48 if (NULL == memory) | |
49 break; | |
50 | |
51 wchar_t* name; | |
52 uint32 attributes = 0; | |
53 HANDLE root_directory = 0; | |
54 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes, | |
55 &root_directory); | |
56 if (!NT_SUCCESS(ret) || NULL == name) | |
57 break; | |
58 | |
59 SharedMemIPCClient ipc(memory); | |
60 CrossCallReturn answer = {0}; | |
61 | |
62 ResultCode code = CrossCall(ipc, IPC_NTCREATEKEY_TAG, name, attributes, | |
63 root_directory, desired_access, title_index, | |
64 create_options, &answer); | |
65 | |
66 operator delete(name, NT_ALLOC); | |
67 | |
68 if (SBOX_ALL_OK != code) | |
69 break; | |
70 | |
71 if (!NT_SUCCESS(answer.nt_status)) | |
72 // TODO(nsylvain): We should return answer.nt_status here instead | |
73 // of status. We can do this only after we checked the policy. | |
74 // otherwise we will returns ACCESS_DENIED for all paths | |
75 // that are not specified by a policy, even though your token allows | |
76 // access to that path, and the original call had a more meaningful | |
77 // error. Bug 4369 | |
78 break; | |
79 | |
80 __try { | |
81 *key = answer.handle; | |
82 | |
83 if (disposition) | |
84 *disposition = answer.extended[0].unsigned_int; | |
85 | |
86 status = answer.nt_status; | |
87 } __except(EXCEPTION_EXECUTE_HANDLER) { | |
88 break; | |
89 } | |
90 } while (false); | |
91 | |
92 return status; | |
93 } | |
94 | |
95 NTSTATUS WINAPI CommonNtOpenKey(NTSTATUS status, PHANDLE key, | |
96 ACCESS_MASK desired_access, | |
97 POBJECT_ATTRIBUTES object_attributes) { | |
98 // We don't trust that the IPC can work this early. | |
99 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled()) | |
100 return status; | |
101 | |
102 do { | |
103 if (!ValidParameter(key, sizeof(HANDLE), WRITE)) | |
104 break; | |
105 | |
106 void* memory = GetGlobalIPCMemory(); | |
107 if (NULL == memory) | |
108 break; | |
109 | |
110 wchar_t* name; | |
111 uint32 attributes; | |
112 HANDLE root_directory; | |
113 NTSTATUS ret = AllocAndCopyName(object_attributes, &name, &attributes, | |
114 &root_directory); | |
115 if (!NT_SUCCESS(ret) || NULL == name) | |
116 break; | |
117 | |
118 SharedMemIPCClient ipc(memory); | |
119 CrossCallReturn answer = {0}; | |
120 ResultCode code = CrossCall(ipc, IPC_NTOPENKEY_TAG, name, attributes, | |
121 root_directory, desired_access, &answer); | |
122 | |
123 operator delete(name, NT_ALLOC); | |
124 | |
125 if (SBOX_ALL_OK != code) | |
126 break; | |
127 | |
128 if (!NT_SUCCESS(answer.nt_status)) | |
129 // TODO(nsylvain): We should return answer.nt_status here instead | |
130 // of status. We can do this only after we checked the policy. | |
131 // otherwise we will returns ACCESS_DENIED for all paths | |
132 // that are not specified by a policy, even though your token allows | |
133 // access to that path, and the original call had a more meaningful | |
134 // error. Bug 4369 | |
135 break; | |
136 | |
137 __try { | |
138 *key = answer.handle; | |
139 status = answer.nt_status; | |
140 } __except(EXCEPTION_EXECUTE_HANDLER) { | |
141 break; | |
142 } | |
143 } while (false); | |
144 | |
145 return status; | |
146 } | |
147 | |
148 NTSTATUS WINAPI TargetNtOpenKey(NtOpenKeyFunction orig_OpenKey, PHANDLE key, | |
149 ACCESS_MASK desired_access, | |
150 POBJECT_ATTRIBUTES object_attributes) { | |
151 // Check if the process can open it first. | |
152 NTSTATUS status = orig_OpenKey(key, desired_access, object_attributes); | |
153 if (NT_SUCCESS(status)) | |
154 return status; | |
155 | |
156 return CommonNtOpenKey(status, key, desired_access, object_attributes); | |
157 } | |
158 | |
159 NTSTATUS WINAPI TargetNtOpenKeyEx(NtOpenKeyExFunction orig_OpenKeyEx, | |
160 PHANDLE key, ACCESS_MASK desired_access, | |
161 POBJECT_ATTRIBUTES object_attributes, | |
162 ULONG open_options) { | |
163 // Check if the process can open it first. | |
164 NTSTATUS status = orig_OpenKeyEx(key, desired_access, object_attributes, | |
165 open_options); | |
166 | |
167 // We do not support open_options at this time. The 2 current known values | |
168 // are REG_OPTION_CREATE_LINK, to open a symbolic link, and | |
169 // REG_OPTION_BACKUP_RESTORE to open the key with special privileges. | |
170 if (NT_SUCCESS(status) || open_options != 0) | |
171 return status; | |
172 | |
173 return CommonNtOpenKey(status, key, desired_access, object_attributes); | |
174 } | |
175 | |
176 } // namespace sandbox | |
OLD | NEW |