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.
5 #include "sandbox/linux/services/namespace_sandbox.h"
14 #include "base/command_line.h"
15 #include "base/files/file_enumerator.h"
16 #include "base/files/file_path.h"
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/process/launch.h"
20 #include "base/process/process.h"
21 #include "base/test/multiprocess_test.h"
22 #include "sandbox/linux/services/credentials.h"
23 #include "sandbox/linux/services/namespace_utils.h"
24 #include "sandbox/linux/services/proc_util.h"
25 #include "sandbox/linux/tests/unit_tests.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "testing/multiprocess_func_list.h"
33 bool RootDirectoryIsEmpty() {
34 base::FilePath
root("/");
36 base::FileEnumerator::DIRECTORIES
| base::FileEnumerator::FILES
;
37 base::FileEnumerator
enumerator_before(root
, false, file_type
);
38 return enumerator_before
.Next().empty();
41 class NamespaceSandboxTest
: public base::MultiProcessTest
{
43 void TestProc(const std::string
& procname
) {
44 if (!Credentials::CanCreateProcessInNewUserNS()) {
48 base::FileHandleMappingVector fds_to_remap
= {
49 std::make_pair(STDOUT_FILENO
, STDOUT_FILENO
),
50 std::make_pair(STDERR_FILENO
, STDERR_FILENO
),
52 base::LaunchOptions launch_options
;
53 launch_options
.fds_to_remap
= &fds_to_remap
;
55 base::Process process
=
56 NamespaceSandbox::LaunchProcess(MakeCmdLine(procname
), launch_options
);
57 ASSERT_TRUE(process
.IsValid());
59 const int kDummyExitCode
= 42;
60 int exit_code
= kDummyExitCode
;
61 EXPECT_TRUE(process
.WaitForExit(&exit_code
));
62 EXPECT_EQ(0, exit_code
);
66 MULTIPROCESS_TEST_MAIN(SimpleChildProcess
) {
67 scoped_ptr
<base::Environment
> env(base::Environment::Create());
68 bool in_user_ns
= NamespaceSandbox::InNewUserNamespace();
69 bool in_pid_ns
= NamespaceSandbox::InNewPidNamespace();
70 bool in_net_ns
= NamespaceSandbox::InNewNetNamespace();
73 NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWPID
));
75 NamespaceUtils::KernelSupportsUnprivilegedNamespace(CLONE_NEWNET
));
77 CHECK_EQ(1, getpid());
82 TEST_F(NamespaceSandboxTest
, BasicUsage
) {
83 TestProc("SimpleChildProcess");
86 MULTIPROCESS_TEST_MAIN(ChrootMe
) {
87 CHECK(!RootDirectoryIsEmpty());
88 CHECK(sandbox::Credentials::MoveToNewUserNS());
89 CHECK(sandbox::Credentials::DropFileSystemAccess(ProcUtil::OpenProc().get()));
90 CHECK(RootDirectoryIsEmpty());
94 // Temporarily disabled on ASAN due to crbug.com/451603.
95 TEST_F(NamespaceSandboxTest
, DISABLE_ON_ASAN(ChrootAndDropCapabilities
)) {
99 MULTIPROCESS_TEST_MAIN(NestedNamespaceSandbox
) {
100 base::FileHandleMappingVector fds_to_remap
= {
101 std::make_pair(STDOUT_FILENO
, STDOUT_FILENO
),
102 std::make_pair(STDERR_FILENO
, STDERR_FILENO
),
104 base::LaunchOptions launch_options
;
105 launch_options
.fds_to_remap
= &fds_to_remap
;
106 base::Process process
= NamespaceSandbox::LaunchProcess(
107 base::CommandLine(base::FilePath("/bin/true")), launch_options
);
108 CHECK(process
.IsValid());
110 const int kDummyExitCode
= 42;
111 int exit_code
= kDummyExitCode
;
112 CHECK(process
.WaitForExit(&exit_code
));
113 CHECK_EQ(0, exit_code
);
117 TEST_F(NamespaceSandboxTest
, NestedNamespaceSandbox
) {
118 TestProc("NestedNamespaceSandbox");
123 } // namespace sandbox