// 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 "sandbox/linux/services/syscall_wrappers.h"

#include <pthread.h>
#include <sched.h>
#include <setjmp.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstring>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/third_party/valgrind/valgrind.h"
#include "build/build_config.h"
#include "sandbox/linux/system_headers/capability.h"
#include "sandbox/linux/system_headers/linux_signal.h"
#include "sandbox/linux/system_headers/linux_syscalls.h"

namespace sandbox {

pid_t sys_getpid(void) {
  return syscall(__NR_getpid);
}

pid_t sys_gettid(void) {
  return syscall(__NR_gettid);
}

long sys_clone(unsigned long flags,
               std::nullptr_t child_stack,
               pid_t* ptid,
               pid_t* ctid,
               std::nullptr_t tls) {
  const bool clone_tls_used = flags & CLONE_SETTLS;
  const bool invalid_ctid =
      (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
  const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;

  // We do not support CLONE_VM.
  const bool clone_vm_used = flags & CLONE_VM;
  if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
    RAW_LOG(FATAL, "Invalid usage of sys_clone");
  }

  if (ptid) MSAN_UNPOISON(ptid, sizeof(*ptid));
  if (ctid) MSAN_UNPOISON(ctid, sizeof(*ctid));
  // See kernel/fork.c in Linux. There is different ordering of sys_clone
  // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options.
#if defined(ARCH_CPU_X86_64)
  return syscall(__NR_clone, flags, child_stack, ptid, ctid, tls);
#elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \
    defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY)
  // CONFIG_CLONE_BACKWARDS defined.
  return syscall(__NR_clone, flags, child_stack, ptid, tls, ctid);
#endif
}

long sys_clone(unsigned long flags) {
  return sys_clone(flags, nullptr, nullptr, nullptr, nullptr);
}

void sys_exit_group(int status) {
  syscall(__NR_exit_group, status);
}

int sys_seccomp(unsigned int operation,
                unsigned int flags,
                const struct sock_fprog* args) {
  return syscall(__NR_seccomp, operation, flags, args);
}

int sys_prlimit64(pid_t pid,
                  int resource,
                  const struct rlimit64* new_limit,
                  struct rlimit64* old_limit) {
  int res = syscall(__NR_prlimit64, pid, resource, new_limit, old_limit);
  if (res == 0 && old_limit) MSAN_UNPOISON(old_limit, sizeof(*old_limit));
  return res;
}

int sys_capget(cap_hdr* hdrp, cap_data* datap) {
  int res = syscall(__NR_capget, hdrp, datap);
  if (res == 0) {
    if (hdrp) MSAN_UNPOISON(hdrp, sizeof(*hdrp));
    if (datap) MSAN_UNPOISON(datap, sizeof(*datap));
  }
  return res;
}

int sys_capset(cap_hdr* hdrp, const cap_data* datap) {
  return syscall(__NR_capset, hdrp, datap);
}

int sys_getresuid(uid_t* ruid, uid_t* euid, uid_t* suid) {
  int res;
#if defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARMEL)
  // On 32-bit x86 or 32-bit arm, getresuid supports 16bit values only.
  // Use getresuid32 instead.
  res = syscall(__NR_getresuid32, ruid, euid, suid);
#else
  res = syscall(__NR_getresuid, ruid, euid, suid);
#endif
  if (res == 0) {
    if (ruid) MSAN_UNPOISON(ruid, sizeof(*ruid));
    if (euid) MSAN_UNPOISON(euid, sizeof(*euid));
    if (suid) MSAN_UNPOISON(suid, sizeof(*suid));
  }
  return res;
}

int sys_getresgid(gid_t* rgid, gid_t* egid, gid_t* sgid) {
  int res;
#if defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARMEL)
  // On 32-bit x86 or 32-bit arm, getresgid supports 16bit values only.
  // Use getresgid32 instead.
  res = syscall(__NR_getresgid32, rgid, egid, sgid);
#else
  res = syscall(__NR_getresgid, rgid, egid, sgid);
#endif
  if (res == 0) {
    if (rgid) MSAN_UNPOISON(rgid, sizeof(*rgid));
    if (egid) MSAN_UNPOISON(egid, sizeof(*egid));
    if (sgid) MSAN_UNPOISON(sgid, sizeof(*sgid));
  }
  return res;
}

int sys_chroot(const char* path) {
  return syscall(__NR_chroot, path);
}

int sys_unshare(int flags) {
  return syscall(__NR_unshare, flags);
}

int sys_sigprocmask(int how, const sigset_t* set, std::nullptr_t oldset) {
  // In some toolchain (in particular Android and PNaCl toolchain),
  // sigset_t is 32 bits, but the Linux ABI uses more.
  LinuxSigSet linux_value;
  std::memset(&linux_value, 0, sizeof(LinuxSigSet));
  std::memcpy(&linux_value, set, std::min(sizeof(sigset_t),
                                          sizeof(LinuxSigSet)));

  return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr,
                 sizeof(linux_value));
}

// When this is built with PNaCl toolchain, we should always use sys_sigaction
// below, because sigaction() provided by the toolchain is incompatible with
// Linux's ABI.
#if !defined(OS_NACL_NONSFI)
int sys_sigaction(int signum,
                  const struct sigaction* act,
                  struct sigaction* oldact) {
  return sigaction(signum, act, oldact);
}
#else
#if defined(ARCH_CPU_X86_FAMILY)

// On x86_64, sa_restorer is required. We specify it on x86 as well in order to
// support kernels with VDSO disabled.
#if !defined(SA_RESTORER)
#define SA_RESTORER 0x04000000
#endif

// XSTR(__NR_foo) expands to a string literal containing the value value of
// __NR_foo.
#define STR(x) #x
#define XSTR(x) STR(x)

// rt_sigreturn is a special system call that interacts with the user land
// stack. Thus, here prologue must not be created, which implies syscall()
// does not work properly, too. Note that rt_sigreturn does not return.
// TODO(rickyz): These assembly functions may still break stack unwinding on
// nonsfi NaCl builds.
#if defined(ARCH_CPU_X86_64)

extern "C" {
  void sys_rt_sigreturn();
}

asm(
    ".text\n"
    "sys_rt_sigreturn:\n"
    "mov $" XSTR(__NR_rt_sigreturn) ", %eax\n"
    "syscall\n");

#elif defined(ARCH_CPU_X86)
extern "C" {
  void sys_sigreturn();
  void sys_rt_sigreturn();
}

asm(
    ".text\n"
    "sys_rt_sigreturn:\n"
    "mov $" XSTR(__NR_rt_sigreturn) ", %eax\n"
    "int $0x80\n"

    "sys_sigreturn:\n"
    "pop %eax\n"
    "mov $" XSTR(__NR_sigreturn) ", %eax\n"
    "int $0x80\n");
#else
#error "Unsupported architecture."
#endif

#undef STR
#undef XSTR

#endif

int sys_sigaction(int signum,
                  const struct sigaction* act,
                  struct sigaction* oldact) {
  LinuxSigAction linux_act = {};
  if (act) {
    linux_act.kernel_handler = act->sa_handler;
    std::memcpy(&linux_act.sa_mask, &act->sa_mask,
                std::min(sizeof(linux_act.sa_mask), sizeof(act->sa_mask)));
    linux_act.sa_flags = act->sa_flags;

#if defined(ARCH_CPU_X86_FAMILY)
    if (!(linux_act.sa_flags & SA_RESTORER)) {
      linux_act.sa_flags |= SA_RESTORER;
#if defined(ARCH_CPU_X86_64)
      linux_act.sa_restorer = sys_rt_sigreturn;
#elif defined(ARCH_CPU_X86)
      linux_act.sa_restorer =
          linux_act.sa_flags & SA_SIGINFO ? sys_rt_sigreturn : sys_sigreturn;
#else
#error "Unsupported architecture."
#endif
    }
#endif
  }

  LinuxSigAction linux_oldact = {};
  int result = syscall(__NR_rt_sigaction, signum, act ? &linux_act : nullptr,
                       oldact ? &linux_oldact : nullptr,
                       sizeof(LinuxSigSet));

  if (result == 0 && oldact) {
    oldact->sa_handler = linux_oldact.kernel_handler;
    sigemptyset(&oldact->sa_mask);
    std::memcpy(&oldact->sa_mask, &linux_oldact.sa_mask,
                std::min(sizeof(linux_act.sa_mask), sizeof(act->sa_mask)));
    oldact->sa_flags = linux_oldact.sa_flags;
  }
  return result;
}

#endif  // defined(MEMORY_SANITIZER)

}  // namespace sandbox
