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/linux/services/broker_process.h" | 5 #include "sandbox/linux/services/broker_process.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <sys/syscall.h> | 10 #include <sys/syscall.h> |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 fast_check_in_client_(fast_check_in_client), | 124 fast_check_in_client_(fast_check_in_client), |
125 quiet_failures_for_tests_(quiet_failures_for_tests), | 125 quiet_failures_for_tests_(quiet_failures_for_tests), |
126 broker_pid_(-1), | 126 broker_pid_(-1), |
127 allowed_r_files_(allowed_r_files), | 127 allowed_r_files_(allowed_r_files), |
128 allowed_w_files_(allowed_w_files), | 128 allowed_w_files_(allowed_w_files), |
129 ipc_socketpair_(-1) { | 129 ipc_socketpair_(-1) { |
130 } | 130 } |
131 | 131 |
132 BrokerProcess::~BrokerProcess() { | 132 BrokerProcess::~BrokerProcess() { |
133 if (initialized_ && ipc_socketpair_ != -1) { | 133 if (initialized_ && ipc_socketpair_ != -1) { |
134 void (HANDLE_EINTR(close(ipc_socketpair_))); | 134 close(ipc_socketpair_); |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 bool BrokerProcess::Init(bool (*sandbox_callback)(void)) { | 138 bool BrokerProcess::Init(bool (*sandbox_callback)(void)) { |
139 CHECK(!initialized_); | 139 CHECK(!initialized_); |
140 int socket_pair[2]; | 140 int socket_pair[2]; |
141 // Use SOCK_SEQPACKET, because we need to preserve message boundaries | 141 // Use SOCK_SEQPACKET, because we need to preserve message boundaries |
142 // but we also want to be notified (recvmsg should return and not block) | 142 // but we also want to be notified (recvmsg should return and not block) |
143 // when the connection has been broken (one of the processes died). | 143 // when the connection has been broken (one of the processes died). |
144 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socket_pair)) { | 144 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socket_pair)) { |
145 LOG(ERROR) << "Failed to create socketpair"; | 145 LOG(ERROR) << "Failed to create socketpair"; |
146 return false; | 146 return false; |
147 } | 147 } |
148 | 148 |
149 int child_pid = fork(); | 149 int child_pid = fork(); |
150 if (child_pid == -1) { | 150 if (child_pid == -1) { |
151 ignore_result(HANDLE_EINTR(close(socket_pair[0]))); | 151 close(socket_pair[0]); |
152 ignore_result(HANDLE_EINTR(close(socket_pair[1]))); | 152 close(socket_pair[1]); |
153 return false; | 153 return false; |
154 } | 154 } |
155 if (child_pid) { | 155 if (child_pid) { |
156 // We are the parent and we have just forked our broker process. | 156 // We are the parent and we have just forked our broker process. |
157 ignore_result(HANDLE_EINTR(close(socket_pair[0]))); | 157 close(socket_pair[0]); |
158 // We should only be able to write to the IPC channel. We'll always send | 158 // We should only be able to write to the IPC channel. We'll always send |
159 // a new file descriptor to receive the reply on. | 159 // a new file descriptor to receive the reply on. |
160 shutdown(socket_pair[1], SHUT_RD); | 160 shutdown(socket_pair[1], SHUT_RD); |
161 ipc_socketpair_ = socket_pair[1]; | 161 ipc_socketpair_ = socket_pair[1]; |
162 is_child_ = false; | 162 is_child_ = false; |
163 broker_pid_ = child_pid; | 163 broker_pid_ = child_pid; |
164 initialized_ = true; | 164 initialized_ = true; |
165 return true; | 165 return true; |
166 } else { | 166 } else { |
167 // We are the broker. | 167 // We are the broker. |
168 ignore_result(HANDLE_EINTR(close(socket_pair[1]))); | 168 close(socket_pair[1]); |
169 // We should only be able to read from this IPC channel. We will send our | 169 // We should only be able to read from this IPC channel. We will send our |
170 // replies on a new file descriptor attached to the requests. | 170 // replies on a new file descriptor attached to the requests. |
171 shutdown(socket_pair[0], SHUT_WR); | 171 shutdown(socket_pair[0], SHUT_WR); |
172 ipc_socketpair_ = socket_pair[0]; | 172 ipc_socketpair_ = socket_pair[0]; |
173 is_child_ = true; | 173 is_child_ = true; |
174 // Enable the sandbox if provided. | 174 // Enable the sandbox if provided. |
175 if (sandbox_callback) { | 175 if (sandbox_callback) { |
176 CHECK(sandbox_callback()); | 176 CHECK(sandbox_callback()); |
177 } | 177 } |
178 initialized_ = true; | 178 initialized_ = true; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 case kCommandOpen: | 322 case kCommandOpen: |
323 // We reply on the file descriptor sent to us via the IPC channel. | 323 // We reply on the file descriptor sent to us via the IPC channel. |
324 r = HandleRemoteCommand(static_cast<IPCCommands>(command_type), | 324 r = HandleRemoteCommand(static_cast<IPCCommands>(command_type), |
325 temporary_ipc, pickle, iter); | 325 temporary_ipc, pickle, iter); |
326 break; | 326 break; |
327 default: | 327 default: |
328 NOTREACHED(); | 328 NOTREACHED(); |
329 r = false; | 329 r = false; |
330 break; | 330 break; |
331 } | 331 } |
332 int ret = HANDLE_EINTR(close(temporary_ipc)); | 332 int ret = IGNORE_EINTR(close(temporary_ipc)); |
333 DCHECK(!ret) << "Could not close temporary IPC channel"; | 333 DCHECK(!ret) << "Could not close temporary IPC channel"; |
334 return r; | 334 return r; |
335 } | 335 } |
336 | 336 |
337 LOG(ERROR) << "Error parsing IPC request"; | 337 LOG(ERROR) << "Error parsing IPC request"; |
338 return false; | 338 return false; |
339 } | 339 } |
340 | 340 |
341 // Handle a |command_type| request contained in |read_pickle| and send the reply | 341 // Handle a |command_type| request contained in |read_pickle| and send the reply |
342 // on |reply_ipc|. | 342 // on |reply_ipc|. |
(...skipping 24 matching lines...) Expand all Loading... |
367 break; | 367 break; |
368 } | 368 } |
369 | 369 |
370 CHECK_LE(write_pickle.size(), kMaxMessageLength); | 370 CHECK_LE(write_pickle.size(), kMaxMessageLength); |
371 ssize_t sent = UnixDomainSocket::SendMsg(reply_ipc, write_pickle.data(), | 371 ssize_t sent = UnixDomainSocket::SendMsg(reply_ipc, write_pickle.data(), |
372 write_pickle.size(), opened_files); | 372 write_pickle.size(), opened_files); |
373 | 373 |
374 // Close anything we have opened in this process. | 374 // Close anything we have opened in this process. |
375 for (std::vector<int>::iterator it = opened_files.begin(); | 375 for (std::vector<int>::iterator it = opened_files.begin(); |
376 it < opened_files.end(); ++it) { | 376 it < opened_files.end(); ++it) { |
377 int ret = HANDLE_EINTR(close(*it)); | 377 int ret = IGNORE_EINTR(close(*it)); |
378 DCHECK(!ret) << "Could not close file descriptor"; | 378 DCHECK(!ret) << "Could not close file descriptor"; |
379 } | 379 } |
380 | 380 |
381 if (sent <= 0) { | 381 if (sent <= 0) { |
382 LOG(ERROR) << "Could not send IPC reply"; | 382 LOG(ERROR) << "Could not send IPC reply"; |
383 return false; | 383 return false; |
384 } | 384 } |
385 return true; | 385 return true; |
386 } | 386 } |
387 | 387 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 GetFileNameInWhitelist(allowed_w_files_, requested_filename, | 509 GetFileNameInWhitelist(allowed_w_files_, requested_filename, |
510 file_to_open); | 510 file_to_open); |
511 return allowed_for_read_and_write; | 511 return allowed_for_read_and_write; |
512 } | 512 } |
513 default: | 513 default: |
514 return false; | 514 return false; |
515 } | 515 } |
516 } | 516 } |
517 | 517 |
518 } // namespace sandbox. | 518 } // namespace sandbox. |
OLD | NEW |