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/limits.h"
16
17 #include <csignal>
18 #include <memory>
19 #include <string>
20 #include <utility>
21 #include <vector>
22
23 #include "gtest/gtest.h"
24 #include "sandboxed_api/sandbox2/executor.h"
25 #include "sandboxed_api/sandbox2/result.h"
26 #include "sandboxed_api/sandbox2/sandbox2.h"
27 #include "sandboxed_api/testing.h"
28 #include "sandboxed_api/util/status_matchers.h"
29
30 namespace sandbox2 {
31 namespace {
32
33 using ::sapi::CreateDefaultPermissiveTestPolicy;
34 using ::sapi::GetTestSourcePath;
35
GetLimitsTestcaseBinPath()36 std::string GetLimitsTestcaseBinPath() {
37 return GetTestSourcePath("sandbox2/testcases/limits");
38 }
39
TEST(LimitsTest,RLimitASMmapUnderLimit)40 TEST(LimitsTest, RLimitASMmapUnderLimit) {
41 SKIP_SANITIZERS;
42 const std::string path = GetLimitsTestcaseBinPath();
43 std::vector<std::string> args = {path, "1"}; // mmap(1 MiB)
44 auto executor = std::make_unique<sandbox2::Executor>(path, args);
45 executor->limits()->set_rlimit_as(100ULL << 20); // 100 MiB
46
47 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
48 CreateDefaultPermissiveTestPolicy(path).TryBuild());
49 sandbox2::Sandbox2 s2(std::move(executor), std::move(policy));
50 auto result = s2.Run();
51
52 ASSERT_EQ(result.final_status(), sandbox2::Result::OK);
53 EXPECT_EQ(result.reason_code(), 0);
54 }
55
TEST(LimitsTest,RLimitASMmapAboveLimit)56 TEST(LimitsTest, RLimitASMmapAboveLimit) {
57 SKIP_SANITIZERS;
58 const std::string path = GetLimitsTestcaseBinPath();
59 std::vector<std::string> args = {path, "2"}; // mmap(100 MiB)
60 auto executor = std::make_unique<sandbox2::Executor>(path, args);
61 executor->limits()->set_rlimit_as(100ULL << 20); // 100 MiB
62
63 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
64 CreateDefaultPermissiveTestPolicy(path).TryBuild());
65 sandbox2::Sandbox2 s2(std::move(executor), std::move(policy));
66 auto result = s2.Run();
67
68 ASSERT_EQ(result.final_status(), sandbox2::Result::OK);
69 EXPECT_EQ(result.reason_code(), 0);
70 }
71
TEST(LimitsTest,RLimitASAllocaSmallUnderLimit)72 TEST(LimitsTest, RLimitASAllocaSmallUnderLimit) {
73 SKIP_SANITIZERS;
74 const std::string path = GetLimitsTestcaseBinPath();
75 std::vector<std::string> args = {path, "3"}; // alloca(1 MiB)
76 auto executor = std::make_unique<sandbox2::Executor>(path, args);
77 executor->limits()->set_rlimit_as(100ULL << 20); // 100 MiB
78
79 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
80 CreateDefaultPermissiveTestPolicy(path).TryBuild());
81 sandbox2::Sandbox2 s2(std::move(executor), std::move(policy));
82 auto result = s2.Run();
83
84 ASSERT_EQ(result.final_status(), sandbox2::Result::OK);
85 EXPECT_EQ(result.reason_code(), 0);
86 }
87
TEST(LimitsTest,RLimitASAllocaBigUnderLimit)88 TEST(LimitsTest, RLimitASAllocaBigUnderLimit) {
89 SKIP_SANITIZERS;
90 const std::string path = GetLimitsTestcaseBinPath();
91 std::vector<std::string> args = {path, "4"}; // alloca(8 MiB)
92 auto executor = std::make_unique<sandbox2::Executor>(path, args);
93 executor->limits()->set_rlimit_as(100ULL << 20); // 100 MiB
94
95 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
96 CreateDefaultPermissiveTestPolicy(path).TryBuild());
97 sandbox2::Sandbox2 s2(std::move(executor), std::move(policy));
98 auto result = s2.Run();
99
100 ASSERT_EQ(result.final_status(), sandbox2::Result::SIGNALED);
101 EXPECT_EQ(result.reason_code(), SIGSEGV);
102 }
103
TEST(LimitsTest,RLimitASAllocaBigAboveLimit)104 TEST(LimitsTest, RLimitASAllocaBigAboveLimit) {
105 SKIP_SANITIZERS;
106 const std::string path = GetLimitsTestcaseBinPath();
107 std::vector<std::string> args = {path, "5"}; // alloca(100 MiB)
108 auto executor = std::make_unique<sandbox2::Executor>(path, args);
109 executor->limits()->set_rlimit_as(100ULL << 20); // 100 MiB
110
111 SAPI_ASSERT_OK_AND_ASSIGN(auto policy,
112 CreateDefaultPermissiveTestPolicy(path).TryBuild());
113 sandbox2::Sandbox2 s2(std::move(executor), std::move(policy));
114 auto result = s2.Run();
115
116 ASSERT_EQ(result.final_status(), sandbox2::Result::SIGNALED);
117 EXPECT_EQ(result.reason_code(), SIGSEGV);
118 }
119
120 } // namespace
121 } // namespace sandbox2
122