OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sandbox/src/handle_policy.h" | 5 #include "sandbox/src/handle_policy.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/win/scoped_handle.h" | 9 #include "base/win/scoped_handle.h" |
10 #include "sandbox/src/broker_services.h" | 10 #include "sandbox/src/broker_services.h" |
11 #include "sandbox/src/ipc_tags.h" | 11 #include "sandbox/src/ipc_tags.h" |
12 #include "sandbox/src/policy_engine_opcodes.h" | 12 #include "sandbox/src/policy_engine_opcodes.h" |
13 #include "sandbox/src/policy_params.h" | 13 #include "sandbox/src/policy_params.h" |
14 #include "sandbox/src/sandbox_types.h" | 14 #include "sandbox/src/sandbox_types.h" |
15 #include "sandbox/src/sandbox_utils.h" | 15 #include "sandbox/src/sandbox_utils.h" |
16 | 16 |
17 namespace sandbox { | 17 namespace sandbox { |
18 | 18 |
19 bool HandlePolicy::GenerateRules(const wchar_t* type_name, | 19 bool HandlePolicy::GenerateRules(const wchar_t* type_name, |
20 TargetPolicy::Semantics semantics, | 20 TargetPolicy::Semantics semantics, |
21 LowLevelPolicy* policy) { | 21 LowLevelPolicy* policy) { |
22 // We don't support any other semantics for handles yet. | 22 PolicyRule duplicate_rule(ASK_BROKER); |
23 if (TargetPolicy::HANDLES_DUP_ANY != semantics) { | 23 |
24 return false; | 24 switch (semantics) { |
25 case TargetPolicy::HANDLES_DUP_ANY: { | |
26 if (!duplicate_rule.AddNumberMatch(IF_NOT, HandleTarget::TARGET, | |
27 ::GetCurrentProcessId(), EQUAL)) { | |
28 return false; | |
29 } | |
30 break; | |
31 } | |
32 | |
33 case TargetPolicy::HANDLES_DUP_BROKER: { | |
34 if (!duplicate_rule.AddNumberMatch(IF, HandleTarget::TARGET, | |
rvargas (doing something else)
2012/05/18 21:02:52
So we need two explicit rules in case we want to g
jschuh
2012/05/18 21:40:53
Yep. It's the same effort to implement either way,
| |
35 ::GetCurrentProcessId(), EQUAL)) { | |
36 return false; | |
37 } | |
38 break; | |
39 } | |
40 | |
41 default: | |
42 return false; | |
25 } | 43 } |
26 PolicyRule duplicate_rule(ASK_BROKER); | 44 if (!duplicate_rule.AddStringMatch(IF, HandleTarget::NAME, type_name, |
27 if (!duplicate_rule.AddStringMatch(IF, NameBased::NAME, type_name, | |
28 CASE_INSENSITIVE)) { | 45 CASE_INSENSITIVE)) { |
29 return false; | 46 return false; |
30 } | 47 } |
31 if (!policy->AddRule(IPC_DUPLICATEHANDLEPROXY_TAG, &duplicate_rule)) { | 48 if (!policy->AddRule(IPC_DUPLICATEHANDLEPROXY_TAG, &duplicate_rule)) { |
32 return false; | 49 return false; |
33 } | 50 } |
34 return true; | 51 return true; |
35 } | 52 } |
36 | 53 |
37 DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result, | 54 DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result, |
38 const ClientInfo& client_info, | 55 const ClientInfo& client_info, |
39 HANDLE source_handle, | 56 HANDLE source_handle, |
40 DWORD target_process_id, | 57 DWORD target_process_id, |
41 HANDLE* target_handle, | 58 HANDLE* target_handle, |
42 DWORD desired_access, | 59 DWORD desired_access, |
43 DWORD options) { | 60 DWORD options) { |
44 // The only action supported is ASK_BROKER which means duplicate the handle. | 61 // The only action supported is ASK_BROKER which means duplicate the handle. |
45 if (ASK_BROKER != eval_result) { | 62 if (ASK_BROKER != eval_result) { |
46 return ERROR_ACCESS_DENIED; | 63 return ERROR_ACCESS_DENIED; |
47 } | 64 } |
48 | 65 |
49 // Make sure the target is one of our sandboxed children. | 66 base::win::ScopedHandle remote_target_process; |
50 if (!BrokerServicesBase::GetInstance()->IsActiveTarget(target_process_id)) { | 67 if (target_process_id != ::GetCurrentProcessId()) { |
51 return ERROR_ACCESS_DENIED; | 68 // Sandboxed children are dynamic, so we check that manually. |
69 if (!BrokerServicesBase::GetInstance()->IsActiveTarget(target_process_id)) { | |
70 return ERROR_ACCESS_DENIED; | |
71 } | |
72 | |
73 remote_target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, | |
74 target_process_id)); | |
75 if (NULL == remote_target_process) | |
rvargas (doing something else)
2012/05/18 21:02:52
!IsValid()
jschuh
2012/05/18 21:40:53
Done.
| |
76 return ::GetLastError(); | |
52 } | 77 } |
53 | 78 |
54 base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE, | 79 // If the policy didn't block us and we have no valid target, then the broker |
55 FALSE, | 80 // (this process) is the valid target. |
56 target_process_id)); | 81 HANDLE target_process = remote_target_process.IsValid() ? |
rvargas (doing something else)
2012/05/18 21:02:52
interesting artifact of the limitations of ScopedH
jschuh
2012/05/18 21:40:53
Yeah, we can blame MS for making the process pseud
rvargas (doing something else)
2012/05/18 22:07:04
Except that a sane (auto-) implementation would no
| |
57 if (NULL == target_process) | 82 remote_target_process : ::GetCurrentProcess(); |
58 return ::GetLastError(); | |
59 | |
60 DWORD result = ERROR_SUCCESS; | 83 DWORD result = ERROR_SUCCESS; |
61 if (!::DuplicateHandle(client_info.process, source_handle, target_process, | 84 if (!::DuplicateHandle(client_info.process, source_handle, target_process, |
62 target_handle, desired_access, FALSE, | 85 target_handle, desired_access, FALSE, |
63 options)) { | 86 options)) { |
64 return ::GetLastError(); | 87 return ::GetLastError(); |
65 } | 88 } |
66 | 89 |
67 return ERROR_SUCCESS; | 90 return ERROR_SUCCESS; |
68 } | 91 } |
69 | 92 |
70 } // namespace sandbox | 93 } // namespace sandbox |
71 | 94 |
OLD | NEW |