| 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 |