// 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 "content/browser/renderer_host/sandbox_ipc_linux.h"

#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/stat.h>

#include "base/command_line.h"
#include "base/files/scoped_file.h"
#include "base/linux_util.h"
#include "base/macros.h"
#include "base/memory/shared_memory.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/unix_domain_socket_linux.h"
#include "base/process/launch.h"
#include "base/strings/string_number_conversions.h"
#include "content/browser/renderer_host/font_utils_linux.h"
#include "content/common/font_config_ipc_linux.h"
#include "content/common/sandbox_linux/sandbox_linux.h"
#include "content/common/set_process_title.h"
#include "content/public/common/content_switches.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
#include "skia/ext/skia_utils_base.h"
#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_fallback_linux.h"
#include "ui/gfx/font_render_params.h"

namespace content {

namespace {

// Converts gfx::FontRenderParams::Hinting to WebFontRenderStyle::hintStyle.
// Returns an int for serialization, but the underlying Blink type is a char.
int ConvertHinting(gfx::FontRenderParams::Hinting hinting) {
  switch (hinting) {
    case gfx::FontRenderParams::HINTING_NONE:   return 0;
    case gfx::FontRenderParams::HINTING_SLIGHT: return 1;
    case gfx::FontRenderParams::HINTING_MEDIUM: return 2;
    case gfx::FontRenderParams::HINTING_FULL:   return 3;
  }
  NOTREACHED() << "Unexpected hinting value " << hinting;
  return 0;
}

// Converts gfx::FontRenderParams::SubpixelRendering to
// WebFontRenderStyle::useSubpixelRendering. Returns an int for serialization,
// but the underlying Blink type is a char.
int ConvertSubpixelRendering(
    gfx::FontRenderParams::SubpixelRendering rendering) {
  switch (rendering) {
    case gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE: return 0;
    case gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB:  return 1;
    case gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR:  return 1;
    case gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB: return 1;
    case gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR: return 1;
  }
  NOTREACHED() << "Unexpected subpixel rendering value " << rendering;
  return 0;
}

}  // namespace

SandboxIPCHandler::SandboxIPCHandler(int lifeline_fd, int browser_socket)
    : lifeline_fd_(lifeline_fd),
      browser_socket_(browser_socket) {
}

void SandboxIPCHandler::Run() {
  struct pollfd pfds[2];
  pfds[0].fd = lifeline_fd_;
  pfds[0].events = POLLIN;
  pfds[1].fd = browser_socket_;
  pfds[1].events = POLLIN;

  int failed_polls = 0;
  for (;;) {
    const int r =
        HANDLE_EINTR(poll(pfds, arraysize(pfds), -1 /* no timeout */));
    // '0' is not a possible return value with no timeout.
    DCHECK_NE(0, r);
    if (r < 0) {
      PLOG(WARNING) << "poll";
      if (failed_polls++ == 3) {
        LOG(FATAL) << "poll(2) failing. SandboxIPCHandler aborting.";
        return;
      }
      continue;
    }

    failed_polls = 0;

    // The browser process will close the other end of this pipe on shutdown,
    // so we should exit.
    if (pfds[0].revents) {
      break;
    }

    // If poll(2) reports an error condition in this fd,
    // we assume the zygote is gone and we exit the loop.
    if (pfds[1].revents & (POLLERR | POLLHUP)) {
      break;
    }

    if (pfds[1].revents & POLLIN) {
      HandleRequestFromRenderer(browser_socket_);
    }
  }

  VLOG(1) << "SandboxIPCHandler stopping.";
}

void SandboxIPCHandler::HandleRequestFromRenderer(int fd) {
  std::vector<base::ScopedFD> fds;

  // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
  // bytes long (this is the largest message type).
  // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC
  // error for a maximum length message.
  char buf[FontConfigIPC::kMaxFontFamilyLength + 128];

  const ssize_t len =
      base::UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
  if (len == -1) {
    // TODO: should send an error reply, or the sender might block forever.
    NOTREACHED() << "Sandbox host message is larger than kMaxFontFamilyLength";
    return;
  }
  if (fds.empty())
    return;

  base::Pickle pickle(buf, len);
  base::PickleIterator iter(pickle);

  int kind;
  if (!iter.ReadInt(&kind))
    return;

  if (kind == FontConfigIPC::METHOD_MATCH) {
    HandleFontMatchRequest(fd, iter, fds);
  } else if (kind == FontConfigIPC::METHOD_OPEN) {
    HandleFontOpenRequest(fd, iter, fds);
  } else if (kind == LinuxSandbox::METHOD_GET_FALLBACK_FONT_FOR_CHAR) {
    HandleGetFallbackFontForChar(fd, iter, fds);
  } else if (kind == LinuxSandbox::METHOD_LOCALTIME) {
    HandleLocaltime(fd, iter, fds);
  } else if (kind == LinuxSandbox::METHOD_GET_STYLE_FOR_STRIKE) {
    HandleGetStyleForStrike(fd, iter, fds);
  } else if (kind == LinuxSandbox::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
    HandleMakeSharedMemorySegment(fd, iter, fds);
  } else if (kind == LinuxSandbox::METHOD_MATCH_WITH_FALLBACK) {
    HandleMatchWithFallback(fd, iter, fds);
  }
}

int SandboxIPCHandler::FindOrAddPath(const SkString& path) {
  int count = paths_.size();
  for (int i = 0; i < count; ++i) {
    if (path == paths_[i])
      return i;
  }
  paths_.emplace_back(path);
  return count;
}

void SandboxIPCHandler::HandleFontMatchRequest(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  SkFontStyle requested_style;
  std::string family;
  if (!iter.ReadString(&family) ||
      !skia::ReadSkFontStyle(&iter, &requested_style))
    return;

  SkFontConfigInterface::FontIdentity result_identity;
  SkString result_family;
  SkFontStyle result_style;
  SkFontConfigInterface* fc =
      SkFontConfigInterface::GetSingletonDirectInterface();
  const bool r =
      fc->matchFamilyName(family.c_str(),
                          requested_style,
                          &result_identity,
                          &result_family,
                          &result_style);

  base::Pickle reply;
  if (!r) {
    reply.WriteBool(false);
  } else {
    // Stash away the returned path, so we can give it an ID (index)
    // which will later be given to us in a request to open the file.
    int index = FindOrAddPath(result_identity.fString);
    result_identity.fID = static_cast<uint32_t>(index);

    reply.WriteBool(true);
    skia::WriteSkString(&reply, result_family);
    skia::WriteSkFontIdentity(&reply, result_identity);
    skia::WriteSkFontStyle(&reply, result_style);
  }
  SendRendererReply(fds, reply, -1);
}

void SandboxIPCHandler::HandleFontOpenRequest(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  uint32_t index;
  if (!iter.ReadUInt32(&index))
    return;
  if (index >= static_cast<uint32_t>(paths_.size()))
    return;
  const int result_fd = open(paths_[index].c_str(), O_RDONLY);

  base::Pickle reply;
  if (result_fd == -1) {
    reply.WriteBool(false);
  } else {
    reply.WriteBool(true);
  }

  // The receiver will have its own access to the file, so we will close it
  // after this send.
  SendRendererReply(fds, reply, result_fd);

  if (result_fd >= 0) {
    int err = IGNORE_EINTR(close(result_fd));
    DCHECK(!err);
  }
}

void SandboxIPCHandler::HandleGetFallbackFontForChar(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  // The other side of this call is
  // content/common/child_process_sandbox_support_impl_linux.cc

  UChar32 c;
  if (!iter.ReadInt(&c))
    return;

  std::string preferred_locale;
  if (!iter.ReadString(&preferred_locale))
    return;

  auto fallback_font = gfx::GetFallbackFontForChar(c, preferred_locale);
  int fontconfig_interface_id =
      FindOrAddPath(SkString(fallback_font.filename.data()));

  base::Pickle reply;
  reply.WriteString(fallback_font.name);
  reply.WriteString(fallback_font.filename);
  reply.WriteInt(fontconfig_interface_id);
  reply.WriteInt(fallback_font.ttc_index);
  reply.WriteBool(fallback_font.is_bold);
  reply.WriteBool(fallback_font.is_italic);
  SendRendererReply(fds, reply, -1);
}

void SandboxIPCHandler::HandleGetStyleForStrike(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  std::string family;
  bool bold, italic;
  uint16_t pixel_size;

  if (!iter.ReadString(&family) ||
      !iter.ReadBool(&bold) ||
      !iter.ReadBool(&italic) ||
      !iter.ReadUInt16(&pixel_size)) {
    return;
  }

  gfx::FontRenderParamsQuery query;
  query.families.push_back(family);
  query.pixel_size = pixel_size;
  query.style = italic ? gfx::Font::ITALIC : 0;
  query.weight = bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL;
  const gfx::FontRenderParams params = gfx::GetFontRenderParams(query, NULL);

  // These are passed as ints since they're interpreted as tri-state chars in
  // Blink.
  base::Pickle reply;
  reply.WriteInt(params.use_bitmaps);
  reply.WriteInt(params.autohinter);
  reply.WriteInt(params.hinting != gfx::FontRenderParams::HINTING_NONE);
  reply.WriteInt(ConvertHinting(params.hinting));
  reply.WriteInt(params.antialiasing);
  reply.WriteInt(ConvertSubpixelRendering(params.subpixel_rendering));
  reply.WriteInt(params.subpixel_positioning);

  SendRendererReply(fds, reply, -1);
}

void SandboxIPCHandler::HandleLocaltime(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  // The other side of this call is in zygote_main_linux.cc

  std::string time_string;
  if (!iter.ReadString(&time_string) || time_string.size() != sizeof(time_t))
    return;

  time_t time;
  memcpy(&time, time_string.data(), sizeof(time));
  // We use localtime here because we need the tm_zone field to be filled
  // out. Since we are a single-threaded process, this is safe.
  const struct tm* expanded_time = localtime(&time);

  std::string result_string;
  const char* time_zone_string = "";
  if (expanded_time != NULL) {
    result_string = std::string(reinterpret_cast<const char*>(expanded_time),
                                sizeof(struct tm));
    time_zone_string = expanded_time->tm_zone;
  }

  base::Pickle reply;
  reply.WriteString(result_string);
  reply.WriteString(time_zone_string);
  SendRendererReply(fds, reply, -1);
}

void SandboxIPCHandler::HandleMakeSharedMemorySegment(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  base::SharedMemoryCreateOptions options;
  uint32_t size;
  if (!iter.ReadUInt32(&size))
    return;
  options.size = size;
  if (!iter.ReadBool(&options.executable))
    return;
  int shm_fd = -1;
  base::SharedMemory shm;
  if (shm.Create(options))
    shm_fd = shm.handle().fd;
  base::Pickle reply;
  SendRendererReply(fds, reply, shm_fd);
}

void SandboxIPCHandler::HandleMatchWithFallback(
    int fd,
    base::PickleIterator iter,
    const std::vector<base::ScopedFD>& fds) {
  std::string face;
  bool is_bold, is_italic;
  uint32_t charset, fallback_family;

  if (!iter.ReadString(&face) || face.empty() ||
      !iter.ReadBool(&is_bold) ||
      !iter.ReadBool(&is_italic) ||
      !iter.ReadUInt32(&charset) ||
      !iter.ReadUInt32(&fallback_family)) {
    return;
  }

  int font_fd = MatchFontFaceWithFallback(
      face, is_bold, is_italic, charset, fallback_family);

  base::Pickle reply;
  SendRendererReply(fds, reply, font_fd);

  if (font_fd >= 0) {
    if (IGNORE_EINTR(close(font_fd)) < 0)
      PLOG(ERROR) << "close";
  }
}

void SandboxIPCHandler::SendRendererReply(
    const std::vector<base::ScopedFD>& fds,
    const base::Pickle& reply,
    int reply_fd) {
  struct msghdr msg;
  memset(&msg, 0, sizeof(msg));
  struct iovec iov = {const_cast<void*>(reply.data()), reply.size()};
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  char control_buffer[CMSG_SPACE(sizeof(int))];

  if (reply_fd != -1) {
    struct stat st;
    if (fstat(reply_fd, &st) == 0 && S_ISDIR(st.st_mode)) {
      LOG(FATAL) << "Tried to send a directory descriptor over sandbox IPC";
      // We must never send directory descriptors to a sandboxed process
      // because they can use openat with ".." elements in the path in order
      // to escape the sandbox and reach the real filesystem.
    }

    struct cmsghdr* cmsg;
    msg.msg_control = control_buffer;
    msg.msg_controllen = sizeof(control_buffer);
    cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    memcpy(CMSG_DATA(cmsg), &reply_fd, sizeof(reply_fd));
    msg.msg_controllen = cmsg->cmsg_len;
  }

  if (HANDLE_EINTR(sendmsg(fds[0].get(), &msg, MSG_DONTWAIT)) < 0)
    PLOG(ERROR) << "sendmsg";
}

SandboxIPCHandler::~SandboxIPCHandler() {
  if (IGNORE_EINTR(close(lifeline_fd_)) < 0)
    PLOG(ERROR) << "close";
  if (IGNORE_EINTR(close(browser_socket_)) < 0)
    PLOG(ERROR) << "close";
}

}  // namespace content
