Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: sandbox/mac/launchd_interception_server.cc

Issue 306123012: Do not double-unref send rights when using POLICY_SUBSTITUE_PORT. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Adjust comment Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/mac/launchd_interception_server.h ('k') | sandbox/mac/os_compatibility.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <bsm/libbsm.h> 7 #include <bsm/libbsm.h>
8 #include <servers/bootstrap.h> 8 #include <servers/bootstrap.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 } 69 }
70 reply_buffer_.reset(buffer, kBufferSize); 70 reply_buffer_.reset(buffer, kBufferSize);
71 71
72 // Allocate the dummy sandbox port. 72 // Allocate the dummy sandbox port.
73 if ((kr = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &port)) != 73 if ((kr = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &port)) !=
74 KERN_SUCCESS) { 74 KERN_SUCCESS) {
75 MACH_LOG(ERROR, kr) << "Failed to allocate dummy sandbox port."; 75 MACH_LOG(ERROR, kr) << "Failed to allocate dummy sandbox port.";
76 return false; 76 return false;
77 } 77 }
78 sandbox_port_.reset(port); 78 sandbox_port_.reset(port);
79 if ((kr = mach_port_insert_right(task, sandbox_port_, sandbox_port_,
80 MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS)) {
81 MACH_LOG(ERROR, kr) << "Failed to allocate dummy sandbox port send right.";
82 return false;
83 }
84 sandbox_send_port_.reset(sandbox_port_);
79 85
80 // Set up the dispatch queue to service the bootstrap port. 86 // Set up the dispatch queue to service the bootstrap port.
81 // TODO(rsesek): Specify DISPATCH_QUEUE_SERIAL, in the 10.7 SDK. NULL means 87 // TODO(rsesek): Specify DISPATCH_QUEUE_SERIAL, in the 10.7 SDK. NULL means
82 // the same thing but is not symbolically clear. 88 // the same thing but is not symbolically clear.
83 server_queue_ = dispatch_queue_create( 89 server_queue_ = dispatch_queue_create(
84 "org.chromium.sandbox.LaunchdInterceptionServer", NULL); 90 "org.chromium.sandbox.LaunchdInterceptionServer", NULL);
85 server_source_ = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, 91 server_source_ = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
86 server_port_.get(), 0, server_queue_); 92 server_port_.get(), 0, server_queue_);
87 dispatch_source_set_event_handler(server_source_, ^{ ReceiveMessage(); }); 93 dispatch_source_set_event_handler(server_source_, ^{ ReceiveMessage(); });
88 dispatch_resume(server_source_); 94 dispatch_resume(server_source_);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 // or the one specified in the policy. 215 // or the one specified in the policy.
210 VLOG(1) << "Intercepting look_up2 with a sandboxed service port: " 216 VLOG(1) << "Intercepting look_up2 with a sandboxed service port: "
211 << request_service_name; 217 << request_service_name;
212 218
213 mach_port_t result_port; 219 mach_port_t result_port;
214 if (rule.result == POLICY_DENY_DUMMY_PORT) 220 if (rule.result == POLICY_DENY_DUMMY_PORT)
215 result_port = sandbox_port_.get(); 221 result_port = sandbox_port_.get();
216 else 222 else
217 result_port = rule.substitute_port; 223 result_port = rule.substitute_port;
218 224
219 // Grant an additional send right on the result_port so that it can be
220 // sent to the sandboxed child process.
221 kern_return_t kr = mach_port_insert_right(mach_task_self(),
222 result_port, result_port, MACH_MSG_TYPE_MAKE_SEND);
223 if (kr != KERN_SUCCESS) {
224 MACH_LOG(ERROR, kr) << "Unable to insert right on result_port.";
225 }
226
227 compat_shim_.look_up2_fill_reply(reply, result_port); 225 compat_shim_.look_up2_fill_reply(reply, result_port);
228 SendReply(reply); 226 // If the message was sent successfully, clear the result_port out of the
227 // message so that it is not destroyed at the end of ReceiveMessage. The
228 // above-inserted right has been moved out of the process, and destroying
229 // the message will unref yet another right.
230 if (SendReply(reply))
231 compat_shim_.look_up2_fill_reply(reply, MACH_PORT_NULL);
229 } else { 232 } else {
230 NOTREACHED(); 233 NOTREACHED();
231 } 234 }
232 } 235 }
233 236
234 void LaunchdInterceptionServer::HandleSwapInteger(mach_msg_header_t* request, 237 void LaunchdInterceptionServer::HandleSwapInteger(mach_msg_header_t* request,
235 mach_msg_header_t* reply, 238 mach_msg_header_t* reply,
236 pid_t sender_pid) { 239 pid_t sender_pid) {
237 // Only allow getting information out of launchd. Do not allow setting 240 // Only allow getting information out of launchd. Do not allow setting
238 // values. Two commonly observed values that are retrieved are 241 // values. Two commonly observed values that are retrieved are
239 // VPROC_GSK_MGR_PID and VPROC_GSK_TRANSACTIONS_ENABLED. 242 // VPROC_GSK_MGR_PID and VPROC_GSK_TRANSACTIONS_ENABLED.
240 if (compat_shim_.swap_integer_is_get_only(request)) { 243 if (compat_shim_.swap_integer_is_get_only(request)) {
241 VLOG(2) << "Forwarding vproc swap_integer message."; 244 VLOG(2) << "Forwarding vproc swap_integer message.";
242 ForwardMessage(request, reply); 245 ForwardMessage(request, reply);
243 } else { 246 } else {
244 VLOG(2) << "Rejecting non-read-only swap_integer message."; 247 VLOG(2) << "Rejecting non-read-only swap_integer message.";
245 RejectMessage(request, reply, BOOTSTRAP_NOT_PRIVILEGED); 248 RejectMessage(request, reply, BOOTSTRAP_NOT_PRIVILEGED);
246 } 249 }
247 } 250 }
248 251
249 void LaunchdInterceptionServer::SendReply(mach_msg_header_t* reply) { 252 bool LaunchdInterceptionServer::SendReply(mach_msg_header_t* reply) {
250 kern_return_t kr = mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, 253 kern_return_t kr = mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0,
251 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 254 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
252 if (kr != KERN_SUCCESS) { 255 MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr)
253 MACH_LOG(ERROR, kr) << "Unable to send intercepted reply message."; 256 << "Unable to send intercepted reply message.";
254 } 257 return kr == KERN_SUCCESS;
255 } 258 }
256 259
257 void LaunchdInterceptionServer::ForwardMessage(mach_msg_header_t* request, 260 void LaunchdInterceptionServer::ForwardMessage(mach_msg_header_t* request,
258 mach_msg_header_t* reply) { 261 mach_msg_header_t* reply) {
259 request->msgh_local_port = request->msgh_remote_port; 262 request->msgh_local_port = request->msgh_remote_port;
260 request->msgh_remote_port = sandbox_->real_bootstrap_port(); 263 request->msgh_remote_port = sandbox_->real_bootstrap_port();
261 // Preserve the msgh_bits that do not deal with the local and remote ports. 264 // Preserve the msgh_bits that do not deal with the local and remote ports.
262 request->msgh_bits = (request->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) | 265 request->msgh_bits = (request->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) |
263 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MOVE_SEND_ONCE); 266 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MOVE_SEND_ONCE);
264 kern_return_t kr = mach_msg_send(request); 267 kern_return_t kr = mach_msg_send(request);
(...skipping 10 matching lines...) Expand all
275 mig_reply_error_t* error_reply = reinterpret_cast<mig_reply_error_t*>(reply); 278 mig_reply_error_t* error_reply = reinterpret_cast<mig_reply_error_t*>(reply);
276 error_reply->Head.msgh_size = sizeof(mig_reply_error_t); 279 error_reply->Head.msgh_size = sizeof(mig_reply_error_t);
277 error_reply->Head.msgh_bits = 280 error_reply->Head.msgh_bits =
278 MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE); 281 MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE);
279 error_reply->NDR = NDR_record; 282 error_reply->NDR = NDR_record;
280 error_reply->RetCode = error_code; 283 error_reply->RetCode = error_code;
281 SendReply(&error_reply->Head); 284 SendReply(&error_reply->Head);
282 } 285 }
283 286
284 } // namespace sandbox 287 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/mac/launchd_interception_server.h ('k') | sandbox/mac/os_compatibility.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698