Home | History | Annotate | Download | only in services
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sandbox/linux/services/syscall_wrappers.h"
      6 
      7 #include <stdint.h>
      8 #include <sys/syscall.h>
      9 #include <sys/types.h>
     10 #include <sys/wait.h>
     11 #include <unistd.h>
     12 #include <cstring>
     13 
     14 #include "base/logging.h"
     15 #include "base/posix/eintr_wrapper.h"
     16 #include "build/build_config.h"
     17 #include "sandbox/linux/system_headers/linux_signal.h"
     18 #include "sandbox/linux/tests/test_utils.h"
     19 #include "sandbox/linux/tests/unit_tests.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "third_party/valgrind/valgrind.h"
     22 
     23 namespace sandbox {
     24 
     25 namespace {
     26 
     27 TEST(SyscallWrappers, BasicSyscalls) {
     28   EXPECT_EQ(getpid(), sys_getpid());
     29 }
     30 
     31 TEST(SyscallWrappers, CloneBasic) {
     32   pid_t child = sys_clone(SIGCHLD);
     33   TestUtils::HandlePostForkReturn(child);
     34   EXPECT_LT(0, child);
     35 }
     36 
     37 TEST(SyscallWrappers, CloneParentSettid) {
     38   pid_t ptid = 0;
     39   pid_t child = sys_clone(CLONE_PARENT_SETTID | SIGCHLD, nullptr, &ptid,
     40                           nullptr, nullptr);
     41   TestUtils::HandlePostForkReturn(child);
     42   EXPECT_LT(0, child);
     43   EXPECT_EQ(child, ptid);
     44 }
     45 
     46 TEST(SyscallWrappers, CloneChildSettid) {
     47   pid_t ctid = 0;
     48   pid_t pid =
     49       sys_clone(CLONE_CHILD_SETTID | SIGCHLD, nullptr, nullptr, &ctid, nullptr);
     50 
     51   const int kSuccessExit = 0;
     52   if (0 == pid) {
     53     // In child.
     54     if (sys_getpid() == ctid)
     55       _exit(kSuccessExit);
     56     _exit(1);
     57   }
     58 
     59   ASSERT_NE(-1, pid);
     60   int status = 0;
     61   ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0)));
     62   ASSERT_TRUE(WIFEXITED(status));
     63   EXPECT_EQ(kSuccessExit, WEXITSTATUS(status));
     64 }
     65 
     66 TEST(SyscallWrappers, GetRESUid) {
     67   uid_t ruid, euid, suid;
     68   uid_t sys_ruid, sys_euid, sys_suid;
     69   ASSERT_EQ(0, getresuid(&ruid, &euid, &suid));
     70   ASSERT_EQ(0, sys_getresuid(&sys_ruid, &sys_euid, &sys_suid));
     71   EXPECT_EQ(ruid, sys_ruid);
     72   EXPECT_EQ(euid, sys_euid);
     73   EXPECT_EQ(suid, sys_suid);
     74 }
     75 
     76 TEST(SyscallWrappers, GetRESGid) {
     77   gid_t rgid, egid, sgid;
     78   gid_t sys_rgid, sys_egid, sys_sgid;
     79   ASSERT_EQ(0, getresgid(&rgid, &egid, &sgid));
     80   ASSERT_EQ(0, sys_getresgid(&sys_rgid, &sys_egid, &sys_sgid));
     81   EXPECT_EQ(rgid, sys_rgid);
     82   EXPECT_EQ(egid, sys_egid);
     83   EXPECT_EQ(sgid, sys_sgid);
     84 }
     85 
     86 TEST(SyscallWrappers, LinuxSigSet) {
     87   sigset_t sigset;
     88   ASSERT_EQ(0, sigemptyset(&sigset));
     89   ASSERT_EQ(0, sigaddset(&sigset, LINUX_SIGSEGV));
     90   ASSERT_EQ(0, sigaddset(&sigset, LINUX_SIGBUS));
     91   uint64_t linux_sigset = 0;
     92   std::memcpy(&linux_sigset, &sigset,
     93               std::min(sizeof(sigset), sizeof(linux_sigset)));
     94   EXPECT_EQ((1ULL << (LINUX_SIGSEGV - 1)) | (1ULL << (LINUX_SIGBUS - 1)),
     95             linux_sigset);
     96 }
     97 
     98 }  // namespace
     99 
    100 }  // namespace sandbox
    101