chromium/ipc/ipc_send_fds_test.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#if BUILDFLAG(IS_MAC)
extern "C" {
#include <sandbox.h>
}
#endif

#include <fcntl.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>

#include <memory>
#include <queue>

#include "base/file_descriptor_posix.h"
#include "base/pickle.h"
#include "base/posix/eintr_wrapper.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "ipc/ipc_message_attachment_set.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_test_base.h"

#if BUILDFLAG(IS_MAC)
#include "sandbox/mac/seatbelt.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include "base/memory/scoped_refptr.h"
#include "base/test/scoped_dev_zero_fuchsia.h"
#endif

namespace {

const unsigned kNumFDsToSend =;  // per message
const unsigned kNumMessages =;
const char* kDevZeroPath =;

static_assert;

class MyChannelDescriptorListenerBase : public IPC::Listener {};

class MyChannelDescriptorListener : public MyChannelDescriptorListenerBase {};

class IPCSendFdsTest : public IPCChannelMojoTestBase {};

// Disabled on Fuchsia due to failures; see https://crbug.com/1272424.
#if BUILDFLAG(IS_FUCHSIA)
#define MAYBE_DescriptorTest
#else
#define MAYBE_DescriptorTest
#endif
TEST_F(IPCSendFdsTest, MAYBE_DescriptorTest) {}

class SendFdsTestClientFixture : public IpcChannelMojoTestClient {};

DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
    SendFdsClient,
    SendFdsTestClientFixture) {}

#if BUILDFLAG(IS_MAC)
// Test that FDs are correctly sent to a sandboxed process.
// TODO(port): Make this test cross-platform.
TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) {
  Init("SendFdsSandboxedClient");
  RunServer();
}

DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE(
    SendFdsSandboxedClient,
    SendFdsTestClientFixture) {
  struct stat st;
  const int fd = open(kDevZeroPath, O_RDONLY);
  fstat(fd, &st);
  ASSERT_LE(0, IGNORE_EINTR(close(fd)));

  // Enable the sandbox.
  std::string error;
  ASSERT_TRUE(sandbox::Seatbelt::Init(
      sandbox::Seatbelt::kProfilePureComputation, SANDBOX_NAMED, &error))
      << error;

  // Make sure sandbox is really enabled.
  ASSERT_EQ(-1, open(kDevZeroPath, O_RDONLY))
      << "Sandbox wasn't properly enabled";

  // See if we can receive a file descriptor.
  SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino);
}
#endif  // BUILDFLAG(IS_MAC)

}  // namespace