• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/win/src/sync_interception.h"
6 
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/ipc_tags.h"
9 #include "sandbox/win/src/policy_params.h"
10 #include "sandbox/win/src/policy_target.h"
11 #include "sandbox/win/src/sandbox_factory.h"
12 #include "sandbox/win/src/sandbox_nt_util.h"
13 #include "sandbox/win/src/sharedmem_ipc_client.h"
14 #include "sandbox/win/src/target_services.h"
15 
16 namespace sandbox {
17 
ProxyCreateEvent(LPCWSTR name,BOOL initial_state,EVENT_TYPE event_type,void * ipc_memory,CrossCallReturn * answer)18 ResultCode ProxyCreateEvent(LPCWSTR name,
19                             BOOL initial_state,
20                             EVENT_TYPE event_type,
21                             void* ipc_memory,
22                             CrossCallReturn* answer) {
23   CountedParameterSet<NameBased> params;
24   params[NameBased::NAME] = ParamPickerMake(name);
25 
26   if (!QueryBroker(IPC_CREATEEVENT_TAG, params.GetBase()))
27     return SBOX_ERROR_GENERIC;
28 
29   SharedMemIPCClient ipc(ipc_memory);
30   ResultCode code = CrossCall(ipc, IPC_CREATEEVENT_TAG, name, event_type,
31                               initial_state, answer);
32   return code;
33 }
34 
ProxyOpenEvent(LPCWSTR name,ACCESS_MASK desired_access,void * ipc_memory,CrossCallReturn * answer)35 ResultCode ProxyOpenEvent(LPCWSTR name,
36                           ACCESS_MASK desired_access,
37                           void* ipc_memory,
38                           CrossCallReturn* answer) {
39   CountedParameterSet<OpenEventParams> params;
40   params[OpenEventParams::NAME] = ParamPickerMake(name);
41   params[OpenEventParams::ACCESS] = ParamPickerMake(desired_access);
42 
43   if (!QueryBroker(IPC_OPENEVENT_TAG, params.GetBase()))
44     return SBOX_ERROR_GENERIC;
45 
46   SharedMemIPCClient ipc(ipc_memory);
47   ResultCode code = CrossCall(ipc, IPC_OPENEVENT_TAG, name, desired_access,
48                               answer);
49 
50   return code;
51 }
52 
TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,PHANDLE event_handle,ACCESS_MASK desired_access,POBJECT_ATTRIBUTES object_attributes,EVENT_TYPE event_type,BOOLEAN initial_state)53 NTSTATUS WINAPI TargetNtCreateEvent(NtCreateEventFunction orig_CreateEvent,
54                                     PHANDLE event_handle,
55                                     ACCESS_MASK desired_access,
56                                     POBJECT_ATTRIBUTES object_attributes,
57                                     EVENT_TYPE event_type,
58                                     BOOLEAN initial_state) {
59   NTSTATUS status = orig_CreateEvent(event_handle, desired_access,
60                                      object_attributes, event_type,
61                                      initial_state);
62   if (status != STATUS_ACCESS_DENIED || !object_attributes)
63     return status;
64 
65   // We don't trust that the IPC can work this early.
66   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
67     return status;
68 
69   do {
70     if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
71       break;
72 
73     void* memory = GetGlobalIPCMemory();
74     if (memory == NULL)
75       break;
76 
77     OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
78     // The RootDirectory points to BaseNamedObjects. We can ignore it.
79     object_attribs_copy.RootDirectory = NULL;
80 
81     wchar_t* name = NULL;
82     uint32 attributes = 0;
83     NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
84                                     NULL);
85     if (!NT_SUCCESS(ret) || name == NULL)
86       break;
87 
88     CrossCallReturn answer = {0};
89     answer.nt_status = status;
90     ResultCode code = ProxyCreateEvent(name, initial_state, event_type, memory,
91                                        &answer);
92     operator delete(name, NT_ALLOC);
93 
94     if (code != SBOX_ALL_OK) {
95       status = answer.nt_status;
96       break;
97     }
98     __try {
99       *event_handle = answer.handle;
100       status = STATUS_SUCCESS;
101     } __except(EXCEPTION_EXECUTE_HANDLER) {
102       break;
103     }
104   } while (false);
105 
106   return status;
107 }
108 
TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,PHANDLE event_handle,ACCESS_MASK desired_access,POBJECT_ATTRIBUTES object_attributes)109 NTSTATUS WINAPI TargetNtOpenEvent(NtOpenEventFunction orig_OpenEvent,
110                                   PHANDLE event_handle,
111                                   ACCESS_MASK desired_access,
112                                   POBJECT_ATTRIBUTES object_attributes) {
113   NTSTATUS status = orig_OpenEvent(event_handle, desired_access,
114                                    object_attributes);
115   if (status != STATUS_ACCESS_DENIED || !object_attributes)
116     return status;
117 
118   // We don't trust that the IPC can work this early.
119   if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
120     return status;
121 
122   do {
123     if (!ValidParameter(event_handle, sizeof(HANDLE), WRITE))
124       break;
125 
126     void* memory = GetGlobalIPCMemory();
127     if (memory == NULL)
128       break;
129 
130     OBJECT_ATTRIBUTES object_attribs_copy = *object_attributes;
131     // The RootDirectory points to BaseNamedObjects. We can ignore it.
132     object_attribs_copy.RootDirectory = NULL;
133 
134     wchar_t* name = NULL;
135     uint32 attributes = 0;
136     NTSTATUS ret = AllocAndCopyName(&object_attribs_copy, &name, &attributes,
137                                     NULL);
138     if (!NT_SUCCESS(ret) || name == NULL)
139       break;
140 
141     CrossCallReturn answer = {0};
142     answer.nt_status = status;
143     ResultCode code = ProxyOpenEvent(name, desired_access, memory, &answer);
144     operator delete(name, NT_ALLOC);
145 
146     if (code != SBOX_ALL_OK) {
147       status = answer.nt_status;
148       break;
149     }
150     __try {
151       *event_handle = answer.handle;
152       status = STATUS_SUCCESS;
153     } __except(EXCEPTION_EXECUTE_HANDLER) {
154       break;
155     }
156   } while (false);
157 
158   return status;
159 }
160 
161 }  // namespace sandbox
162