// Copyright 2017 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/gpu/gpu_sandbox_hook_linux.h"

#include <dlfcn.h>
#include <errno.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_enumerator.h"
#include "base/files/scoped_file.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "content/public/common/content_switches.h"
#include "media/gpu/features.h"
#include "sandbox/linux/bpf_dsl/policy.h"
#include "sandbox/linux/syscall_broker/broker_file_permission.h"
#include "sandbox/linux/syscall_broker/broker_process.h"
#include "services/service_manager/embedder/set_process_title.h"
#include "services/service_manager/sandbox/linux/bpf_cros_amd_gpu_policy_linux.h"
#include "services/service_manager/sandbox/linux/bpf_cros_arm_gpu_policy_linux.h"
#include "services/service_manager/sandbox/linux/bpf_gpu_policy_linux.h"
#include "services/service_manager/sandbox/linux/sandbox_linux.h"

using sandbox::bpf_dsl::Policy;
using sandbox::syscall_broker::BrokerFilePermission;
using sandbox::syscall_broker::BrokerProcess;

namespace content {
namespace {

inline bool IsChromeOS() {
#if defined(OS_CHROMEOS)
  return true;
#else
  return false;
#endif
}

inline bool IsArchitectureX86_64() {
#if defined(__x86_64__)
  return true;
#else
  return false;
#endif
}

inline bool IsArchitectureI386() {
#if defined(__i386__)
  return true;
#else
  return false;
#endif
}

inline bool IsArchitectureArm() {
#if defined(__arm__) || defined(__aarch64__)
  return true;
#else
  return false;
#endif
}

inline bool UseV4L2Codec() {
#if BUILDFLAG(USE_V4L2_CODEC)
  return true;
#else
  return false;
#endif
}

inline bool UseLibV4L2() {
#if BUILDFLAG(USE_LIBV4L2)
  return true;
#else
  return false;
#endif
}

void AddV4L2GpuWhitelist(std::vector<BrokerFilePermission>* permissions,
                         bool accelerated_video_decode_enabled) {
  if (accelerated_video_decode_enabled) {
    // Device nodes for V4L2 video decode accelerator drivers.
    static const base::FilePath::CharType kDevicePath[] =
        FILE_PATH_LITERAL("/dev/");
    static const base::FilePath::CharType kVideoDecPattern[] = "video-dec[0-9]";
    base::FileEnumerator enumerator(base::FilePath(kDevicePath), false,
                                    base::FileEnumerator::FILES,
                                    base::FilePath(kVideoDecPattern).value());
    for (base::FilePath name = enumerator.Next(); !name.empty();
         name = enumerator.Next())
      permissions->push_back(BrokerFilePermission::ReadWrite(name.value()));
  }

  // Device node for V4L2 video encode accelerator drivers.
  static const char kDevVideoEncPath[] = "/dev/video-enc";
  permissions->push_back(BrokerFilePermission::ReadWrite(kDevVideoEncPath));

  // Device node for V4L2 JPEG decode accelerator drivers.
  static const char kDevJpegDecPath[] = "/dev/jpeg-dec";
  permissions->push_back(BrokerFilePermission::ReadWrite(kDevJpegDecPath));
}

void UpdateProcessTypeToGpuBroker() {
  base::CommandLine::StringVector exec =
      base::CommandLine::ForCurrentProcess()->GetArgs();
  base::CommandLine::Reset();
  base::CommandLine::Init(0, NULL);
  base::CommandLine::ForCurrentProcess()->InitFromArgv(exec);
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kProcessType, "gpu-broker");

  // Update the process title. The argv was already cached by the call to
  // SetProcessTitleFromCommandLine in content_main_runner.cc, so we can pass
  // NULL here (we don't have the original argv at this point).
  service_manager::SetProcessTitleFromCommandLine(nullptr);
}

bool UpdateProcessTypeAndEnableSandbox(
    std::unique_ptr<Policy> (*broker_sandboxer_allocator)()) {
  DCHECK(broker_sandboxer_allocator);
  UpdateProcessTypeToGpuBroker();
  return service_manager::SandboxSeccompBPF::StartSandboxWithExternalPolicy(
      broker_sandboxer_allocator(), base::ScopedFD());
}

void AddArmMaliGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
  // Device file needed by the ARM GPU userspace.
  static const char kMali0Path[] = "/dev/mali0";

  // Image processor used on ARM platforms.
  static const char kDevImageProc0Path[] = "/dev/image-proc0";

  permissions->push_back(BrokerFilePermission::ReadWrite(kMali0Path));
  permissions->push_back(BrokerFilePermission::ReadWrite(kDevImageProc0Path));
}

void AddAmdGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
  static const char* kReadOnlyList[] = {"/etc/ld.so.cache",
                                        "/usr/lib64/libEGL.so.1",
                                        "/usr/lib64/libGLESv2.so.2"};
  int listSize = arraysize(kReadOnlyList);

  for (int i = 0; i < listSize; i++) {
    permissions->push_back(BrokerFilePermission::ReadOnly(kReadOnlyList[i]));
  }

  static const char* kReadWriteList[] = {
      "/dev/dri",
      "/dev/dri/card0",
      "/dev/dri/controlD64",
      "/dev/dri/renderD128",
      "/sys/class/drm/card0/device/config",
      "/sys/class/drm/controlD64/device/config",
      "/sys/class/drm/renderD128/device/config",
      "/usr/share/libdrm/amdgpu.ids"};

  listSize = arraysize(kReadWriteList);

  for (int i = 0; i < listSize; i++) {
    permissions->push_back(BrokerFilePermission::ReadWrite(kReadWriteList[i]));
  }

  static const char kCharDevices[] = "/sys/dev/char/";
  permissions->push_back(BrokerFilePermission::ReadOnlyRecursive(kCharDevices));
}

void AddArmGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
  // On ARM we're enabling the sandbox before the X connection is made,
  // so we need to allow access to |.Xauthority|.
  static const char kXAuthorityPath[] = "/home/chronos/.Xauthority";
  static const char kLdSoCache[] = "/etc/ld.so.cache";

  // Files needed by the ARM GPU userspace.
  static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
  static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";

  permissions->push_back(BrokerFilePermission::ReadOnly(kXAuthorityPath));
  permissions->push_back(BrokerFilePermission::ReadOnly(kLdSoCache));
  permissions->push_back(BrokerFilePermission::ReadOnly(kLibGlesPath));
  permissions->push_back(BrokerFilePermission::ReadOnly(kLibEglPath));

  AddArmMaliGpuWhitelist(permissions);
}

// Start a broker process to handle open() inside the sandbox.
// |broker_sandboxer_allocator| is a function pointer which can allocate a
// suitable sandbox policy for the broker process itself.
// |permissions_extra| is a list of file permissions
// that should be whitelisted by the broker process, in addition to
// the basic ones.
std::unique_ptr<BrokerProcess> InitGpuBrokerProcess(
    std::unique_ptr<Policy> (*broker_sandboxer_allocator)(),
    const std::vector<BrokerFilePermission>& permissions_extra,
    bool accelerated_video_decode_enabled) {
  static const char kDriRcPath[] = "/etc/drirc";
  static const char kDriCardBasePath[] = "/dev/dri/card";
  static const char kNvidiaCtlPath[] = "/dev/nvidiactl";
  static const char kNvidiaDeviceBasePath[] = "/dev/nvidia";
  static const char kNvidiaParamsPath[] = "/proc/driver/nvidia/params";
  static const char kDevShm[] = "/dev/shm/";

  // All GPU process policies need these files brokered out.
  std::vector<BrokerFilePermission> permissions;
  permissions.push_back(BrokerFilePermission::ReadOnly(kDriRcPath));

  if (!IsChromeOS()) {
    // For shared memory.
    permissions.push_back(
        BrokerFilePermission::ReadWriteCreateUnlinkRecursive(kDevShm));
    // For DRI cards.
    for (int i = 0; i <= 9; ++i) {
      permissions.push_back(BrokerFilePermission::ReadWrite(
          base::StringPrintf("%s%d", kDriCardBasePath, i)));
    }
    // For Nvidia GLX driver.
    permissions.push_back(BrokerFilePermission::ReadWrite(kNvidiaCtlPath));
    for (int i = 0; i <= 9; ++i) {
      permissions.push_back(BrokerFilePermission::ReadWrite(
          base::StringPrintf("%s%d", kNvidiaDeviceBasePath, i)));
    }
    permissions.push_back(BrokerFilePermission::ReadOnly(kNvidiaParamsPath));
  } else if (UseV4L2Codec()) {
    AddV4L2GpuWhitelist(&permissions, accelerated_video_decode_enabled);
    if (UseLibV4L2()) {
      dlopen("/usr/lib/libv4l2.so", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
      // This is a device-specific encoder plugin.
      dlopen("/usr/lib/libv4l/plugins/libv4l-encplugin.so",
             RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
    }
  }

  // Add eventual extra files from permissions_extra.
  for (const auto& perm : permissions_extra) {
    permissions.push_back(perm);
  }

  auto result = std::make_unique<BrokerProcess>(
      service_manager::SandboxBPFBasePolicy::GetFSDeniedErrno(), permissions);
  // The initialization callback will perform generic initialization and then
  // call broker_sandboxer_callback.
  CHECK(result->Init(base::Bind(&UpdateProcessTypeAndEnableSandbox,
                                broker_sandboxer_allocator)));

  return result;
}

bool GpuPreSandboxHook(sandbox::bpf_dsl::Policy* policy,
                       service_manager::SandboxSeccompBPF::Options options) {
  // Warm up resources needed by the policy we're about to enable and
  // eventually start a broker process.
  const bool chromeos_arm_gpu = IsChromeOS() && IsArchitectureArm();
  // This policy is for x86 or Desktop.
  DCHECK(!chromeos_arm_gpu);

  // Create a new broker process with no extra files in whitelist.
  service_manager::SandboxLinux::GetInstance()->set_broker_process(
      InitGpuBrokerProcess(
          []() -> std::unique_ptr<Policy> {
            return std::make_unique<service_manager::GpuBrokerProcessPolicy>();
          },
          std::vector<BrokerFilePermission>(),
          options.accelerated_video_decode_enabled));

  if (IsArchitectureX86_64() || IsArchitectureI386()) {
    // Accelerated video dlopen()'s some shared objects
    // inside the sandbox, so preload them now.
    if (options.vaapi_accelerated_video_encode_enabled ||
        options.accelerated_video_decode_enabled) {
      const char* I965DrvVideoPath = NULL;
      const char* I965HybridDrvVideoPath = NULL;

      if (IsArchitectureX86_64()) {
        I965DrvVideoPath = "/usr/lib64/va/drivers/i965_drv_video.so";
        I965HybridDrvVideoPath = "/usr/lib64/va/drivers/hybrid_drv_video.so";
      } else if (IsArchitectureI386()) {
        I965DrvVideoPath = "/usr/lib/va/drivers/i965_drv_video.so";
      }

      dlopen(I965DrvVideoPath, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
      if (I965HybridDrvVideoPath)
        dlopen(I965HybridDrvVideoPath, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
      dlopen("libva.so.1", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
#if defined(USE_OZONE)
      dlopen("libva-drm.so.1", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
#elif defined(USE_X11)
      dlopen("libva-x11.so.1", RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
#endif
    }
  }

  return true;
}

bool CrosArmGpuPreSandboxHook(
    sandbox::bpf_dsl::Policy* policy,
    service_manager::SandboxSeccompBPF::Options options) {
  DCHECK(IsChromeOS() && IsArchitectureArm());

  // Add ARM-specific files to whitelist in the broker.
  std::vector<BrokerFilePermission> permissions;
  AddArmGpuWhitelist(&permissions);
  service_manager::SandboxLinux::GetInstance()->set_broker_process(
      InitGpuBrokerProcess(
          []() -> std::unique_ptr<Policy> {
            return std::make_unique<
                service_manager::CrosArmGpuBrokerProcessPolicy>();
          },
          permissions, options.accelerated_video_decode_enabled));

  const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;

  // Preload the Mali library.
  dlopen("/usr/lib/libmali.so", dlopen_flag);
  // Preload the Tegra V4L2 (video decode acceleration) library.
  dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag);
  // Resetting errno since platform-specific libraries will fail on other
  // platforms.
  errno = 0;

  return true;
}

bool CrosAmdGpuPreSandboxHook(
    sandbox::bpf_dsl::Policy* policy,
    service_manager::SandboxSeccompBPF::Options options) {
  DCHECK(IsChromeOS());

  // Add AMD-specific files to whitelist in the broker.
  std::vector<BrokerFilePermission> permissions;
  AddAmdGpuWhitelist(&permissions);

  service_manager::SandboxLinux::GetInstance()->set_broker_process(
      InitGpuBrokerProcess(
          []() -> std::unique_ptr<Policy> {
            return std::make_unique<
                service_manager::CrosAmdGpuBrokerProcessPolicy>();
          },
          permissions, options.accelerated_video_decode_enabled));

  const int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;

  // Preload the amdgpu-dependent libraries.
  errno = 0;
  if (NULL == dlopen("libglapi.so", dlopen_flag)) {
    LOG(ERROR) << "dlopen(libglapi.so) failed with error: " << dlerror();
    return false;
  }
  if (NULL == dlopen("/usr/lib64/dri/radeonsi_dri.so", dlopen_flag)) {
    LOG(ERROR) << "dlopen(radeonsi_dri.so) failed with error: " << dlerror();
    return false;
  }

  return true;
}

}  // namespace

service_manager::SandboxSeccompBPF::PreSandboxHook GetGpuProcessPreSandboxHook(
    bool use_amd_specific_policies) {
  if (IsChromeOS()) {
    if (IsArchitectureArm())
      return base::BindOnce(&CrosArmGpuPreSandboxHook);
    if (use_amd_specific_policies)
      return base::BindOnce(&CrosAmdGpuPreSandboxHook);
  }
  return base::BindOnce(&GpuPreSandboxHook);
}

}  // namespace content
