1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "serialization.hpp"
18 #include "../../FdUtils.h"
19 #include "../../tests/FileUtils.h"
20 
21 #include <android/binder_ibinder_platform.h>
22 #include <android/binder_libbinder.h>
23 #include <binder/IServiceManager.h>
24 #include <binder/Parcel.h>
25 #include <binder/ParcelFileDescriptor.h>
26 #include <binder/ProcessState.h>
27 #include <binder/Status.h>
28 #include <gtest/gtest.h>
29 #include <utils/Errors.h>
30 #include <utils/String16.h>
31 
32 #include <cmath>
33 #include <cstdint>
34 #include <iostream>
35 #include <optional>
36 
37 using namespace std;
38 using namespace android;
39 using android::binder::unique_fd;
40 using android::os::ParcelFileDescriptor;
41 
42 // defined in Rust
43 extern "C" AIBinder *rust_service();
44 
45 
46 const int8_t TESTDATA_I8[4] = {-128, 0, 117, 127};
47 const uint8_t TESTDATA_U8[4] = {0, 42, 117, 255};
48 const char16_t TESTDATA_CHARS[4] = {0, 42, 117, numeric_limits<char16_t>::max()};
49 const int32_t TESTDATA_I32[4] = {numeric_limits<int32_t>::min(), 0, 117, numeric_limits<int32_t>::max()};
50 const int64_t TESTDATA_I64[4] = {numeric_limits<int64_t>::min(), 0, 117, numeric_limits<int64_t>::max()};
51 const uint64_t TESTDATA_U64[4] = {0, 42, 117, numeric_limits<uint64_t>::max()};
52 const float TESTDATA_FLOAT[4] = {
53         numeric_limits<float>::quiet_NaN(),
54         -numeric_limits<float>::infinity(),
55         117.0,
56         numeric_limits<float>::infinity(),
57 };
58 const double TESTDATA_DOUBLE[4] = {
59         numeric_limits<double>::quiet_NaN(),
60         -numeric_limits<double>::infinity(),
61         117.0,
62         numeric_limits<double>::infinity(),
63 };
64 const bool TESTDATA_BOOL[4] = {true, false, false, true};
65 const char* const TESTDATA_STRS[4] = {"", nullptr, "test", ""};
66 
67 static ::testing::Environment* gEnvironment;
68 
69 class SerializationEnvironment : public ::testing::Environment {
70 public:
SetUp()71     void SetUp() override {
72         m_server = AIBinder_toPlatformBinder(rust_service());
73     }
74 
getServer(void)75     sp<IBinder> getServer(void) { return m_server; }
76 
77 private:
78     sp<IBinder> m_server;
79 };
80 
81 
82 class SerializationTest : public ::testing::Test {
83 protected:
SetUp()84     void SetUp() override {
85         ASSERT_NE(gEnvironment, nullptr);
86         m_server = static_cast<SerializationEnvironment *>(gEnvironment)->getServer();
87     }
88 
89     sp<IBinder> m_server;
90 };
91 
92 
TEST_F(SerializationTest,SerializeBool)93 TEST_F(SerializationTest, SerializeBool) {
94     android::Parcel data;
95     data.writeInterfaceToken(String16("read_parcel_test"));
96 
97     vector<bool> bools(begin(TESTDATA_BOOL), end(TESTDATA_BOOL));
98     ASSERT_EQ(data.writeBool(true), OK);
99     ASSERT_EQ(data.writeBool(false), OK);
100     ASSERT_EQ(data.writeBoolVector(bools), OK);
101     ASSERT_EQ(data.writeBoolVector(nullopt), OK);
102 
103     android::Parcel reply;
104     ASSERT_EQ(m_server->transact(TEST_BOOL, data, &reply), OK);
105 
106     vector<bool> read_bools;
107     optional<vector<bool>> maybe_bools;
108     ASSERT_EQ(reply.readBool(), true);
109     ASSERT_EQ(reply.readBool(), false);
110     ASSERT_EQ(reply.readBoolVector(&read_bools), OK);
111     ASSERT_EQ(read_bools, bools);
112     ASSERT_EQ(reply.readBoolVector(&maybe_bools), OK);
113     ASSERT_EQ(maybe_bools, nullopt);
114 
115     int32_t end;
116     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
117 }
118 
TEST_F(SerializationTest,SerializeByte)119 TEST_F(SerializationTest, SerializeByte) {
120     android::Parcel data;
121     data.writeInterfaceToken(String16("read_parcel_test"));
122 
123     vector<int8_t> i8s(begin(TESTDATA_I8), end(TESTDATA_I8));
124     vector<uint8_t> u8s(begin(TESTDATA_U8), end(TESTDATA_U8));
125     data.writeByte(0);
126     data.writeByte(1);
127     data.writeByte(numeric_limits<int8_t>::max());
128     data.writeByteVector(i8s);
129     data.writeByteVector(u8s);
130     data.writeByteVector(optional<vector<int8_t>>({}));
131 
132     android::Parcel reply;
133     ASSERT_EQ(m_server->transact(TEST_BYTE, data, &reply), OK);
134 
135     vector<int8_t> read_i8s;
136     vector<uint8_t> read_u8s;
137     optional<vector<int8_t>> maybe_i8s;
138     ASSERT_EQ(reply.readByte(), 0);
139     ASSERT_EQ(reply.readByte(), 1);
140     ASSERT_EQ(reply.readByte(), numeric_limits<int8_t>::max());
141     ASSERT_EQ(reply.readByteVector(&read_i8s), OK);
142     ASSERT_EQ(read_i8s, i8s);
143     ASSERT_EQ(reply.readByteVector(&read_u8s), OK);
144     ASSERT_EQ(read_u8s, u8s);
145     ASSERT_EQ(reply.readByteVector(&maybe_i8s), OK);
146     ASSERT_EQ(maybe_i8s, nullopt);
147 
148     int32_t end;
149     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
150 }
151 
TEST_F(SerializationTest,SerializeU16)152 TEST_F(SerializationTest, SerializeU16) {
153     android::Parcel data;
154     data.writeInterfaceToken(String16("read_parcel_test"));
155 
156     vector<char16_t> chars(begin(TESTDATA_CHARS), end(TESTDATA_CHARS));
157     data.writeChar(0);
158     data.writeChar(1);
159     data.writeChar(numeric_limits<char16_t>::max());
160     data.writeCharVector(chars);
161     data.writeCharVector(nullopt);
162 
163     android::Parcel reply;
164     ASSERT_EQ(m_server->transact(TEST_U16, data, &reply), OK);
165 
166     vector<char16_t> read_chars;
167     optional<vector<char16_t>> maybe_chars;
168     ASSERT_EQ(reply.readChar(), 0);
169     ASSERT_EQ(reply.readChar(), 1);
170     ASSERT_EQ(reply.readChar(), numeric_limits<char16_t>::max());
171     ASSERT_EQ(reply.readCharVector(&read_chars), OK);
172     ASSERT_EQ(read_chars, chars);
173     ASSERT_EQ(reply.readCharVector(&maybe_chars), OK);
174     ASSERT_EQ(maybe_chars, nullopt);
175 
176     int32_t end;
177     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
178 }
179 
TEST_F(SerializationTest,SerializeI32)180 TEST_F(SerializationTest, SerializeI32) {
181     android::Parcel data;
182     data.writeInterfaceToken(String16("read_parcel_test"));
183 
184     vector<int32_t> i32s(begin(TESTDATA_I32), end(TESTDATA_I32));
185     data.writeInt32(0);
186     data.writeInt32(1);
187     data.writeInt32(numeric_limits<int32_t>::max());
188     data.writeInt32Vector(i32s);
189     data.writeInt32Vector(nullopt);
190 
191     android::Parcel reply;
192     ASSERT_EQ(m_server->transact(TEST_I32, data, &reply), OK);
193 
194     vector<int32_t> read_i32s;
195     optional<vector<int32_t>> maybe_i32s;
196     ASSERT_EQ(reply.readInt32(), 0);
197     ASSERT_EQ(reply.readInt32(), 1);
198     ASSERT_EQ(reply.readInt32(), numeric_limits<int32_t>::max());
199     ASSERT_EQ(reply.readInt32Vector(&read_i32s), OK);
200     ASSERT_EQ(read_i32s, i32s);
201     ASSERT_EQ(reply.readInt32Vector(&maybe_i32s), OK);
202     ASSERT_EQ(maybe_i32s, nullopt);
203 
204     int32_t end;
205     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
206 }
207 
TEST_F(SerializationTest,SerializeI64)208 TEST_F(SerializationTest, SerializeI64) {
209     android::Parcel data;
210     data.writeInterfaceToken(String16("read_parcel_test"));
211 
212     vector<int64_t> i64s(begin(TESTDATA_I64), end(TESTDATA_I64));
213     data.writeInt64(0);
214     data.writeInt64(1);
215     data.writeInt64(numeric_limits<int64_t>::max());
216     data.writeInt64Vector(i64s);
217     data.writeInt64Vector(nullopt);
218 
219     android::Parcel reply;
220     ASSERT_EQ(m_server->transact(TEST_I64, data, &reply), OK);
221 
222     vector<int64_t> read_i64s;
223     optional<vector<int64_t>> maybe_i64s;
224     ASSERT_EQ(reply.readInt64(), 0);
225     ASSERT_EQ(reply.readInt64(), 1);
226     ASSERT_EQ(reply.readInt64(), numeric_limits<int64_t>::max());
227     ASSERT_EQ(reply.readInt64Vector(&read_i64s), OK);
228     ASSERT_EQ(read_i64s, i64s);
229     ASSERT_EQ(reply.readInt64Vector(&maybe_i64s), OK);
230     ASSERT_EQ(maybe_i64s, nullopt);
231 
232     int32_t end;
233     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
234 }
235 
TEST_F(SerializationTest,SerializeU64)236 TEST_F(SerializationTest, SerializeU64) {
237     android::Parcel data;
238     data.writeInterfaceToken(String16("read_parcel_test"));
239 
240     vector<uint64_t> u64s(begin(TESTDATA_U64), end(TESTDATA_U64));
241     data.writeUint64(0);
242     data.writeUint64(1);
243     data.writeUint64(numeric_limits<uint64_t>::max());
244     data.writeUint64Vector(u64s);
245     data.writeUint64Vector(nullopt);
246 
247     android::Parcel reply;
248     ASSERT_EQ(m_server->transact(TEST_U64, data, &reply), OK);
249 
250     vector<uint64_t> read_u64s;
251     optional<vector<uint64_t>> maybe_u64s;
252     ASSERT_EQ(reply.readUint64(), 0);
253     ASSERT_EQ(reply.readUint64(), 1);
254     ASSERT_EQ(reply.readUint64(), numeric_limits<uint64_t>::max());
255     ASSERT_EQ(reply.readUint64Vector(&read_u64s), OK);
256     ASSERT_EQ(read_u64s, u64s);
257     ASSERT_EQ(reply.readUint64Vector(&maybe_u64s), OK);
258     ASSERT_EQ(maybe_u64s, nullopt);
259 
260     int32_t end;
261     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
262 }
263 
TEST_F(SerializationTest,SerializeF32)264 TEST_F(SerializationTest, SerializeF32) {
265     android::Parcel data;
266     data.writeInterfaceToken(String16("read_parcel_test"));
267 
268     vector<float> floats(begin(TESTDATA_FLOAT), end(TESTDATA_FLOAT));
269     data.writeFloat(0);
270     data.writeFloatVector(floats);
271     data.writeFloatVector(nullopt);
272 
273     android::Parcel reply;
274     ASSERT_EQ(m_server->transact(TEST_F32, data, &reply), OK);
275 
276     vector<float> read_floats;
277     optional<vector<float>> maybe_floats;
278     ASSERT_EQ(reply.readFloat(), 0);
279     ASSERT_EQ(reply.readFloatVector(&read_floats), OK);
280     ASSERT_TRUE(isnan(read_floats[0]));
281     ASSERT_EQ(read_floats[1], floats[1]);
282     ASSERT_EQ(read_floats[2], floats[2]);
283     ASSERT_EQ(read_floats[3], floats[3]);
284     ASSERT_EQ(reply.readFloatVector(&maybe_floats), OK);
285     ASSERT_EQ(maybe_floats, nullopt);
286 
287     int32_t end;
288     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
289 }
290 
TEST_F(SerializationTest,SerializeF64)291 TEST_F(SerializationTest, SerializeF64) {
292     android::Parcel data;
293     data.writeInterfaceToken(String16("read_parcel_test"));
294 
295     vector<double> doubles(begin(TESTDATA_DOUBLE), end(TESTDATA_DOUBLE));
296     data.writeDouble(0);
297     data.writeDoubleVector(doubles);
298     data.writeDoubleVector(nullopt);
299 
300     android::Parcel reply;
301     ASSERT_EQ(m_server->transact(TEST_F64, data, &reply), OK);
302 
303     vector<double> read_doubles;
304     optional<vector<double>> maybe_doubles;
305     ASSERT_EQ(reply.readDouble(), 0);
306     ASSERT_EQ(reply.readDoubleVector(&read_doubles), OK);
307     ASSERT_TRUE(isnan(read_doubles[0]));
308     ASSERT_EQ(read_doubles[1], doubles[1]);
309     ASSERT_EQ(read_doubles[2], doubles[2]);
310     ASSERT_EQ(read_doubles[3], doubles[3]);
311     ASSERT_EQ(reply.readDoubleVector(&maybe_doubles), OK);
312     ASSERT_EQ(maybe_doubles, nullopt);
313 
314     int32_t end;
315     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
316 }
317 
TEST_F(SerializationTest,SerializeString)318 TEST_F(SerializationTest, SerializeString) {
319     android::Parcel data;
320     data.writeInterfaceToken(String16("read_parcel_test"));
321 
322     vector<optional<String16>> strings;
323     for (auto I = begin(TESTDATA_STRS), E = end(TESTDATA_STRS); I != E; ++I) {
324         if (*I == nullptr) {
325             strings.push_back(optional<String16>());
326         } else {
327             strings.emplace_back(*I);
328         }
329     }
330     data.writeUtf8AsUtf16(string("testing"));
331     data.writeString16(nullopt);
332     data.writeString16Vector(strings);
333     data.writeString16Vector(nullopt);
334 
335     android::Parcel reply;
336     ASSERT_EQ(m_server->transact(TEST_STRING, data, &reply), OK);
337 
338     optional<String16> maybe_string;
339     optional<vector<optional<String16>>> read_strings;
340     ASSERT_EQ(reply.readString16(), String16("testing"));
341     ASSERT_EQ(reply.readString16(&maybe_string), OK);
342     ASSERT_EQ(maybe_string, nullopt);
343     ASSERT_EQ(reply.readString16Vector(&read_strings), OK);
344     ASSERT_EQ(read_strings, strings);
345     ASSERT_EQ(reply.readString16Vector(&read_strings), OK);
346     ASSERT_EQ(read_strings, nullopt);
347 
348     int32_t end;
349     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
350 }
351 
TEST_F(SerializationTest,SerializeFileDescriptor)352 TEST_F(SerializationTest, SerializeFileDescriptor) {
353     unique_fd out_file, in_file;
354     ASSERT_TRUE(binder::Pipe(&out_file, &in_file));
355 
356     vector<ParcelFileDescriptor> file_descriptors;
357     file_descriptors.push_back(ParcelFileDescriptor(std::move(out_file)));
358     file_descriptors.push_back(ParcelFileDescriptor(std::move(in_file)));
359 
360     android::Parcel data;
361     data.writeInterfaceToken(String16("read_parcel_test"));
362 
363     data.writeParcelable(file_descriptors[0]);
364     data.writeParcelable(file_descriptors[1]);
365     data.writeParcelableVector(file_descriptors);
366 
367     android::Parcel reply;
368     ASSERT_EQ(m_server->transact(TEST_FILE_DESCRIPTOR, data, &reply), OK);
369 
370     ParcelFileDescriptor returned_fd1, returned_fd2;
371     vector<ParcelFileDescriptor> returned_file_descriptors;
372     ASSERT_EQ(reply.readParcelable(&returned_fd1), OK);
373     ASSERT_EQ(reply.readParcelable(&returned_fd2), OK);
374     ASSERT_EQ(reply.readParcelableVector(&returned_file_descriptors), OK);
375 
376     int32_t end;
377     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
378 
379     base::WriteStringToFd("Testing", returned_fd2.get());
380     base::WriteStringToFd("File", returned_file_descriptors[1].get());
381     base::WriteStringToFd("Descriptors", file_descriptors[1].get());
382 
383     string expected = "TestingFileDescriptors";
384     vector<char> buf(expected.length());
385     base::ReadFully(file_descriptors[0].release(), buf.data(), buf.size());
386     ASSERT_EQ(expected, string(buf.data(), expected.length()));
387 }
388 
TEST_F(SerializationTest,SerializeIBinder)389 TEST_F(SerializationTest, SerializeIBinder) {
390     android::Parcel data;
391     data.writeInterfaceToken(String16("read_parcel_test"));
392 
393     data.writeStrongBinder(m_server);
394     data.writeStrongBinder(nullptr);
395     data.writeStrongBinderVector({m_server, nullptr});
396     data.writeStrongBinderVector(nullopt);
397 
398     android::Parcel reply;
399     ASSERT_EQ(m_server->transact(TEST_IBINDER, data, &reply), OK);
400 
401     optional<vector<sp<IBinder>>> binders;
402     ASSERT_TRUE(reply.readStrongBinder());
403     ASSERT_FALSE(reply.readStrongBinder());
404     ASSERT_EQ(reply.readStrongBinderVector(&binders), OK);
405     ASSERT_EQ(binders->size(), 2);
406     ASSERT_TRUE((*binders)[0]);
407     ASSERT_FALSE((*binders)[1]);
408     ASSERT_EQ(reply.readStrongBinderVector(&binders), OK);
409     ASSERT_FALSE(binders);
410 
411     int32_t end;
412     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
413 }
414 
TEST_F(SerializationTest,SerializeStatus)415 TEST_F(SerializationTest, SerializeStatus) {
416     android::Parcel data;
417     data.writeInterfaceToken(String16("read_parcel_test"));
418 
419     binder::Status::ok().writeToParcel(&data);
420     binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER, "a status message")
421             .writeToParcel(&data);
422     binder::Status::fromServiceSpecificError(42, "a service-specific error").writeToParcel(&data);
423 
424     android::Parcel reply;
425     ASSERT_EQ(m_server->transact(TEST_STATUS, data, &reply), OK);
426 
427     binder::Status status;
428 
429     ASSERT_EQ(status.readFromParcel(reply), OK);
430     ASSERT_TRUE(status.isOk());
431 
432     ASSERT_EQ(status.readFromParcel(reply), OK);
433     ASSERT_EQ(status.exceptionCode(), binder::Status::EX_NULL_POINTER);
434     ASSERT_EQ(status.exceptionMessage(), "a status message");
435 
436     ASSERT_EQ(status.readFromParcel(reply), OK);
437     ASSERT_EQ(status.serviceSpecificErrorCode(), 42);
438     ASSERT_EQ(status.exceptionMessage(), "a service-specific error");
439 
440     int32_t end;
441     ASSERT_EQ(reply.readInt32(&end), NOT_ENOUGH_DATA);
442 }
443 
444 // Test that failures from Rust properly propagate to C++
TEST_F(SerializationTest,SerializeRustFail)445 TEST_F(SerializationTest, SerializeRustFail) {
446     android::Parcel data;
447     data.writeInterfaceToken(String16("read_parcel_test"));
448     ASSERT_EQ(m_server->transact(TEST_FAIL, data, nullptr), FAILED_TRANSACTION);
449 }
450 
main(int argc,char ** argv)451 int main(int argc, char **argv) {
452     ::testing::InitGoogleTest(&argc, argv);
453     gEnvironment = AddGlobalTestEnvironment(new SerializationEnvironment());
454     ProcessState::self()->startThreadPool();
455     return RUN_ALL_TESTS();
456 }
457