Home | History | Annotate | Download | only in services
      1 // Copyright 2015 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/namespace_utils.h"
      6 
      7 #include <errno.h>
      8 #include <sched.h>
      9 #include <sys/types.h>
     10 #include <sys/wait.h>
     11 
     12 #include "base/logging.h"
     13 #include "base/posix/eintr_wrapper.h"
     14 #include "base/process/launch.h"
     15 #include "sandbox/linux/services/credentials.h"
     16 #include "sandbox/linux/tests/unit_tests.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace sandbox {
     20 
     21 namespace {
     22 
     23 SANDBOX_TEST(NamespaceUtils, KernelSupportsUnprivilegedNamespace) {
     24   const bool can_create_user_ns = Credentials::CanCreateProcessInNewUserNS();
     25   const bool supports_user_ns =
     26       NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWUSER);
     27   // can_create_user_ns implies supports_user_ns, but the converse is not
     28   // necessarily true, as creating a user namespace can fail for various
     29   // reasons.
     30   if (can_create_user_ns) {
     31     SANDBOX_ASSERT(supports_user_ns);
     32   }
     33 }
     34 
     35 SANDBOX_TEST(NamespaceUtils, WriteToIdMapFile) {
     36   if (!Credentials::CanCreateProcessInNewUserNS()) {
     37     return;
     38   }
     39 
     40   const uid_t uid = getuid();
     41   const gid_t gid = getgid();
     42 
     43   const bool supports_deny_setgroups =
     44       NamespaceUtils::KernelSupportsDenySetgroups();
     45 
     46   const pid_t pid =
     47       base::ForkWithFlags(CLONE_NEWUSER | SIGCHLD, nullptr, nullptr);
     48   ASSERT_NE(-1, pid);
     49   if (pid == 0) {
     50     if (supports_deny_setgroups) {
     51       RAW_CHECK(NamespaceUtils::DenySetgroups());
     52     }
     53 
     54     RAW_CHECK(getuid() != uid);
     55     RAW_CHECK(NamespaceUtils::WriteToIdMapFile("/proc/self/uid_map", uid));
     56     RAW_CHECK(getuid() == uid);
     57 
     58     RAW_CHECK(getgid() != gid);
     59     RAW_CHECK(NamespaceUtils::WriteToIdMapFile("/proc/self/gid_map", gid));
     60     RAW_CHECK(getgid() == gid);
     61 
     62     _exit(0);
     63   }
     64 
     65   int status = 42;
     66   SANDBOX_ASSERT_EQ(pid, HANDLE_EINTR(waitpid(pid, &status, 0)));
     67   SANDBOX_ASSERT_EQ(0, status);
     68 }
     69 
     70 }  // namespace.
     71 
     72 }  // namespace sandbox.
     73