OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/mac/launchd_interception_server.h" | 5 #include "sandbox/mac/launchd_interception_server.h" |
6 | 6 |
7 #include <servers/bootstrap.h> | 7 #include <servers/bootstrap.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac/mach_logging.h" | 10 #include "base/mac/mach_logging.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 | 48 |
49 message_server_.reset(new MachMessageServer(this, kBufferSize)); | 49 message_server_.reset(new MachMessageServer(this, kBufferSize)); |
50 return message_server_->Initialize(); | 50 return message_server_->Initialize(); |
51 } | 51 } |
52 | 52 |
53 void LaunchdInterceptionServer::DemuxMessage(mach_msg_header_t* request, | 53 void LaunchdInterceptionServer::DemuxMessage(mach_msg_header_t* request, |
54 mach_msg_header_t* reply) { | 54 mach_msg_header_t* reply) { |
55 VLOG(3) << "Incoming message #" << request->msgh_id; | 55 VLOG(3) << "Incoming message #" << request->msgh_id; |
56 | 56 |
57 pid_t sender_pid = message_server_->GetMessageSenderPID(request); | 57 pid_t sender_pid = message_server_->GetMessageSenderPID(request); |
58 if (sandbox_->PolicyForProcess(sender_pid) == NULL) { | 58 const BootstrapSandboxPolicy* policy = |
| 59 sandbox_->PolicyForProcess(sender_pid); |
| 60 if (policy == NULL) { |
59 // No sandbox policy is in place for the sender of this message, which | 61 // No sandbox policy is in place for the sender of this message, which |
60 // means it is from the sandbox host process or an unsandboxed child. | 62 // means it is from the sandbox host process or an unsandboxed child. |
61 VLOG(3) << "Message from pid " << sender_pid << " forwarded to launchd"; | 63 VLOG(3) << "Message from pid " << sender_pid << " forwarded to launchd"; |
62 ForwardMessage(request); | 64 ForwardMessage(request); |
63 return; | 65 return; |
64 } | 66 } |
65 | 67 |
66 if (request->msgh_id == compat_shim_.msg_id_look_up2) { | 68 if (request->msgh_id == compat_shim_.msg_id_look_up2) { |
67 // Filter messages sent via bootstrap_look_up to enforce the sandbox policy | 69 // Filter messages sent via bootstrap_look_up to enforce the sandbox policy |
68 // over the bootstrap namespace. | 70 // over the bootstrap namespace. |
69 HandleLookUp(request, reply, sender_pid); | 71 HandleLookUp(request, reply, policy); |
70 } else if (request->msgh_id == compat_shim_.msg_id_swap_integer) { | 72 } else if (request->msgh_id == compat_shim_.msg_id_swap_integer) { |
71 // Ensure that any vproc_swap_integer requests are safe. | 73 // Ensure that any vproc_swap_integer requests are safe. |
72 HandleSwapInteger(request, reply, sender_pid); | 74 HandleSwapInteger(request, reply); |
73 } else { | 75 } else { |
74 // All other messages are not permitted. | 76 // All other messages are not permitted. |
75 VLOG(1) << "Rejecting unhandled message #" << request->msgh_id; | 77 VLOG(1) << "Rejecting unhandled message #" << request->msgh_id; |
76 message_server_->RejectMessage(reply, MIG_REMOTE_ERROR); | 78 message_server_->RejectMessage(reply, MIG_REMOTE_ERROR); |
77 } | 79 } |
78 } | 80 } |
79 | 81 |
80 void LaunchdInterceptionServer::HandleLookUp(mach_msg_header_t* request, | 82 void LaunchdInterceptionServer::HandleLookUp( |
81 mach_msg_header_t* reply, | 83 mach_msg_header_t* request, |
82 pid_t sender_pid) { | 84 mach_msg_header_t* reply, |
| 85 const BootstrapSandboxPolicy* policy) { |
83 const std::string request_service_name( | 86 const std::string request_service_name( |
84 compat_shim_.look_up2_get_request_name(request)); | 87 compat_shim_.look_up2_get_request_name(request)); |
85 VLOG(2) << "Incoming look_up2 request for " << request_service_name; | 88 VLOG(2) << "Incoming look_up2 request for " << request_service_name; |
86 | 89 |
87 // Find the Rule for this service. If one is not found, use | 90 // Find the Rule for this service. If a named rule is not found, use the |
88 // a safe default, POLICY_DENY_ERROR. | 91 // default specified by the policy. |
89 const BootstrapSandboxPolicy* policy = sandbox_->PolicyForProcess(sender_pid); | |
90 const BootstrapSandboxPolicy::NamedRules::const_iterator it = | 92 const BootstrapSandboxPolicy::NamedRules::const_iterator it = |
91 policy->rules.find(request_service_name); | 93 policy->rules.find(request_service_name); |
92 Rule rule(policy->default_rule); | 94 Rule rule(policy->default_rule); |
93 if (it != policy->rules.end()) | 95 if (it != policy->rules.end()) |
94 rule = it->second; | 96 rule = it->second; |
95 | 97 |
96 if (rule.result == POLICY_ALLOW) { | 98 if (rule.result == POLICY_ALLOW) { |
97 // This service is explicitly allowed, so this message will not be | 99 // This service is explicitly allowed, so this message will not be |
98 // intercepted by the sandbox. | 100 // intercepted by the sandbox. |
99 VLOG(1) << "Permitting and forwarding look_up2: " << request_service_name; | 101 VLOG(1) << "Permitting and forwarding look_up2: " << request_service_name; |
(...skipping 24 matching lines...) Expand all Loading... |
124 // above-inserted right has been moved out of the process, and destroying | 126 // above-inserted right has been moved out of the process, and destroying |
125 // the message will unref yet another right. | 127 // the message will unref yet another right. |
126 if (message_server_->SendReply(reply)) | 128 if (message_server_->SendReply(reply)) |
127 compat_shim_.look_up2_fill_reply(reply, MACH_PORT_NULL); | 129 compat_shim_.look_up2_fill_reply(reply, MACH_PORT_NULL); |
128 } else { | 130 } else { |
129 NOTREACHED(); | 131 NOTREACHED(); |
130 } | 132 } |
131 } | 133 } |
132 | 134 |
133 void LaunchdInterceptionServer::HandleSwapInteger(mach_msg_header_t* request, | 135 void LaunchdInterceptionServer::HandleSwapInteger(mach_msg_header_t* request, |
134 mach_msg_header_t* reply, | 136 mach_msg_header_t* reply) { |
135 pid_t sender_pid) { | |
136 // Only allow getting information out of launchd. Do not allow setting | 137 // Only allow getting information out of launchd. Do not allow setting |
137 // values. Two commonly observed values that are retrieved are | 138 // values. Two commonly observed values that are retrieved are |
138 // VPROC_GSK_MGR_PID and VPROC_GSK_TRANSACTIONS_ENABLED. | 139 // VPROC_GSK_MGR_PID and VPROC_GSK_TRANSACTIONS_ENABLED. |
139 if (compat_shim_.swap_integer_is_get_only(request)) { | 140 if (compat_shim_.swap_integer_is_get_only(request)) { |
140 VLOG(2) << "Forwarding vproc swap_integer message."; | 141 VLOG(2) << "Forwarding vproc swap_integer message."; |
141 ForwardMessage(request); | 142 ForwardMessage(request); |
142 } else { | 143 } else { |
143 VLOG(2) << "Rejecting non-read-only swap_integer message."; | 144 VLOG(2) << "Rejecting non-read-only swap_integer message."; |
144 message_server_->RejectMessage(reply, BOOTSTRAP_NOT_PRIVILEGED); | 145 message_server_->RejectMessage(reply, BOOTSTRAP_NOT_PRIVILEGED); |
145 } | 146 } |
146 } | 147 } |
147 void LaunchdInterceptionServer::ForwardMessage(mach_msg_header_t* request) { | 148 void LaunchdInterceptionServer::ForwardMessage(mach_msg_header_t* request) { |
148 message_server_->ForwardMessage(request, sandbox_->real_bootstrap_port()); | 149 message_server_->ForwardMessage(request, sandbox_->real_bootstrap_port()); |
149 } | 150 } |
150 | 151 |
151 } // namespace sandbox | 152 } // namespace sandbox |
OLD | NEW |