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

#include "services/audio/audio_sandbox_hook_linux.h"

#include <dlfcn.h>
#include <unistd.h>
#include <string>
#include <string_view>
#include <vector>

#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "sandbox/linux/syscall_broker/broker_command.h"
#include "sandbox/linux/syscall_broker/broker_file_permission.h"

using sandbox::syscall_broker::BrokerFilePermission;
using sandbox::syscall_broker::MakeBrokerCommandSet;

namespace audio {

namespace {

#if defined(USE_ALSA)
void AddAlsaFilePermissions(std::vector<BrokerFilePermission>* permissions) {
  base::FilePath home_dir;
  base::PathService::Get(base::DIR_HOME, &home_dir);
  const base::FilePath asoundrc =
      home_dir.Append(FILE_PATH_LITERAL(".asoundrc"));
  const std::string read_only_filenames[]{"/etc/asound.conf", "/proc/cpuinfo",
                                          "/etc/group", "/etc/nsswitch.conf",
                                          asoundrc.value()};
  for (const auto& filename : read_only_filenames)
    permissions->push_back(BrokerFilePermission::ReadOnly(filename));

  permissions->push_back(
      BrokerFilePermission::ReadOnlyRecursive("/usr/share/alsa/"));
  permissions->push_back(
      BrokerFilePermission::ReadWriteCreateRecursive("/dev/snd/"));

  static const base::FilePath::CharType dev_aload_path[] =
      FILE_PATH_LITERAL("/dev/aloadC");
  for (int i = 0; i <= 31; ++i) {
    permissions->push_back(BrokerFilePermission::ReadWrite(
        base::StringPrintf("%s%d", dev_aload_path, i)));
  }
}
#endif

#if defined(USE_PULSEAUDIO)
// Utility function used to grant permissions on paths used by PulseAudio which
// are specified through environment variables. |recursive_only| is used to
// determine if the path itself should be allowed access or only its content.
void AllowAccessToEnvSpecifiedPath(
    std::string_view variable_name,
    std::vector<BrokerFilePermission>* permissions,
    bool recursive_only) {
  std::unique_ptr<base::Environment> env(base::Environment::Create());

  std::string path_value;
  if (!env->GetVar(variable_name, &path_value))
    return;

  const base::FilePath pa_config_path(path_value);
  if (pa_config_path.empty())
    return;

  if (!recursive_only) {
    permissions->push_back(BrokerFilePermission::ReadWriteCreate(
        pa_config_path.StripTrailingSeparators().value()));
  }
  permissions->push_back(BrokerFilePermission::ReadWriteCreateRecursive(
      pa_config_path.AsEndingWithSeparator().value()));
}

void AddPulseAudioFilePermissions(
    std::vector<BrokerFilePermission>* permissions) {
  base::FilePath home_dir;
  base::PathService::Get(base::DIR_HOME, &home_dir);
  const base::FilePath xauthority_path =
      home_dir.Append(FILE_PATH_LITERAL(".Xauthority"));

  // Calling read() system call on /proc/self/exe returns broker process' path,
  // and it's used by pulse audio for creating a new context.
  const std::string read_only_filenames[]{
      "/etc/machine-id", "/proc/self/exe",
      "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache",
      "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules", xauthority_path.value()};
  for (const auto& filename : read_only_filenames)
    permissions->push_back(BrokerFilePermission::ReadOnly(filename));

  // In certain situations, pulse runs stat() on the home directory.
  permissions->push_back(
      BrokerFilePermission::StatOnlyWithIntermediateDirs(home_dir.value()));

  permissions->push_back(
      BrokerFilePermission::ReadOnlyRecursive("/etc/pulse/"));

  // At times, Pulse tries to create the directory even if the directory already
  // exists and fails if the mkdir() operation returns anything other than
  // "success" or "exists".
  const char* pulse_home_dirs[] = {".pulse", ".config/pulse"};
  for (const char* pulse_home_dir : pulse_home_dirs) {
    const base::FilePath pulse_home_path = home_dir.Append(pulse_home_dir);
    permissions->push_back(
        BrokerFilePermission::ReadWriteCreate(pulse_home_path.value()));
    permissions->push_back(BrokerFilePermission::ReadWriteCreateRecursive(
        pulse_home_path.AsEndingWithSeparator().value()));
  }
  // Pulse might also need to create directories in tmp of the form
  // "/tmp/pulse-<random string>".
  permissions->push_back(
      BrokerFilePermission::ReadWriteCreateRecursive("/tmp/"));
  const char* env_tmp_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
  for (const char* env_tmp_path : env_tmp_paths) {
    AllowAccessToEnvSpecifiedPath(env_tmp_path, permissions,
                                  /*recursive_only=*/true);
  }
  // Read up the Pulse paths specified via environment variable and allow for
  // read/write/create recursively on the directory.
  const char* env_pulse_paths[] = {"PULSE_CONFIG_PATH", "PULSE_RUNTIME_PATH",
                                   "PULSE_STATE_PATH"};
  for (const char* env_pulse_path : env_pulse_paths) {
    AllowAccessToEnvSpecifiedPath(env_pulse_path, permissions,
                                  /*recursive_only=*/false);
  }

  const char* run_user_paths[] = {"/run/user", "/var/run/user"};
  for (const char* run_user_path : run_user_paths) {
    const std::string path =
        base::StringPrintf("%s/%d", run_user_path, getuid());
    permissions->push_back(BrokerFilePermission::ReadWriteCreate(path));
    permissions->push_back(
        BrokerFilePermission::ReadWriteCreate(path + "/pulse"));
    permissions->push_back(
        BrokerFilePermission::ReadWriteCreateRecursive(path + "/pulse/"));
  }
}
#endif

std::vector<BrokerFilePermission> GetAudioFilePermissions() {
  std::vector<BrokerFilePermission> permissions{
      BrokerFilePermission::ReadOnly("/dev/urandom"),
      BrokerFilePermission::ReadOnly("/sys/devices/system/cpu"),
      BrokerFilePermission::ReadOnlyRecursive("/usr/share/locale/"),
      BrokerFilePermission::ReadWriteCreateRecursive("/dev/shm/")};

#if defined(USE_PULSEAUDIO)
  AddPulseAudioFilePermissions(&permissions);
#endif
#if defined(USE_ALSA)
  AddAlsaFilePermissions(&permissions);
#endif

  return permissions;
}

void LoadAudioLibraries() {
  const std::string libraries[]{"libasound.so.2", "libpulse.so.0",
                                "libnss_files.so.2", "libnss_compat.so.2"};
  for (const auto& library_name : libraries) {
    if (nullptr ==
        dlopen(library_name.c_str(), RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE)) {
      LOG(WARNING) << "dlopen: failed to open " << library_name
                   << " with error: " << dlerror();
    }
  }
}

}  // namespace

bool AudioPreSandboxHook(sandbox::policy::SandboxLinux::Options options) {
  LoadAudioLibraries();
  auto* instance = sandbox::policy::SandboxLinux::GetInstance();
  instance->StartBrokerProcess(MakeBrokerCommandSet({
                                 sandbox::syscall_broker::COMMAND_ACCESS,
#if defined(USE_PULSEAUDIO)
                                     sandbox::syscall_broker::COMMAND_MKDIR,
#endif
                                     sandbox::syscall_broker::COMMAND_OPEN,
                                     sandbox::syscall_broker::COMMAND_READLINK,
                                     sandbox::syscall_broker::COMMAND_STAT,
                                     sandbox::syscall_broker::COMMAND_UNLINK,
                               }),
                               GetAudioFilePermissions(),
                               sandbox::policy::SandboxLinux::PreSandboxHook(),
                               options);

  // TODO(https://crbug.com/850878) enable namespace sandbox. Currently, if
  // enabled, connect() on pulse native socket fails with ENOENT (called from
  // pa_context_connect).

  return true;
}

}  // namespace audio
