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.
5 #include "sandbox/win/src/registry_interception.h"
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/ipc_tags.h"
9 #include "sandbox/win/src/sandbox_factory.h"
10 #include "sandbox/win/src/sandbox_nt_util.h"
11 #include "sandbox/win/src/sharedmem_ipc_client.h"
12 #include "sandbox/win/src/target_services.h"
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
,
25 if (NT_SUCCESS(status
))
28 // We don't trust that the IPC can work this early.
29 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
33 if (!ValidParameter(key
, sizeof(HANDLE
), WRITE
))
36 if (disposition
&& !ValidParameter(disposition
, sizeof(ULONG
), WRITE
))
39 // At this point we don't support class_name.
40 if (class_name
&& class_name
->Buffer
&& class_name
->Length
)
43 // We don't support creating link keys, volatile keys and backup/restore.
47 void* memory
= GetGlobalIPCMemory();
52 uint32 attributes
= 0;
53 HANDLE root_directory
= 0;
54 NTSTATUS ret
= AllocAndCopyName(object_attributes
, &name
, &attributes
,
56 if (!NT_SUCCESS(ret
) || NULL
== name
)
59 SharedMemIPCClient
ipc(memory
);
60 CrossCallReturn answer
= {0};
62 ResultCode code
= CrossCall(ipc
, IPC_NTCREATEKEY_TAG
, name
, attributes
,
63 root_directory
, desired_access
, title_index
,
64 create_options
, &answer
);
66 operator delete(name
, NT_ALLOC
);
68 if (SBOX_ALL_OK
!= code
)
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
84 *disposition
= answer
.extended
[0].unsigned_int
;
86 status
= answer
.nt_status
;
87 } __except(EXCEPTION_EXECUTE_HANDLER
) {
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())
103 if (!ValidParameter(key
, sizeof(HANDLE
), WRITE
))
106 void* memory
= GetGlobalIPCMemory();
112 HANDLE root_directory
;
113 NTSTATUS ret
= AllocAndCopyName(object_attributes
, &name
, &attributes
,
115 if (!NT_SUCCESS(ret
) || NULL
== name
)
118 SharedMemIPCClient
ipc(memory
);
119 CrossCallReturn answer
= {0};
120 ResultCode code
= CrossCall(ipc
, IPC_NTOPENKEY_TAG
, name
, attributes
,
121 root_directory
, desired_access
, &answer
);
123 operator delete(name
, NT_ALLOC
);
125 if (SBOX_ALL_OK
!= code
)
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
138 *key
= answer
.handle
;
139 status
= answer
.nt_status
;
140 } __except(EXCEPTION_EXECUTE_HANDLER
) {
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
))
156 return CommonNtOpenKey(status
, key
, desired_access
, object_attributes
);
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
,
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)
173 return CommonNtOpenKey(status
, key
, desired_access
, object_attributes
);
176 } // namespace sandbox