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/policy_target.h"
7 #include "sandbox/win/src/crosscall_client.h"
8 #include "sandbox/win/src/ipc_tags.h"
9 #include "sandbox/win/src/policy_engine_processor.h"
10 #include "sandbox/win/src/policy_low_level.h"
11 #include "sandbox/win/src/policy_params.h"
12 #include "sandbox/win/src/sandbox_factory.h"
13 #include "sandbox/win/src/sandbox_nt_util.h"
14 #include "sandbox/win/src/sharedmem_ipc_client.h"
15 #include "sandbox/win/src/target_services.h"
19 // Handle for our private heap.
22 // This is the list of all imported symbols from ntdll.dll.
23 SANDBOX_INTERCEPT NtExports g_nt
;
26 extern void* volatile g_shared_policy_memory
;
27 SANDBOX_INTERCEPT
size_t g_shared_policy_size
;
29 bool QueryBroker(int ipc_id
, CountedParameterSetBase
* params
) {
30 DCHECK_NT(static_cast<size_t>(ipc_id
) < kMaxServiceCount
);
31 DCHECK_NT(g_shared_policy_memory
);
32 DCHECK_NT(g_shared_policy_size
> 0);
34 if (static_cast<size_t>(ipc_id
) >= kMaxServiceCount
)
37 PolicyGlobal
* global_policy
=
38 reinterpret_cast<PolicyGlobal
*>(g_shared_policy_memory
);
40 if (!global_policy
->entry
[ipc_id
])
43 PolicyBuffer
* policy
= reinterpret_cast<PolicyBuffer
*>(
44 reinterpret_cast<char*>(g_shared_policy_memory
) +
45 reinterpret_cast<size_t>(global_policy
->entry
[ipc_id
]));
47 if ((reinterpret_cast<size_t>(global_policy
->entry
[ipc_id
]) >
48 global_policy
->data_size
) ||
49 (g_shared_policy_size
< global_policy
->data_size
)) {
54 for (int i
= 0; i
< params
->count
; i
++) {
55 if (!params
->parameters
[i
].IsValid()) {
61 PolicyProcessor
processor(policy
);
62 PolicyResult result
= processor
.Evaluate(kShortEval
, params
->parameters
,
64 DCHECK_NT(POLICY_ERROR
!= result
);
66 return POLICY_MATCH
== result
&& ASK_BROKER
== processor
.GetAction();
69 // -----------------------------------------------------------------------
71 // Hooks NtSetInformationThread to block RevertToSelf from being
72 // called before the actual call to LowerToken.
73 NTSTATUS WINAPI
TargetNtSetInformationThread(
74 NtSetInformationThreadFunction orig_SetInformationThread
, HANDLE thread
,
75 NT_THREAD_INFORMATION_CLASS thread_info_class
, PVOID thread_information
,
76 ULONG thread_information_bytes
) {
78 if (SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
80 if (ThreadImpersonationToken
!= thread_info_class
)
82 if (!thread_information
)
85 if (sizeof(token
) > thread_information_bytes
)
88 NTSTATUS ret
= CopyData(&token
, thread_information
, sizeof(token
));
89 if (!NT_SUCCESS(ret
) || NULL
!= token
)
92 // This is a revert to self.
93 return STATUS_SUCCESS
;
96 return orig_SetInformationThread(thread
, thread_info_class
,
98 thread_information_bytes
);
101 // Hooks NtOpenThreadToken to force the open_as_self parameter to be set to
102 // FALSE if we are still running with the impersonation token. open_as_self set
103 // to TRUE means that the token will be open using the process token instead of
104 // the impersonation token. This is bad because the process token does not have
105 // access to open the thread token.
106 NTSTATUS WINAPI
TargetNtOpenThreadToken(
107 NtOpenThreadTokenFunction orig_OpenThreadToken
, HANDLE thread
,
108 ACCESS_MASK desired_access
, BOOLEAN open_as_self
, PHANDLE token
) {
109 if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
110 open_as_self
= FALSE
;
112 return orig_OpenThreadToken(thread
, desired_access
, open_as_self
, token
);
115 // See comment for TargetNtOpenThreadToken
116 NTSTATUS WINAPI
TargetNtOpenThreadTokenEx(
117 NtOpenThreadTokenExFunction orig_OpenThreadTokenEx
, HANDLE thread
,
118 ACCESS_MASK desired_access
, BOOLEAN open_as_self
, ULONG handle_attributes
,
120 if (!SandboxFactory::GetTargetServices()->GetState()->RevertedToSelf())
121 open_as_self
= FALSE
;
123 return orig_OpenThreadTokenEx(thread
, desired_access
, open_as_self
,
124 handle_attributes
, token
);
127 } // namespace sandbox