1 // Copyright 2019 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "sandboxed_api/sandbox2/ipc.h"
16
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 #include "gtest/gtest.h"
23 #include "sandboxed_api/sandbox2/comms.h"
24 #include "sandboxed_api/sandbox2/executor.h"
25 #include "sandboxed_api/sandbox2/policy.h"
26 #include "sandboxed_api/sandbox2/result.h"
27 #include "sandboxed_api/sandbox2/sandbox2.h"
28 #include "sandboxed_api/testing.h"
29 #include "sandboxed_api/util/status_matchers.h"
30
31 namespace sandbox2 {
32 namespace {
33
34 using ::sapi::CreateDefaultPermissiveTestPolicy;
35 using ::sapi::GetTestSourcePath;
36
37 constexpr int kPreferredIpcFd = 812;
38
39 class IPCTest : public testing::Test,
40 public testing::WithParamInterface<int> {};
41
42 // This test verifies that mapping fds by name works if the sandbox is enabled
43 // before execve.
TEST_P(IPCTest,MapFDByNamePreExecve)44 TEST_P(IPCTest, MapFDByNamePreExecve) {
45 const int fd = GetParam();
46 const std::string path = GetTestSourcePath("sandbox2/testcases/ipc");
47 std::vector<std::string> args = {path, "1", std::to_string(fd)};
48 auto executor = std::make_unique<Executor>(path, args);
49 Comms comms(executor->ipc()->ReceiveFd(fd, "ipc_test"));
50
51 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
52 CreateDefaultPermissiveTestPolicy(path).TryBuild());
53
54 Sandbox2 s2(std::move(executor), std::move(policy));
55 s2.RunAsync();
56
57 ASSERT_TRUE(comms.SendString("hello"));
58 std::string resp;
59 ASSERT_TRUE(s2.comms()->RecvString(&resp));
60 ASSERT_EQ(resp, "start");
61 ASSERT_TRUE(s2.comms()->SendString("started"));
62 ASSERT_TRUE(comms.RecvString(&resp));
63 ASSERT_EQ(resp, "world");
64 ASSERT_TRUE(s2.comms()->RecvString(&resp));
65 ASSERT_EQ(resp, "finish");
66 ASSERT_TRUE(s2.comms()->SendString("finished"));
67
68 auto result = s2.AwaitResult();
69
70 ASSERT_EQ(result.final_status(), Result::OK);
71 ASSERT_EQ(result.reason_code(), 0);
72 }
73
74 // This test verifies that mapping fds by name works if SandboxMeHere() is
75 // called by the sandboxee.
TEST_P(IPCTest,MapFDByNamePostExecve)76 TEST_P(IPCTest, MapFDByNamePostExecve) {
77 const int fd = GetParam();
78 const std::string path = GetTestSourcePath("sandbox2/testcases/ipc");
79 std::vector<std::string> args = {path, "2", std::to_string(fd)};
80 auto executor = std::make_unique<Executor>(path, args);
81 executor->set_enable_sandbox_before_exec(false);
82 Comms comms(executor->ipc()->ReceiveFd(fd, "ipc_test"));
83
84 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
85 CreateDefaultPermissiveTestPolicy(path).TryBuild());
86
87 Sandbox2 s2(std::move(executor), std::move(policy));
88 s2.RunAsync();
89
90 ASSERT_TRUE(comms.SendString("hello"));
91 std::string resp;
92 ASSERT_TRUE(s2.comms()->RecvString(&resp));
93 ASSERT_EQ(resp, "start");
94 ASSERT_TRUE(s2.comms()->SendString("started"));
95 ASSERT_TRUE(comms.RecvString(&resp));
96 ASSERT_EQ(resp, "world");
97 ASSERT_TRUE(s2.comms()->RecvString(&resp));
98 ASSERT_EQ(resp, "finish");
99 ASSERT_TRUE(s2.comms()->SendString("finished"));
100
101 auto result = s2.AwaitResult();
102
103 ASSERT_EQ(result.final_status(), Result::OK);
104 ASSERT_EQ(result.reason_code(), 0);
105 }
106
TEST(IPCTest,NoMappedFDsPreExecve)107 TEST(IPCTest, NoMappedFDsPreExecve) {
108 const std::string path = GetTestSourcePath("sandbox2/testcases/ipc");
109 std::vector<std::string> args = {path, "3"};
110 auto executor = std::make_unique<Executor>(path, args);
111
112 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
113 CreateDefaultPermissiveTestPolicy(path).TryBuild());
114
115 Sandbox2 s2(std::move(executor), std::move(policy));
116 auto result = s2.Run();
117
118 ASSERT_EQ(result.final_status(), Result::OK);
119 ASSERT_EQ(result.reason_code(), 0);
120 }
121
122 INSTANTIATE_TEST_SUITE_P(NormalFds, IPCTest, testing::Values(kPreferredIpcFd));
123
124 INSTANTIATE_TEST_SUITE_P(RestrictedFds, IPCTest,
125 testing::Values(Comms::kSandbox2ClientCommsFD,
126 Comms::kSandbox2TargetExecFD));
127
128 } // namespace
129 } // namespace sandbox2
130