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

Side by Side Diff: util/mach/child_port_handshake.cc

Issue 1383283003: Add and use scoped-right-returning wrappers for Mach bootstrap routines (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Self-review Created 5 years, 2 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
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "util/mach/child_port_handshake.h" 15 #include "util/mach/child_port_handshake.h"
16 16
17 #include <errno.h> 17 #include <errno.h>
18 #include <pthread.h> 18 #include <pthread.h>
19 #include <servers/bootstrap.h>
20 #include <sys/event.h> 19 #include <sys/event.h>
21 #include <sys/socket.h> 20 #include <sys/socket.h>
22 #include <sys/time.h> 21 #include <sys/time.h>
23 #include <sys/types.h> 22 #include <sys/types.h>
24 #include <unistd.h> 23 #include <unistd.h>
25 24
26 #include <algorithm> 25 #include <algorithm>
27 26
28 #include "base/logging.h" 27 #include "base/logging.h"
29 #include "base/mac/mach_logging.h" 28 #include "base/mac/mach_logging.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 // to prevent outsiders from grabbing the name first, which would cause 94 // to prevent outsiders from grabbing the name first, which would cause
96 // bootstrap_check_in() to fail. 95 // bootstrap_check_in() to fail.
97 uint64_t thread_id; 96 uint64_t thread_id;
98 errno = pthread_threadid_np(pthread_self(), &thread_id); 97 errno = pthread_threadid_np(pthread_self(), &thread_id);
99 PCHECK(errno == 0) << "pthread_threadid_np"; 98 PCHECK(errno == 0) << "pthread_threadid_np";
100 std::string service_name = base::StringPrintf( 99 std::string service_name = base::StringPrintf(
101 "com.googlecode.crashpad.child_port_handshake.%d.%llu.%016llx", 100 "com.googlecode.crashpad.child_port_handshake.%d.%llu.%016llx",
102 getpid(), 101 getpid(),
103 thread_id, 102 thread_id,
104 base::RandUint64()); 103 base::RandUint64());
105 DCHECK_LT(service_name.size(), implicit_cast<size_t>(BOOTSTRAP_MAX_NAME_LEN));
106 104
107 // Check the new service in with the bootstrap server, obtaining a receive 105 // Check the new service in with the bootstrap server, obtaining a receive
108 // right for it. 106 // right for it.
109 mach_port_t server_port; 107 base::mac::ScopedMachReceiveRight server_port(BootstrapCheckIn(service_name));
110 kern_return_t kr = 108 CHECK_NE(server_port, kMachPortNull);
111 bootstrap_check_in(bootstrap_port, service_name.c_str(), &server_port);
112 BOOTSTRAP_CHECK(kr == BOOTSTRAP_SUCCESS, kr) << "bootstrap_check_in";
113 base::mac::ScopedMachReceiveRight server_port_owner(server_port);
114 109
115 // Share the service name with the client via the pipe. 110 // Share the service name with the client via the pipe.
116 uint32_t service_name_length = service_name.size(); 111 uint32_t service_name_length = service_name.size();
117 if (!LoggingWriteFile( 112 if (!LoggingWriteFile(
118 pipe_write, &service_name_length, sizeof(service_name_length))) { 113 pipe_write, &service_name_length, sizeof(service_name_length))) {
119 LOG(WARNING) << "no client check-in"; 114 LOG(WARNING) << "no client check-in";
120 return MACH_PORT_NULL; 115 return MACH_PORT_NULL;
121 } 116 }
122 117
123 if (!LoggingWriteFile( 118 if (!LoggingWriteFile(
124 pipe_write, service_name.c_str(), service_name_length)) { 119 pipe_write, service_name.c_str(), service_name_length)) {
125 LOG(WARNING) << "no client check-in"; 120 LOG(WARNING) << "no client check-in";
126 return MACH_PORT_NULL; 121 return MACH_PORT_NULL;
127 } 122 }
128 123
129 // A kqueue cannot monitor a raw Mach receive right with EVFILT_MACHPORT. It 124 // A kqueue cannot monitor a raw Mach receive right with EVFILT_MACHPORT. It
130 // requires a port set. Create a new port set and add the receive right to it. 125 // requires a port set. Create a new port set and add the receive right to it.
131 base::mac::ScopedMachPortSet server_port_set( 126 base::mac::ScopedMachPortSet server_port_set(
132 NewMachPort(MACH_PORT_RIGHT_PORT_SET)); 127 NewMachPort(MACH_PORT_RIGHT_PORT_SET));
133 CHECK_NE(server_port_set, kMachPortNull); 128 CHECK_NE(server_port_set, kMachPortNull);
134 129
135 kr = mach_port_insert_member(mach_task_self(), server_port, server_port_set); 130 kern_return_t kr =
131 mach_port_insert_member(mach_task_self(), server_port, server_port_set);
136 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member"; 132 MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member";
137 133
138 // Set up a kqueue to monitor both the server’s receive right and the write 134 // Set up a kqueue to monitor both the server’s receive right and the write
139 // side of the pipe. Messages from the client will be received via the receive 135 // side of the pipe. Messages from the client will be received via the receive
140 // right, and the pipe will show EOF if the client closes its read side 136 // right, and the pipe will show EOF if the client closes its read side
141 // prematurely. 137 // prematurely.
142 base::ScopedFD kq(kqueue()); 138 base::ScopedFD kq(kqueue());
143 PCHECK(kq != -1) << "kqueue"; 139 PCHECK(kq != -1) << "kqueue";
144 140
145 struct kevent changelist[2]; 141 struct kevent changelist[2];
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // static 306 // static
311 void ChildPortHandshake::RunClientInternal_ReadPipe(int pipe_read, 307 void ChildPortHandshake::RunClientInternal_ReadPipe(int pipe_read,
312 child_port_token_t* token, 308 child_port_token_t* token,
313 std::string* service_name) { 309 std::string* service_name) {
314 // Read the token from the pipe. 310 // Read the token from the pipe.
315 CheckedReadFile(pipe_read, token, sizeof(*token)); 311 CheckedReadFile(pipe_read, token, sizeof(*token));
316 312
317 // Read the service name from the pipe. 313 // Read the service name from the pipe.
318 uint32_t service_name_length; 314 uint32_t service_name_length;
319 CheckedReadFile(pipe_read, &service_name_length, sizeof(service_name_length)); 315 CheckedReadFile(pipe_read, &service_name_length, sizeof(service_name_length));
320 DCHECK_LT(service_name_length,
321 implicit_cast<uint32_t>(BOOTSTRAP_MAX_NAME_LEN));
322 316
323 service_name->resize(service_name_length); 317 service_name->resize(service_name_length);
324 if (!service_name->empty()) { 318 if (!service_name->empty()) {
325 CheckedReadFile(pipe_read, &(*service_name)[0], service_name_length); 319 CheckedReadFile(pipe_read, &(*service_name)[0], service_name_length);
326 } 320 }
327 } 321 }
328 322
329 // static 323 // static
330 void ChildPortHandshake::RunClientInternal_SendCheckIn( 324 void ChildPortHandshake::RunClientInternal_SendCheckIn(
331 const std::string& service_name, 325 const std::string& service_name,
332 child_port_token_t token, 326 child_port_token_t token,
333 mach_port_t port, 327 mach_port_t port,
334 mach_msg_type_name_t right_type) { 328 mach_msg_type_name_t right_type) {
335 // Get a send right to the server by looking up the service with the bootstrap 329 // Get a send right to the server by looking up the service with the bootstrap
336 // server by name. 330 // server by name.
337 mach_port_t server_port; 331 base::mac::ScopedMachSendRight server_port(BootstrapLookUp(service_name));
338 kern_return_t kr = 332 CHECK_NE(server_port, kMachPortNull);
339 bootstrap_look_up(bootstrap_port, service_name.c_str(), &server_port);
340 BOOTSTRAP_CHECK(kr == BOOTSTRAP_SUCCESS, kr) << "bootstrap_look_up";
341 base::mac::ScopedMachSendRight server_port_owner(server_port);
342 333
343 // Check in with the server. 334 // Check in with the server.
344 kr = child_port_check_in(server_port, token, port, right_type); 335 kern_return_t kr = child_port_check_in(server_port, token, port, right_type);
345 MACH_CHECK(kr == KERN_SUCCESS, kr) << "child_port_check_in"; 336 MACH_CHECK(kr == KERN_SUCCESS, kr) << "child_port_check_in";
346 } 337 }
347 338
348 } // namespace crashpad 339 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698