// Copyright (c) 2013 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/seccomp-bpf-helpers/baseline_policy.h"

#include <errno.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#include "base/logging.h"
#include "build/build_config.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h"
#include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h"
#include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h"
#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
#include "sandbox/linux/services/linux_syscalls.h"
#include "sandbox/linux/services/syscall_wrappers.h"

// Changing this implementation will have an effect on *all* policies.
// Currently this means: Renderer/Worker, GPU, Flash and NaCl.

using sandbox::bpf_dsl::Allow;
using sandbox::bpf_dsl::Arg;
using sandbox::bpf_dsl::Error;
using sandbox::bpf_dsl::If;
using sandbox::bpf_dsl::ResultExpr;

namespace sandbox {

namespace {

bool IsBaselinePolicyAllowed(int sysno) {
  return SyscallSets::IsAllowedAddressSpaceAccess(sysno) ||
         SyscallSets::IsAllowedBasicScheduler(sysno) ||
         SyscallSets::IsAllowedEpoll(sysno) ||
         SyscallSets::IsAllowedFileSystemAccessViaFd(sysno) ||
         SyscallSets::IsAllowedFutex(sysno) ||
         SyscallSets::IsAllowedGeneralIo(sysno) ||
         SyscallSets::IsAllowedGetOrModifySocket(sysno) ||
         SyscallSets::IsAllowedGettime(sysno) ||
         SyscallSets::IsAllowedProcessStartOrDeath(sysno) ||
         SyscallSets::IsAllowedSignalHandling(sysno) ||
         SyscallSets::IsGetSimpleId(sysno) ||
         SyscallSets::IsKernelInternalApi(sysno) ||
#if defined(__arm__)
         SyscallSets::IsArmPrivate(sysno) ||
#endif
#if defined(__mips__)
         SyscallSets::IsMipsPrivate(sysno) ||
#endif
         SyscallSets::IsAllowedOperationOnFd(sysno);
}

// System calls that will trigger the crashing SIGSYS handler.
bool IsBaselinePolicyWatched(int sysno) {
  return SyscallSets::IsAdminOperation(sysno) ||
         SyscallSets::IsAdvancedScheduler(sysno) ||
         SyscallSets::IsAdvancedTimer(sysno) ||
         SyscallSets::IsAsyncIo(sysno) ||
         SyscallSets::IsDebug(sysno) ||
         SyscallSets::IsEventFd(sysno) ||
         SyscallSets::IsExtendedAttributes(sysno) ||
         SyscallSets::IsFaNotify(sysno) ||
         SyscallSets::IsFsControl(sysno) ||
         SyscallSets::IsGlobalFSViewChange(sysno) ||
         SyscallSets::IsGlobalProcessEnvironment(sysno) ||
         SyscallSets::IsGlobalSystemStatus(sysno) ||
         SyscallSets::IsInotify(sysno) ||
         SyscallSets::IsKernelModule(sysno) ||
         SyscallSets::IsKeyManagement(sysno) ||
         SyscallSets::IsKill(sysno) ||
         SyscallSets::IsMessageQueue(sysno) ||
         SyscallSets::IsMisc(sysno) ||
#if defined(__x86_64__)
         SyscallSets::IsNetworkSocketInformation(sysno) ||
#endif
         SyscallSets::IsNuma(sysno) ||
         SyscallSets::IsPrctl(sysno) ||
         SyscallSets::IsProcessGroupOrSession(sysno) ||
#if defined(__i386__) || defined(__mips__)
         SyscallSets::IsSocketCall(sysno) ||
#endif
#if defined(__arm__)
         SyscallSets::IsArmPciConfig(sysno) ||
#endif
#if defined(__mips__)
         SyscallSets::IsMipsMisc(sysno) ||
#endif
         SyscallSets::IsTimer(sysno);
}

// |fs_denied_errno| is the errno return for denied filesystem access.
ResultExpr EvaluateSyscallImpl(int fs_denied_errno,
                               pid_t current_pid,
                               int sysno) {
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
    defined(MEMORY_SANITIZER)
  // TCGETS is required by the sanitizers on failure.
  if (sysno == __NR_ioctl) {
    return RestrictIoctl();
  }

  if (sysno == __NR_sched_getaffinity) {
    return Allow();
  }

  if (sysno == __NR_sigaltstack) {
    // Required for better stack overflow detection in ASan. Disallowed in
    // non-ASan builds.
    return Allow();
  }
#endif  // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||
        // defined(MEMORY_SANITIZER)

  if (IsBaselinePolicyAllowed(sysno)) {
    return Allow();
  }

#if defined(OS_ANDROID)
  // Needed for thread creation.
  if (sysno == __NR_sigaltstack)
    return Allow();
#endif

  if (sysno == __NR_clock_gettime) {
    return RestrictClockID();
  }

  if (sysno == __NR_clone) {
    return RestrictCloneToThreadsAndEPERMFork();
  }

  if (sysno == __NR_fcntl)
    return RestrictFcntlCommands();

#if defined(__i386__) || defined(__arm__) || defined(__mips__)
  if (sysno == __NR_fcntl64)
    return RestrictFcntlCommands();
#endif

#if !defined(__aarch64__)
  // fork() is never used as a system call (clone() is used instead), but we
  // have seen it in fallback code on Android.
  if (sysno == __NR_fork) {
    return Error(EPERM);
  }
#endif

  if (sysno == __NR_futex)
    return RestrictFutex();

  if (sysno == __NR_set_robust_list)
    return Error(EPERM);

  if (sysno == __NR_getpriority || sysno ==__NR_setpriority)
    return RestrictGetSetpriority(current_pid);

  if (sysno == __NR_madvise) {
    // Only allow MADV_DONTNEED (aka MADV_FREE).
    const Arg<int> advice(2);
    return If(advice == MADV_DONTNEED, Allow()).Else(Error(EPERM));
  }

#if defined(__i386__) || defined(__x86_64__) || defined(__mips__) || \
    defined(__aarch64__)
  if (sysno == __NR_mmap)
    return RestrictMmapFlags();
#endif

#if defined(__i386__) || defined(__arm__) || defined(__mips__)
  if (sysno == __NR_mmap2)
    return RestrictMmapFlags();
#endif

  if (sysno == __NR_mprotect)
    return RestrictMprotectFlags();

  if (sysno == __NR_prctl)
    return RestrictPrctl();

#if defined(__x86_64__) || defined(__arm__) || defined(__mips__) || \
    defined(__aarch64__)
  if (sysno == __NR_socketpair) {
    // Only allow AF_UNIX, PF_UNIX. Crash if anything else is seen.
    static_assert(AF_UNIX == PF_UNIX,
                  "af_unix and pf_unix should not be different");
    const Arg<int> domain(0);
    return If(domain == AF_UNIX, Allow()).Else(CrashSIGSYS());
  }
#endif

  if (SyscallSets::IsKill(sysno)) {
    return RestrictKillTarget(current_pid, sysno);
  }

  if (SyscallSets::IsFileSystem(sysno) ||
      SyscallSets::IsCurrentDirectory(sysno)) {
    return Error(fs_denied_errno);
  }

  if (SyscallSets::IsSeccomp(sysno))
    return Error(EPERM);

  if (SyscallSets::IsAnySystemV(sysno)) {
    return Error(EPERM);
  }

  if (SyscallSets::IsUmask(sysno) ||
      SyscallSets::IsDeniedFileSystemAccessViaFd(sysno) ||
      SyscallSets::IsDeniedGetOrModifySocket(sysno) ||
      SyscallSets::IsProcessPrivilegeChange(sysno)) {
    return Error(EPERM);
  }

#if defined(__i386__) || defined(__mips__)
  if (SyscallSets::IsSocketCall(sysno))
    return RestrictSocketcallCommand();
#endif

  if (IsBaselinePolicyWatched(sysno)) {
    // Previously unseen syscalls. TODO(jln): some of these should
    // be denied gracefully right away.
    return CrashSIGSYS();
  }

  // In any other case crash the program with our SIGSYS handler.
  return CrashSIGSYS();
}

}  // namespace.

// Unfortunately C++03 doesn't allow delegated constructors.
// Call other constructor when C++11 lands.
BaselinePolicy::BaselinePolicy() : BaselinePolicy(EPERM) {}

BaselinePolicy::BaselinePolicy(int fs_denied_errno)
    : fs_denied_errno_(fs_denied_errno), policy_pid_(sys_getpid()) {
}

BaselinePolicy::~BaselinePolicy() {
  // Make sure that this policy is created, used and destroyed by a single
  // process.
  DCHECK_EQ(sys_getpid(), policy_pid_);
}

ResultExpr BaselinePolicy::EvaluateSyscall(int sysno) const {
  // Sanity check that we're only called with valid syscall numbers.
  DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
  // Make sure that this policy is used in the creating process.
  if (1 == sysno) {
    DCHECK_EQ(sys_getpid(), policy_pid_);
  }
  return EvaluateSyscallImpl(fs_denied_errno_, policy_pid_, sysno);
}

ResultExpr BaselinePolicy::InvalidSyscall() const {
  return CrashSIGSYS();
}

}  // namespace sandbox.
