xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/util_test.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2019 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li #include "sandboxed_api/sandbox2/util.h"
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <sched.h>
18*ec63e07aSXin Li #include <sys/mman.h>
19*ec63e07aSXin Li #include <sys/wait.h>
20*ec63e07aSXin Li #include <unistd.h>
21*ec63e07aSXin Li 
22*ec63e07aSXin Li #include <cstdint>
23*ec63e07aSXin Li #include <cstdlib>
24*ec63e07aSXin Li #include <cstring>
25*ec63e07aSXin Li #include <string>
26*ec63e07aSXin Li #include <vector>
27*ec63e07aSXin Li 
28*ec63e07aSXin Li #include "gmock/gmock.h"
29*ec63e07aSXin Li #include "gtest/gtest.h"
30*ec63e07aSXin Li #include "absl/cleanup/cleanup.h"
31*ec63e07aSXin Li #include "absl/status/statusor.h"
32*ec63e07aSXin Li #include "absl/strings/str_cat.h"
33*ec63e07aSXin Li #include "absl/strings/string_view.h"
34*ec63e07aSXin Li #include "sandboxed_api/util/status_matchers.h"
35*ec63e07aSXin Li 
36*ec63e07aSXin Li namespace sandbox2::util {
37*ec63e07aSXin Li namespace {
38*ec63e07aSXin Li 
39*ec63e07aSXin Li using ::sapi::IsOk;
40*ec63e07aSXin Li using ::testing::ElementsAre;
41*ec63e07aSXin Li using ::testing::Eq;
42*ec63e07aSXin Li using ::testing::Gt;
43*ec63e07aSXin Li using ::testing::IsEmpty;
44*ec63e07aSXin Li using ::testing::IsTrue;
45*ec63e07aSXin Li using ::testing::Ne;
46*ec63e07aSXin Li using ::testing::Not;
47*ec63e07aSXin Li using ::testing::StrEq;
48*ec63e07aSXin Li 
49*ec63e07aSXin Li constexpr absl::string_view kTestString = "This is a test string";
50*ec63e07aSXin Li 
TEST(UtilTest,TestCreateMemFd)51*ec63e07aSXin Li TEST(UtilTest, TestCreateMemFd) {
52*ec63e07aSXin Li   int fd = 0;
53*ec63e07aSXin Li   ASSERT_THAT(CreateMemFd(&fd), IsTrue());
54*ec63e07aSXin Li   EXPECT_THAT(fd, Gt(1));
55*ec63e07aSXin Li   close(fd);
56*ec63e07aSXin Li }
57*ec63e07aSXin Li 
TEST(CharPtrArrayTest,FromStringVector)58*ec63e07aSXin Li TEST(CharPtrArrayTest, FromStringVector) {
59*ec63e07aSXin Li   std::vector<std::string> strings = {"a", "b", "c"};
60*ec63e07aSXin Li   CharPtrArray array = CharPtrArray::FromStringVector(strings);
61*ec63e07aSXin Li   EXPECT_THAT(array.ToStringVector(), Eq(strings));
62*ec63e07aSXin Li   EXPECT_THAT(array.array(),
63*ec63e07aSXin Li               ElementsAre(StrEq("a"), StrEq("b"), StrEq("c"), nullptr));
64*ec63e07aSXin Li   EXPECT_THAT(array.data(), Eq(array.array().data()));
65*ec63e07aSXin Li }
66*ec63e07aSXin Li 
TEST(CharPtrArrayTest,FromCharPtrArray)67*ec63e07aSXin Li TEST(CharPtrArrayTest, FromCharPtrArray) {
68*ec63e07aSXin Li   std::vector<std::string> strings = {"a", "b", "c"};
69*ec63e07aSXin Li   std::vector<char*> string_arr;
70*ec63e07aSXin Li   for (std::string& s : strings) {
71*ec63e07aSXin Li     string_arr.push_back(s.data());
72*ec63e07aSXin Li   }
73*ec63e07aSXin Li   string_arr.push_back(nullptr);
74*ec63e07aSXin Li   CharPtrArray array(string_arr.data());
75*ec63e07aSXin Li   EXPECT_THAT(array.ToStringVector(), Eq(strings));
76*ec63e07aSXin Li   EXPECT_THAT(array.array(),
77*ec63e07aSXin Li               ElementsAre(StrEq("a"), StrEq("b"), StrEq("c"), nullptr));
78*ec63e07aSXin Li   EXPECT_THAT(array.data(), Eq(array.array().data()));
79*ec63e07aSXin Li }
80*ec63e07aSXin Li 
TEST(GetProcStatusLineTest,Pid)81*ec63e07aSXin Li TEST(GetProcStatusLineTest, Pid) {
82*ec63e07aSXin Li   std::string line = GetProcStatusLine(getpid(), "Pid");
83*ec63e07aSXin Li   EXPECT_THAT(line, Eq(absl::StrCat(getpid())));
84*ec63e07aSXin Li }
85*ec63e07aSXin Li 
TEST(GetProcStatusLineTest,NonExisting)86*ec63e07aSXin Li TEST(GetProcStatusLineTest, NonExisting) {
87*ec63e07aSXin Li   std::string line =
88*ec63e07aSXin Li       GetProcStatusLine(getpid(), "__N_o_n_ExistingStatusSetting");
89*ec63e07aSXin Li   EXPECT_THAT(line, IsEmpty());
90*ec63e07aSXin Li }
91*ec63e07aSXin Li 
TEST(ForkWithFlagsTest,DoesForkNormally)92*ec63e07aSXin Li TEST(ForkWithFlagsTest, DoesForkNormally) {
93*ec63e07aSXin Li   int pfds[2];
94*ec63e07aSXin Li   ASSERT_THAT(pipe(pfds), Eq(0));
95*ec63e07aSXin Li   pid_t child = ForkWithFlags(SIGCHLD);
96*ec63e07aSXin Li   ASSERT_THAT(child, Ne(-1));
97*ec63e07aSXin Li   if (child == 0) {
98*ec63e07aSXin Li     char c = 'a';
99*ec63e07aSXin Li     if (!write(pfds[1], &c, 1)) {
100*ec63e07aSXin Li       exit(EXIT_FAILURE);
101*ec63e07aSXin Li     }
102*ec63e07aSXin Li     exit(EXIT_SUCCESS);
103*ec63e07aSXin Li   }
104*ec63e07aSXin Li   close(pfds[1]);
105*ec63e07aSXin Li   char c = ' ';
106*ec63e07aSXin Li   EXPECT_THAT(read(pfds[0], &c, 1), Eq(1));
107*ec63e07aSXin Li   close(pfds[0]);
108*ec63e07aSXin Li   EXPECT_THAT(c, Eq('a'));
109*ec63e07aSXin Li   int status;
110*ec63e07aSXin Li   ASSERT_THAT(TEMP_FAILURE_RETRY(waitpid(child, &status, 0)), Eq(child));
111*ec63e07aSXin Li   EXPECT_TRUE(WIFEXITED(status));
112*ec63e07aSXin Li   EXPECT_THAT(WEXITSTATUS(status), Eq(0));
113*ec63e07aSXin Li }
114*ec63e07aSXin Li 
TEST(ForkWithFlagsTest,UnsupportedFlag)115*ec63e07aSXin Li TEST(ForkWithFlagsTest, UnsupportedFlag) {
116*ec63e07aSXin Li   EXPECT_THAT(ForkWithFlags(CLONE_CHILD_CLEARTID), Eq(-1));
117*ec63e07aSXin Li }
118*ec63e07aSXin Li 
TEST(ReadCPathFromPidSplitPageTest,Normal)119*ec63e07aSXin Li TEST(ReadCPathFromPidSplitPageTest, Normal) {
120*ec63e07aSXin Li   std::string test_str(kTestString);
121*ec63e07aSXin Li   absl::StatusOr<std::string> read =
122*ec63e07aSXin Li       ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(test_str.data()));
123*ec63e07aSXin Li   ASSERT_THAT(read, IsOk());
124*ec63e07aSXin Li   EXPECT_THAT(*read, Eq(kTestString));
125*ec63e07aSXin Li }
126*ec63e07aSXin Li 
TEST(ReadCPathFromPidSplitPageTest,Overlong)127*ec63e07aSXin Li TEST(ReadCPathFromPidSplitPageTest, Overlong) {
128*ec63e07aSXin Li   std::string test_str(PATH_MAX + 1, 'a');
129*ec63e07aSXin Li   absl::StatusOr<std::string> read =
130*ec63e07aSXin Li       ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(test_str.data()));
131*ec63e07aSXin Li   EXPECT_THAT(read, Not(IsOk()));
132*ec63e07aSXin Li }
133*ec63e07aSXin Li 
TEST(ReadCPathFromPidSplitPageTest,SplitPage)134*ec63e07aSXin Li TEST(ReadCPathFromPidSplitPageTest, SplitPage) {
135*ec63e07aSXin Li   const uintptr_t page_size = getpagesize();
136*ec63e07aSXin Li   char* res = reinterpret_cast<char*>(mmap(nullptr, 2 * page_size,
137*ec63e07aSXin Li                                            PROT_READ | PROT_WRITE,
138*ec63e07aSXin Li                                            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0));
139*ec63e07aSXin Li   ASSERT_THAT(res, Ne(MAP_FAILED));
140*ec63e07aSXin Li   absl::Cleanup cleanup = [res, page_size]() {
141*ec63e07aSXin Li     ASSERT_THAT(munmap(res, 2 * page_size), Eq(0));
142*ec63e07aSXin Li   };
143*ec63e07aSXin Li   char* str = &res[page_size - kTestString.size() / 2];
144*ec63e07aSXin Li   memcpy(str, kTestString.data(), kTestString.size());
145*ec63e07aSXin Li   absl::StatusOr<std::string> read =
146*ec63e07aSXin Li       ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(str));
147*ec63e07aSXin Li   ASSERT_THAT(read, IsOk());
148*ec63e07aSXin Li   EXPECT_THAT(*read, Eq(kTestString));
149*ec63e07aSXin Li }
150*ec63e07aSXin Li 
TEST(ReadCPathFromPidSplitPageTest,NearUnreadableMemory)151*ec63e07aSXin Li TEST(ReadCPathFromPidSplitPageTest, NearUnreadableMemory) {
152*ec63e07aSXin Li   const uintptr_t page_size = getpagesize();
153*ec63e07aSXin Li   char* res = reinterpret_cast<char*>(mmap(nullptr, 2 * page_size,
154*ec63e07aSXin Li                                            PROT_READ | PROT_WRITE,
155*ec63e07aSXin Li                                            MAP_ANONYMOUS | MAP_PRIVATE, 0, 0));
156*ec63e07aSXin Li   ASSERT_THAT(res, Ne(MAP_FAILED));
157*ec63e07aSXin Li   absl::Cleanup cleanup = [res, page_size]() {
158*ec63e07aSXin Li     ASSERT_THAT(munmap(res, 2 * page_size), Eq(0));
159*ec63e07aSXin Li   };
160*ec63e07aSXin Li   ASSERT_THAT(mprotect(&res[page_size], page_size, PROT_NONE), Eq(0));
161*ec63e07aSXin Li   char* str = &res[page_size - kTestString.size() - 1];
162*ec63e07aSXin Li   memcpy(str, kTestString.data(), kTestString.size());
163*ec63e07aSXin Li   absl::StatusOr<std::string> read =
164*ec63e07aSXin Li       ReadCPathFromPid(getpid(), reinterpret_cast<uintptr_t>(str));
165*ec63e07aSXin Li   ASSERT_THAT(read, IsOk());
166*ec63e07aSXin Li   EXPECT_THAT(*read, Eq(kTestString));
167*ec63e07aSXin Li }
168*ec63e07aSXin Li 
169*ec63e07aSXin Li }  // namespace
170*ec63e07aSXin Li }  // namespace sandbox2::util
171