Index: sandbox/linux/syscall_broker/broker_process.cc |
diff --git a/sandbox/linux/syscall_broker/broker_process.cc b/sandbox/linux/syscall_broker/broker_process.cc |
index 66b7660af071412d3047aa16f32905d6ea722fdd..ebd7d05c63e4b181c0402f458aee684bce51a0dd 100644 |
--- a/sandbox/linux/syscall_broker/broker_process.cc |
+++ b/sandbox/linux/syscall_broker/broker_process.cc |
@@ -6,7 +6,6 @@ |
#include <fcntl.h> |
#include <signal.h> |
-#include <sys/socket.h> |
#include <sys/stat.h> |
#include <sys/syscall.h> |
#include <sys/types.h> |
@@ -23,30 +22,33 @@ |
#include "base/posix/eintr_wrapper.h" |
#include "base/process/process_metrics.h" |
#include "build/build_config.h" |
+#include "sandbox/linux/syscall_broker/broker_channel.h" |
#include "sandbox/linux/syscall_broker/broker_client.h" |
#include "sandbox/linux/syscall_broker/broker_host.h" |
namespace sandbox { |
+namespace syscall_broker { |
+ |
BrokerProcess::BrokerProcess(int denied_errno, |
const std::vector<std::string>& allowed_r_files, |
const std::vector<std::string>& allowed_w_files, |
bool fast_check_in_client, |
bool quiet_failures_for_tests) |
: initialized_(false), |
- is_child_(false), |
fast_check_in_client_(fast_check_in_client), |
quiet_failures_for_tests_(quiet_failures_for_tests), |
broker_pid_(-1), |
- policy_(denied_errno, allowed_r_files, allowed_w_files), |
- ipc_socketpair_(-1) { |
+ policy_(denied_errno, allowed_r_files, allowed_w_files) { |
} |
BrokerProcess::~BrokerProcess() { |
- if (initialized_ && ipc_socketpair_ != -1) { |
- // Closing the socket should be enough to notify the child to die, |
- // unless it has been duplicated. |
- PCHECK(0 == IGNORE_EINTR(close(ipc_socketpair_))); |
+ if (initialized_) { |
+ if (broker_client_.get()) { |
+ // Closing the socket should be enough to notify the child to die, |
+ // unless it has been duplicated. |
+ CloseChannel(); |
+ } |
PCHECK(0 == kill(broker_pid_, SIGKILL)); |
siginfo_t process_info; |
// Reap the child. |
@@ -58,59 +60,50 @@ BrokerProcess::~BrokerProcess() { |
bool BrokerProcess::Init( |
const base::Callback<bool(void)>& broker_process_init_callback) { |
CHECK(!initialized_); |
- int socket_pair[2]; |
- // Use SOCK_SEQPACKET, because we need to preserve message boundaries |
- // but we also want to be notified (recvmsg should return and not block) |
- // when the connection has been broken (one of the processes died). |
- if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, socket_pair)) { |
- LOG(ERROR) << "Failed to create socketpair"; |
- return false; |
- } |
+ BrokerChannel::EndPoint ipc_reader; |
+ BrokerChannel::EndPoint ipc_writer; |
+ BrokerChannel::CreatePair(&ipc_reader, &ipc_writer); |
#if !defined(THREAD_SANITIZER) |
DCHECK_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle())); |
#endif |
int child_pid = fork(); |
if (child_pid == -1) { |
- close(socket_pair[0]); |
- close(socket_pair[1]); |
return false; |
} |
if (child_pid) { |
// We are the parent and we have just forked our broker process. |
- close(socket_pair[0]); |
- // We should only be able to write to the IPC channel. We'll always send |
- // a new file descriptor to receive the reply on. |
- shutdown(socket_pair[1], SHUT_RD); |
- ipc_socketpair_ = socket_pair[1]; |
- is_child_ = false; |
+ ipc_reader.reset(); |
broker_pid_ = child_pid; |
- broker_client_.reset( |
- new syscall_broker::BrokerClient(policy_, |
- ipc_socketpair_, |
- fast_check_in_client_, |
- quiet_failures_for_tests_)); |
+ broker_client_.reset(new BrokerClient(policy_, ipc_writer.Pass(), |
+ fast_check_in_client_, |
+ quiet_failures_for_tests_)); |
initialized_ = true; |
return true; |
} else { |
- // We are the broker. |
- close(socket_pair[1]); |
- // We should only be able to read from this IPC channel. We will send our |
- // replies on a new file descriptor attached to the requests. |
- shutdown(socket_pair[0], SHUT_WR); |
- ipc_socketpair_ = socket_pair[0]; |
- is_child_ = true; |
+ // We are the broker process. Make sure to close the writer's end so that |
+ // we get notified if the client disappears. |
+ ipc_writer.reset(); |
CHECK(broker_process_init_callback.Run()); |
- syscall_broker::BrokerHost broker_host(policy_, ipc_socketpair_); |
- initialized_ = true; |
+ BrokerHost broker_host(policy_, ipc_reader.Pass()); |
for (;;) { |
- broker_host.HandleRequest(); |
+ switch (broker_host.HandleRequest()) { |
+ case BrokerHost::RequestStatus::LOST_CLIENT: |
+ _exit(1); |
+ case BrokerHost::RequestStatus::SUCCESS: |
+ case BrokerHost::RequestStatus::FAILURE: |
+ continue; |
+ } |
} |
_exit(1); |
} |
NOTREACHED(); |
} |
+void BrokerProcess::CloseChannel() { |
+ broker_client_.reset(); |
+} |
+ |
int BrokerProcess::Access(const char* pathname, int mode) const { |
RAW_CHECK(initialized_); |
return broker_client_->Access(pathname, mode); |
@@ -121,4 +114,6 @@ int BrokerProcess::Open(const char* pathname, int flags) const { |
return broker_client_->Open(pathname, flags); |
} |
+} // namespace syscall_broker |
+ |
} // namespace sandbox. |