xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/comms_test.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 //
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     https://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // Unittest for the sandbox2::Comms class.
15 
16 #include "sandboxed_api/sandbox2/comms.h"
17 
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include <cstdint>
24 #include <cstring>
25 #include <functional>
26 #include <memory>
27 #include <string>
28 #include <thread>  // NOLINT(build/c++11)
29 #include <vector>
30 
31 #include "gmock/gmock.h"
32 #include "gtest/gtest.h"
33 #include "absl/container/fixed_array.h"
34 #include "absl/log/check.h"
35 #include "absl/log/log.h"
36 #include "absl/status/status.h"
37 #include "absl/strings/string_view.h"
38 #include "sandboxed_api/sandbox2/comms_test.pb.h"
39 #include "sandboxed_api/util/status_matchers.h"
40 
41 using ::sapi::IsOk;
42 using ::sapi::StatusIs;
43 using ::testing::Eq;
44 using ::testing::IsFalse;
45 using ::testing::IsTrue;
46 
47 namespace sandbox2 {
48 
49 using CommunicationHandler = std::function<void(Comms* comms)>;
50 
51 constexpr char kProtoStr[] = "ABCD";
NullTestString()52 static absl::string_view NullTestString() {
53   static constexpr char kHelperStr[] = "test\0\n\r\t\x01\x02";
54   return absl::string_view(kHelperStr, sizeof(kHelperStr) - 1);
55 }
56 
57 // Helper function that handles the communication between the two handler
58 // functions.
HandleCommunication(const CommunicationHandler & a,const CommunicationHandler & b)59 void HandleCommunication(const CommunicationHandler& a,
60                          const CommunicationHandler& b) {
61   int sv[2];
62   CHECK_NE(socketpair(AF_UNIX, SOCK_STREAM, 0, sv), -1);
63   Comms comms(sv[0]);
64 
65   // Start handler a.
66   std::thread remote([sv, &a]() {
67     Comms my_comms(sv[1]);
68     a(&my_comms);
69   });
70 
71   // Accept connection and run handler b.
72   b(&comms);
73   remote.join();
74 }
75 
TEST(CommsTest,TestSendRecv8)76 TEST(CommsTest, TestSendRecv8) {
77   auto a = [](Comms* comms) {
78     // Send Uint8.
79     ASSERT_THAT(comms->SendUint8(192), IsTrue());
80 
81     // Recv Int8.
82     int8_t tmp8;
83     ASSERT_THAT(comms->RecvInt8(&tmp8), IsTrue());
84     EXPECT_THAT(tmp8, Eq(-7));
85   };
86   auto b = [](Comms* comms) {
87     // Recv Uint8.
88     uint8_t tmpu8;
89     ASSERT_THAT(comms->RecvUint8(&tmpu8), IsTrue());
90     EXPECT_THAT(tmpu8, Eq(192));
91 
92     // Send Int8.
93     ASSERT_THAT(comms->SendInt8(-7), IsTrue());
94   };
95   HandleCommunication(a, b);
96 }
97 
TEST(CommsTest,TestSendRecv16)98 TEST(CommsTest, TestSendRecv16) {
99   auto a = [](Comms* comms) {
100     // Send Uint16.
101     ASSERT_THAT(comms->SendUint16(40001), IsTrue());
102 
103     // Recv Int16.
104     int16_t tmp16;
105     ASSERT_THAT(comms->RecvInt16(&tmp16), IsTrue());
106     EXPECT_THAT(tmp16, Eq(-22050));
107   };
108   auto b = [](Comms* comms) {
109     // Recv Uint16.
110     uint16_t tmpu16;
111     ASSERT_THAT(comms->RecvUint16(&tmpu16), IsTrue());
112     EXPECT_THAT(tmpu16, Eq(40001));
113 
114     // Send Int16.
115     ASSERT_THAT(comms->SendInt16(-22050), IsTrue());
116   };
117   HandleCommunication(a, b);
118 }
119 
TEST(CommsTest,TestSendRecv32)120 TEST(CommsTest, TestSendRecv32) {
121   auto a = [](Comms* comms) {
122     // SendUint32.
123     ASSERT_THAT(comms->SendUint32(3221225472UL), IsTrue());
124 
125     // Recv Int32.
126     int32_t tmp32;
127     ASSERT_THAT(comms->RecvInt32(&tmp32), IsTrue());
128     EXPECT_THAT(tmp32, Eq(-1073741824));
129   };
130   auto b = [](Comms* comms) {
131     // Recv Uint32.
132     uint32_t tmpu32;
133     ASSERT_THAT(comms->RecvUint32(&tmpu32), IsTrue());
134     EXPECT_THAT(tmpu32, Eq(3221225472UL));
135 
136     // Send Int32.
137     ASSERT_THAT(comms->SendInt32(-1073741824), IsTrue());
138   };
139   HandleCommunication(a, b);
140 }
141 
TEST(CommsTest,TestSendRecv64)142 TEST(CommsTest, TestSendRecv64) {
143   auto a = [](Comms* comms) {
144     // SendUint64.
145     ASSERT_THAT(comms->SendUint64(1099511627776ULL), IsTrue());
146 
147     // Recv Int64.
148     int64_t tmp64;
149     ASSERT_THAT(comms->RecvInt64(&tmp64), IsTrue());
150     EXPECT_THAT(tmp64, Eq(-1099511627776LL));
151   };
152   auto b = [](Comms* comms) {
153     // Recv Uint64.
154     uint64_t tmpu64;
155     ASSERT_THAT(comms->RecvUint64(&tmpu64), IsTrue());
156     EXPECT_THAT(tmpu64, Eq(1099511627776ULL));
157 
158     // Send Int64.
159     ASSERT_THAT(comms->SendInt64(-1099511627776LL), IsTrue());
160   };
161   HandleCommunication(a, b);
162 }
163 
TEST(CommsTest,TestTypeMismatch)164 TEST(CommsTest, TestTypeMismatch) {
165   auto a = [](Comms* comms) {
166     uint8_t tmpu8;
167     // Receive Int8 (but Uint8 expected).
168     EXPECT_THAT(comms->RecvUint8(&tmpu8), IsFalse());
169   };
170   auto b = [](Comms* comms) {
171     // Send Int8 (but Uint8 expected).
172     ASSERT_THAT(comms->SendInt8(-93), IsTrue());
173   };
174   HandleCommunication(a, b);
175 }
176 
TEST(CommsTest,TestSendRecvString)177 TEST(CommsTest, TestSendRecvString) {
178   auto a = [](Comms* comms) {
179     std::string tmps;
180     ASSERT_THAT(comms->RecvString(&tmps), IsTrue());
181     EXPECT_TRUE(tmps == NullTestString());
182     EXPECT_THAT(tmps.size(), Eq(NullTestString().size()));
183   };
184   auto b = [](Comms* comms) {
185     ASSERT_THAT(comms->SendString(std::string(NullTestString())), IsTrue());
186   };
187   HandleCommunication(a, b);
188 }
189 
TEST(CommsTest,TestSendRecvArray)190 TEST(CommsTest, TestSendRecvArray) {
191   auto a = [](Comms* comms) {
192     // Receive 1M bytes.
193     std::vector<uint8_t> buffer;
194     ASSERT_THAT(comms->RecvBytes(&buffer), IsTrue());
195     EXPECT_THAT(buffer.size(), Eq(1024 * 1024));
196   };
197   auto b = [](Comms* comms) {
198     // Send 1M bytes.
199     std::vector<uint8_t> buffer(1024 * 1024);
200     memset(buffer.data(), 0, buffer.size());
201     ASSERT_THAT(comms->SendBytes(buffer), IsTrue());
202   };
203   HandleCommunication(a, b);
204 }
205 
TEST(CommsTest,TestSendRecvFD)206 TEST(CommsTest, TestSendRecvFD) {
207   auto a = [](Comms* comms) {
208     // Receive FD and test it.
209     int fd = -1;
210     ASSERT_THAT(comms->RecvFD(&fd), IsTrue());
211     EXPECT_GE(fd, 0);
212     EXPECT_NE(fcntl(fd, F_GETFD), -1);
213   };
214   auto b = [](Comms* comms) {
215     // Send our STDERR to the thread.
216     ASSERT_THAT(comms->SendFD(STDERR_FILENO), IsTrue());
217   };
218   HandleCommunication(a, b);
219 }
220 
TEST(CommsTest,TestSendRecvEmptyTLV)221 TEST(CommsTest, TestSendRecvEmptyTLV) {
222   auto a = [](Comms* comms) {
223     // Receive TLV without a value.
224     uint32_t tag;
225     std::vector<uint8_t> value;
226     ASSERT_THAT(comms->RecvTLV(&tag, &value), IsTrue());  // NOLINT
227     EXPECT_THAT(tag, Eq(0x00DEADBE));
228     EXPECT_THAT(value.size(), Eq(0));
229   };
230   auto b = [](Comms* comms) {
231     // Send TLV without a value.
232     ASSERT_THAT(comms->SendTLV(0x00DEADBE, 0, nullptr), IsTrue());
233   };
234   HandleCommunication(a, b);
235 }
236 
TEST(CommsTest,TestSendRecvEmptyTLV2)237 TEST(CommsTest, TestSendRecvEmptyTLV2) {
238   auto a = [](Comms* comms) {
239     // Receive TLV without a value.
240     uint32_t tag;
241     std::vector<uint8_t> data;
242     ASSERT_THAT(comms->RecvTLV(&tag, &data), IsTrue());
243     EXPECT_THAT(tag, Eq(0x00DEADBE));
244     EXPECT_THAT(data.size(), Eq(0));
245   };
246   auto b = [](Comms* comms) {
247     // Send TLV without a value.
248     ASSERT_THAT(comms->SendTLV(0x00DEADBE, 0, nullptr), IsTrue());
249   };
250   HandleCommunication(a, b);
251 }
252 
TEST(CommsTest,TestSendRecvProto)253 TEST(CommsTest, TestSendRecvProto) {
254   auto a = [](Comms* comms) {
255     // Receive a ProtoBuf.
256     std::unique_ptr<CommsTestMsg> comms_msg(new CommsTestMsg());
257     ASSERT_THAT(comms->RecvProtoBuf(comms_msg.get()), IsTrue());
258     ASSERT_THAT(comms_msg->value_size(), Eq(1));
259     EXPECT_THAT(comms_msg->value(0), Eq(kProtoStr));
260   };
261   auto b = [](Comms* comms) {
262     // Send a ProtoBuf.
263     std::unique_ptr<CommsTestMsg> comms_msg(new CommsTestMsg());
264     comms_msg->add_value(kProtoStr);
265     ASSERT_THAT(comms_msg->value_size(), Eq(1));
266     ASSERT_THAT(comms->SendProtoBuf(*comms_msg), IsTrue());
267   };
268   HandleCommunication(a, b);
269 }
270 
TEST(CommsTest,TestSendRecvStatusOK)271 TEST(CommsTest, TestSendRecvStatusOK) {
272   auto a = [](Comms* comms) {
273     // Receive a good status.
274     absl::Status status;
275     ASSERT_THAT(comms->RecvStatus(&status), IsTrue());
276     EXPECT_THAT(status, IsOk());
277   };
278   auto b = [](Comms* comms) {
279     // Send a good status.
280     ASSERT_THAT(comms->SendStatus(absl::OkStatus()), IsTrue());
281   };
282   HandleCommunication(a, b);
283 }
284 
TEST(CommsTest,TestSendRecvStatusFailing)285 TEST(CommsTest, TestSendRecvStatusFailing) {
286   auto a = [](Comms* comms) {
287     // Receive a failing status.
288     absl::Status status;
289     ASSERT_THAT(comms->RecvStatus(&status), IsTrue());
290     EXPECT_THAT(status, Not(IsOk()));
291     EXPECT_THAT(status, StatusIs(absl::StatusCode::kInternal, "something odd"));
292   };
293   auto b = [](Comms* comms) {
294     // Send a failing status.
295     ASSERT_THAT(comms->SendStatus(
296                     absl::Status{absl::StatusCode::kInternal, "something odd"}),
297                 IsTrue());
298   };
299   HandleCommunication(a, b);
300 }
301 
TEST(CommsTest,TestUsesDistinctBuffers)302 TEST(CommsTest, TestUsesDistinctBuffers) {
303   auto a = [](Comms* comms) {
304     // Receive 1M bytes.
305     std::vector<uint8_t> buffer1, buffer2;
306     ASSERT_THAT(comms->RecvBytes(&buffer1), IsTrue());  // NOLINT
307     EXPECT_THAT(buffer1.size(), Eq(1024 * 1024));
308 
309     ASSERT_THAT(comms->RecvBytes(&buffer2), IsTrue());  // NOLINT
310     EXPECT_THAT(buffer2.size(), Eq(1024 * 1024));
311 
312     // Make sure we can access the buffer (memory was not free'd).
313     // Probably only useful when running with ASAN/MSAN.
314     EXPECT_THAT(buffer1[1024 * 1024 - 1], Eq(buffer1[1024 * 1024 - 1]));
315     EXPECT_THAT(buffer2[1024 * 1024 - 1], Eq(buffer2[1024 * 1024 - 1]));
316     EXPECT_NE(buffer1.data(), buffer2.data());
317   };
318   auto b = [](Comms* comms) {
319     // Send 1M bytes.
320     absl::FixedArray<uint8_t> buf(1024 * 1024);
321     memset(buf.data(), 0, buf.size());
322     ASSERT_THAT(comms->SendBytes(buf.data(), buf.size()), IsTrue());
323     ASSERT_THAT(comms->SendBytes(buf.data(), buf.size()), IsTrue());
324   };
325   HandleCommunication(a, b);
326 }
327 
TEST(CommsTest,TestSendRecvCredentials)328 TEST(CommsTest, TestSendRecvCredentials) {
329   auto a = [](Comms* comms) {
330     // Check credentials.
331     pid_t pid;
332     uid_t uid;
333     gid_t gid;
334     ASSERT_THAT(comms->RecvCreds(&pid, &uid, &gid), IsTrue());
335     EXPECT_THAT(pid, Eq(getpid()));
336     EXPECT_THAT(uid, Eq(getuid()));
337     EXPECT_THAT(gid, Eq(getgid()));
338   };
339   auto b = [](Comms* comms) {
340     // Nothing to do here.
341   };
342   HandleCommunication(a, b);
343 }
344 
TEST(CommsTest,TestSendTooMuchData)345 TEST(CommsTest, TestSendTooMuchData) {
346   auto a = [](Comms* comms) {
347     // Nothing to do here.
348   };
349   auto b = [](Comms* comms) {
350     // Send too much data.
351     ASSERT_THAT(comms->SendBytes(nullptr, comms->GetMaxMsgSize() + 1),
352                 IsFalse());
353   };
354   HandleCommunication(a, b);
355 }
356 
TEST(CommsTest,TestSendRecvBytes)357 TEST(CommsTest, TestSendRecvBytes) {
358   auto a = [](Comms* comms) {
359     std::vector<uint8_t> buffer;
360     ASSERT_THAT(comms->RecvBytes(&buffer), IsTrue());
361     ASSERT_THAT(comms->SendBytes(buffer), IsTrue());
362   };
363   auto b = [](Comms* comms) {
364     const std::vector<uint8_t> request = {0, 1, 2, 3, 7};
365     ASSERT_THAT(comms->SendBytes(request), IsTrue());
366 
367     std::vector<uint8_t> response;
368     ASSERT_THAT(comms->RecvBytes(&response), IsTrue());
369     EXPECT_THAT(request, Eq(response));
370   };
371   HandleCommunication(a, b);
372 }
373 
374 }  // namespace sandbox2
375