diff options
Diffstat (limited to 'sandbox/linux/syscall_broker/broker_host.cc')
-rw-r--r-- | sandbox/linux/syscall_broker/broker_host.cc | 232 |
1 files changed, 0 insertions, 232 deletions
diff --git a/sandbox/linux/syscall_broker/broker_host.cc b/sandbox/linux/syscall_broker/broker_host.cc deleted file mode 100644 index dd61dac621..0000000000 --- a/sandbox/linux/syscall_broker/broker_host.cc +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "sandbox/linux/syscall_broker/broker_host.h" - -#include <errno.h> -#include <fcntl.h> -#include <stddef.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#include <string> -#include <utility> -#include <vector> - -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "base/pickle.h" -#include "base/posix/eintr_wrapper.h" -#include "base/posix/unix_domain_socket_linux.h" -#include "base/third_party/valgrind/valgrind.h" -#include "sandbox/linux/syscall_broker/broker_common.h" -#include "sandbox/linux/syscall_broker/broker_policy.h" -#include "sandbox/linux/system_headers/linux_syscalls.h" - -namespace sandbox { - -namespace syscall_broker { - -namespace { - -bool IsRunningOnValgrind() { - return RUNNING_ON_VALGRIND; -} - -// A little open(2) wrapper to handle some oddities for us. In the general case -// make a direct system call since we want to keep in control of the broker -// process' system calls profile to be able to loosely sandbox it. -int sys_open(const char* pathname, int flags) { - // Hardcode mode to rw------- when creating files. - int mode; - if (flags & O_CREAT) { - mode = 0600; - } else { - mode = 0; - } - if (IsRunningOnValgrind()) { - // Valgrind does not support AT_FDCWD, just use libc's open() in this case. - return open(pathname, flags, mode); - } else { - return syscall(__NR_openat, AT_FDCWD, pathname, flags, mode); - } -} - -// Open |requested_filename| with |flags| if allowed by our policy. -// Write the syscall return value (-errno) to |write_pickle| and append -// a file descriptor to |opened_files| if relevant. -void OpenFileForIPC(const BrokerPolicy& policy, - const std::string& requested_filename, - int flags, - base::Pickle* write_pickle, - std::vector<int>* opened_files) { - DCHECK(write_pickle); - DCHECK(opened_files); - const char* file_to_open = NULL; - bool unlink_after_open = false; - const bool safe_to_open_file = policy.GetFileNameIfAllowedToOpen( - requested_filename.c_str(), flags, &file_to_open, &unlink_after_open); - - if (safe_to_open_file) { - CHECK(file_to_open); - int opened_fd = sys_open(file_to_open, flags); - if (opened_fd < 0) { - write_pickle->WriteInt(-errno); - } else { - // Success. - if (unlink_after_open) { - unlink(file_to_open); - } - opened_files->push_back(opened_fd); - write_pickle->WriteInt(0); - } - } else { - write_pickle->WriteInt(-policy.denied_errno()); - } -} - -// Perform access(2) on |requested_filename| with mode |mode| if allowed by our -// policy. Write the syscall return value (-errno) to |write_pickle|. -void AccessFileForIPC(const BrokerPolicy& policy, - const std::string& requested_filename, - int mode, - base::Pickle* write_pickle) { - DCHECK(write_pickle); - const char* file_to_access = NULL; - const bool safe_to_access_file = policy.GetFileNameIfAllowedToAccess( - requested_filename.c_str(), mode, &file_to_access); - - if (safe_to_access_file) { - CHECK(file_to_access); - int access_ret = access(file_to_access, mode); - int access_errno = errno; - if (!access_ret) - write_pickle->WriteInt(0); - else - write_pickle->WriteInt(-access_errno); - } else { - write_pickle->WriteInt(-policy.denied_errno()); - } -} - -// Handle a |command_type| request contained in |iter| and send the reply -// on |reply_ipc|. -// Currently COMMAND_OPEN and COMMAND_ACCESS are supported. -bool HandleRemoteCommand(const BrokerPolicy& policy, - IPCCommand command_type, - int reply_ipc, - base::PickleIterator iter) { - // Currently all commands have two arguments: filename and flags. - std::string requested_filename; - int flags = 0; - if (!iter.ReadString(&requested_filename) || !iter.ReadInt(&flags)) - return false; - - base::Pickle write_pickle; - std::vector<int> opened_files; - - switch (command_type) { - case COMMAND_ACCESS: - AccessFileForIPC(policy, requested_filename, flags, &write_pickle); - break; - case COMMAND_OPEN: - OpenFileForIPC( - policy, requested_filename, flags, &write_pickle, &opened_files); - break; - default: - LOG(ERROR) << "Invalid IPC command"; - break; - } - - CHECK_LE(write_pickle.size(), kMaxMessageLength); - ssize_t sent = base::UnixDomainSocket::SendMsg( - reply_ipc, write_pickle.data(), write_pickle.size(), opened_files); - - // Close anything we have opened in this process. - for (std::vector<int>::iterator it = opened_files.begin(); - it != opened_files.end(); - ++it) { - int ret = IGNORE_EINTR(close(*it)); - DCHECK(!ret) << "Could not close file descriptor"; - } - - if (sent <= 0) { - LOG(ERROR) << "Could not send IPC reply"; - return false; - } - return true; -} - -} // namespace - -BrokerHost::BrokerHost(const BrokerPolicy& broker_policy, - BrokerChannel::EndPoint ipc_channel) - : broker_policy_(broker_policy), ipc_channel_(std::move(ipc_channel)) {} - -BrokerHost::~BrokerHost() { -} - -// Handle a request on the IPC channel ipc_channel_. -// A request should have a file descriptor attached on which we will reply and -// that we will then close. -// A request should start with an int that will be used as the command type. -BrokerHost::RequestStatus BrokerHost::HandleRequest() const { - std::vector<base::ScopedFD> fds; - char buf[kMaxMessageLength]; - errno = 0; - const ssize_t msg_len = base::UnixDomainSocket::RecvMsg( - ipc_channel_.get(), buf, sizeof(buf), &fds); - - if (msg_len == 0 || (msg_len == -1 && errno == ECONNRESET)) { - // EOF from the client, or the client died, we should die. - return RequestStatus::LOST_CLIENT; - } - - // The client should send exactly one file descriptor, on which we - // will write the reply. - if (msg_len < 0 || fds.size() != 1 || fds[0].get() < 0) { - PLOG(ERROR) << "Error reading message from the client"; - return RequestStatus::FAILURE; - } - - base::ScopedFD temporary_ipc(std::move(fds[0])); - - base::Pickle pickle(buf, msg_len); - base::PickleIterator iter(pickle); - int command_type; - if (iter.ReadInt(&command_type)) { - bool command_handled = false; - // Go through all the possible IPC messages. - switch (command_type) { - case COMMAND_ACCESS: - case COMMAND_OPEN: - // We reply on the file descriptor sent to us via the IPC channel. - command_handled = HandleRemoteCommand( - broker_policy_, static_cast<IPCCommand>(command_type), - temporary_ipc.get(), iter); - break; - default: - NOTREACHED(); - break; - } - - if (command_handled) { - return RequestStatus::SUCCESS; - } else { - return RequestStatus::FAILURE; - } - - NOTREACHED(); - } - - LOG(ERROR) << "Error parsing IPC request"; - return RequestStatus::FAILURE; -} - -} // namespace syscall_broker - -} // namespace sandbox |