1 // Copyright 2020 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 <linux/futex.h>
16 #include <syscall.h>
17 #include <uv.h>
18
19 #include "gtest/gtest.h"
20 #include "absl/flags/flag.h"
21 #include "sandboxed_api/util/status_matchers.h"
22 #include "uv_sapi.sapi.h" // NOLINT(build/include)
23
24 namespace {
25
26 class UVTestOSSapiSandbox : public uv::UVSandbox {
27 private:
ModifyPolicy(sandbox2::PolicyBuilder *)28 std::unique_ptr<sandbox2::Policy> ModifyPolicy(
29 sandbox2::PolicyBuilder*) override {
30 return sandbox2::PolicyBuilder()
31 .AllowDynamicStartup()
32 .AllowExit()
33 .AllowFutexOp(FUTEX_WAKE_PRIVATE)
34 .AllowGetIDs()
35 .AllowMmapWithoutExec()
36 .AllowOpen()
37 .AllowWrite()
38 .AllowSyscalls({__NR_connect, __NR_socket})
39 .DisableNamespaces()
40 .BuildOrDie();
41 }
42 };
43
44 class UVTestOS : public ::testing::Test {
45 protected:
SetUp()46 void SetUp() override {
47 sandbox_ = std::make_unique<UVTestOSSapiSandbox>();
48 ASSERT_THAT(sandbox_->Init(), sapi::IsOk());
49 api_ = std::make_unique<uv::UVApi>(sandbox_.get());
50 }
51
52 std::unique_ptr<UVTestOSSapiSandbox> sandbox_;
53 std::unique_ptr<uv::UVApi> api_;
54
55 static constexpr size_t kBigBufLen = 4096;
56 static constexpr size_t kSmallBufLen = 1;
57 };
58
TEST_F(UVTestOS,HomeDirBig)59 TEST_F(UVTestOS, HomeDirBig) {
60 // Get expected home directory
61 char expected_homedir[kBigBufLen];
62 size_t len = sizeof(expected_homedir);
63 ASSERT_GE(uv_os_homedir(expected_homedir, &len), 0);
64
65 // Get home directory from the sandbox
66 sapi::v::Array<char> uv_homedir(kBigBufLen);
67 uv_homedir[0] = '\0';
68 sapi::v::IntBase<size_t> uv_homedir_len(kBigBufLen);
69 SAPI_ASSERT_OK_AND_ASSIGN(
70 int error_code,
71 api_->sapi_uv_os_homedir(uv_homedir.PtrBoth(), uv_homedir_len.PtrBoth()));
72 ASSERT_GE(error_code, 0);
73
74 // Test home directory is as expected
75 ASSERT_EQ(std::string{uv_homedir.GetData()}, std::string{expected_homedir});
76 }
77
TEST_F(UVTestOS,HomeDirSmall)78 TEST_F(UVTestOS, HomeDirSmall) {
79 // Try getting expected home directory, error because array is too small
80 char expected_homedir[kSmallBufLen];
81 size_t len = sizeof(expected_homedir);
82 int expected_error_code = uv_os_homedir(expected_homedir, &len);
83 ASSERT_NE(expected_error_code, 0);
84
85 // Try getting home directory from sandbox, error because array is too small
86 sapi::v::Array<char> uv_homedir(kSmallBufLen);
87 uv_homedir[0] = '\0';
88 sapi::v::IntBase<size_t> uv_homedir_len(kSmallBufLen);
89 SAPI_ASSERT_OK_AND_ASSIGN(
90 int error_code,
91 api_->sapi_uv_os_homedir(uv_homedir.PtrBoth(), uv_homedir_len.PtrBoth()));
92 ASSERT_NE(error_code, 0);
93
94 // Test error code is as expected
95 ASSERT_EQ(error_code, expected_error_code);
96 }
97
TEST_F(UVTestOS,TmpDirBig)98 TEST_F(UVTestOS, TmpDirBig) {
99 // Get expected tmp directory
100 char expected_tmpdir[kBigBufLen];
101 size_t len = sizeof(expected_tmpdir);
102 ASSERT_GE(uv_os_tmpdir(expected_tmpdir, &len), 0);
103
104 // Get tmp directory from the sandbox
105 sapi::v::Array<char> uv_tmpdir(kBigBufLen);
106 uv_tmpdir[0] = '\0';
107 sapi::v::IntBase<size_t> uv_tmpdir_len(kBigBufLen);
108 SAPI_ASSERT_OK_AND_ASSIGN(
109 int error_code,
110 api_->sapi_uv_os_tmpdir(uv_tmpdir.PtrBoth(), uv_tmpdir_len.PtrBoth()));
111 ASSERT_GE(error_code, 0);
112
113 // Test tmp directory is as expected
114 ASSERT_EQ(std::string{uv_tmpdir.GetData()}, std::string{expected_tmpdir});
115 }
116
TEST_F(UVTestOS,TmpDirSmall)117 TEST_F(UVTestOS, TmpDirSmall) {
118 // Try getting expected tmp directory, error because array is too small
119 char expected_tmpdir[kSmallBufLen];
120 size_t len = sizeof(expected_tmpdir);
121 int expected_error_code = uv_os_tmpdir(expected_tmpdir, &len);
122 ASSERT_NE(expected_error_code, 0);
123
124 // Try getting tmp directory from sandbox, error because array is too small
125 sapi::v::Array<char> uv_tmpdir(kSmallBufLen);
126 uv_tmpdir[0] = '\0';
127 sapi::v::IntBase<size_t> uv_tmpdir_len(kSmallBufLen);
128 SAPI_ASSERT_OK_AND_ASSIGN(
129 int error_code,
130 api_->sapi_uv_os_tmpdir(uv_tmpdir.PtrBoth(), uv_tmpdir_len.PtrBoth()));
131 ASSERT_NE(error_code, 0);
132
133 // Test error code is as expected
134 ASSERT_EQ(error_code, expected_error_code);
135 }
136
137 } // namespace
138