1 /*
2  * Copyright (C) 2019 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 #define FUZZ_LOG_TAG "hwbinder"
17 
18 #include "hwbinder.h"
19 #include "util.h"
20 
21 #include <android-base/logging.h>
22 #include <hwbinder/Parcel.h>
23 
24 using ::android::status_t;
25 
26 // TODO: support scatter-gather types
27 
operator <<(std::ostream & os,const::android::sp<::android::hardware::IBinder> & binder)28 std::ostream& operator<<(std::ostream& os, const ::android::sp<::android::hardware::IBinder>& binder) {
29     os << binder.get();
30     return os;
31 }
32 
33 #define PARCEL_READ_OPT_STATUS(T, FUN) \
34     PARCEL_READ_NO_STATUS(T, FUN), PARCEL_READ_WITH_STATUS(T, FUN)
35 
36 #define PARCEL_READ_NO_STATUS(T, FUN) \
37     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {\
38         FUZZ_LOG() << "about to read " #T " using " #FUN " with no status";\
39         T t = p.FUN();\
40         FUZZ_LOG() << #T " value: " << t;\
41     }
42 
43 #define PARCEL_READ_WITH_STATUS(T, FUN) \
44     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {\
45         FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
46         T t;\
47         status_t status = p.FUN(&t);\
48         FUZZ_LOG() << #T " status: " << status << " value: " << t;\
49     }
50 
51 // clang-format off
52 std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTIONS {
53     PARCEL_READ_NO_STATUS(size_t, dataSize),
54     PARCEL_READ_NO_STATUS(size_t, dataAvail),
55     PARCEL_READ_NO_STATUS(size_t, dataPosition),
56     PARCEL_READ_NO_STATUS(size_t, dataCapacity),
__anon7775d65a0102() 57     [] (const ::android::hardware::Parcel& p, uint8_t pos) {
58         FUZZ_LOG() << "about to setDataPosition: " << pos;
59         p.setDataPosition(pos);
60         FUZZ_LOG() << "setDataPosition done";
61     },
__anon7775d65a0202() 62     [] (const ::android::hardware::Parcel& p, uint8_t length) {
63         FUZZ_LOG() << "about to enforceInterface";
64         std::string interfaceName(length, 'a');
65         bool okay = p.enforceInterface(interfaceName.c_str());
66         FUZZ_LOG() << "enforceInterface status: " << okay;
67     },
68     PARCEL_READ_NO_STATUS(size_t, objectsCount),
__anon7775d65a0302() 69     [] (const ::android::hardware::Parcel& p, uint8_t length) {
70         FUZZ_LOG() << "about to read";
71         std::vector<uint8_t> data (length);
72         status_t status = p.read(data.data(), length);
73         FUZZ_LOG() << "read status: " << status << " data: " << hexString(data.data(), data.size());
74     },
__anon7775d65a0402() 75     [] (const ::android::hardware::Parcel& p, uint8_t length) {
76         FUZZ_LOG() << "about to read";
77         std::vector<uint8_t> data (length);
78         const void* inplace = p.readInplace(length);
79         FUZZ_LOG() << "read status: " << hexString(inplace, length);
80     },
81     PARCEL_READ_WITH_STATUS(int8_t, readInt8),
82     PARCEL_READ_WITH_STATUS(uint8_t, readUint8),
83     PARCEL_READ_WITH_STATUS(int16_t, readInt16),
84     PARCEL_READ_WITH_STATUS(uint16_t, readUint16),
85     PARCEL_READ_OPT_STATUS(int32_t, readInt32),
86     PARCEL_READ_OPT_STATUS(uint32_t, readUint32),
87     PARCEL_READ_OPT_STATUS(int64_t, readInt64),
88     PARCEL_READ_OPT_STATUS(uint64_t, readUint64),
89     PARCEL_READ_OPT_STATUS(float, readFloat),
90     PARCEL_READ_OPT_STATUS(double, readDouble),
91     PARCEL_READ_OPT_STATUS(bool, readBool),
__anon7775d65a0502() 92     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
93         FUZZ_LOG() << "about to readCString";
94         const char* str = p.readCString();
95         FUZZ_LOG() << "readCString " << (str ? str : "<null>");
96     },
97     PARCEL_READ_OPT_STATUS(::android::String16, readString16),
98     PARCEL_READ_WITH_STATUS(std::unique_ptr<::android::String16>, readString16),
__anon7775d65a0602() 99     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
100         FUZZ_LOG() << "about to readString16Inplace";
101         size_t outSize = 0;
102         const char16_t* str = p.readString16Inplace(&outSize);
103         FUZZ_LOG() << "readString16Inplace: " << hexString(str, sizeof(char16_t) * outSize);
104     },
105     PARCEL_READ_OPT_STATUS(::android::sp<::android::hardware::IBinder>, readStrongBinder),
106     PARCEL_READ_WITH_STATUS(::android::sp<::android::hardware::IBinder>, readNullableStrongBinder),
__anon7775d65a0702() 107     [] (const ::android::hardware::Parcel& p, uint8_t size) {
108         FUZZ_LOG() << "about to readBuffer";
109         size_t handle = 0;
110         const void* data = nullptr;
111         status_t status = p.readBuffer(size, &handle, &data);
112         FUZZ_LOG() << "readBuffer status: " << status << " handle: " << handle << " data: " << data;
113 
114         // should be null since we don't create any IPC objects
115         CHECK(data == nullptr) << data;
116     },
__anon7775d65a0802() 117     [] (const ::android::hardware::Parcel& p, uint8_t size) {
118         FUZZ_LOG() << "about to readNullableBuffer";
119         size_t handle = 0;
120         const void* data = nullptr;
121         status_t status = p.readNullableBuffer(size, &handle, &data);
122         FUZZ_LOG() << "readNullableBuffer status: " << status << " handle: " << handle << " data: " << data;
123 
124         // should be null since we don't create any IPC objects
125         CHECK(data == nullptr) << data;
126     },
__anon7775d65a0902() 127     [] (const ::android::hardware::Parcel& p, uint8_t size) {
128         FUZZ_LOG() << "about to readEmbeddedBuffer";
129         size_t handle = 0;
130         size_t parent_buffer_handle = 0;
131         size_t parent_offset = 3;
132         const void* data = nullptr;
133         status_t status = p.readEmbeddedBuffer(size, &handle, parent_buffer_handle, parent_offset, &data);
134         FUZZ_LOG() << "readEmbeddedBuffer status: " << status << " handle: " << handle << " data: " << data;
135 
136         // should be null since we don't create any IPC objects
137         CHECK(data == nullptr) << data;
138     },
__anon7775d65a0a02() 139     [] (const ::android::hardware::Parcel& p, uint8_t size) {
140         FUZZ_LOG() << "about to readNullableEmbeddedBuffer";
141         size_t handle = 0;
142         size_t parent_buffer_handle = 0;
143         size_t parent_offset = 3;
144         const void* data = nullptr;
145         status_t status = p.readNullableEmbeddedBuffer(size, &handle, parent_buffer_handle, parent_offset, &data);
146         FUZZ_LOG() << "readNullableEmbeddedBuffer status: " << status << " handle: " << handle << " data: " << data;
147 
148         // should be null since we don't create any IPC objects
149         CHECK(data == nullptr) << data;
150     },
__anon7775d65a0b02() 151     [] (const ::android::hardware::Parcel& p, uint8_t size) {
152         FUZZ_LOG() << "about to readEmbeddedNativeHandle";
153         size_t parent_buffer_handle = size & 0xf;
154         size_t parent_offset = size >> 4;
155         const native_handle_t* handle = nullptr;
156         status_t status = p.readEmbeddedNativeHandle(parent_buffer_handle, parent_offset, &handle);
157         FUZZ_LOG() << "readEmbeddedNativeHandle status: " << status << " handle: " << handle << " handle: " << handle;
158 
159         // should be null since we don't create any IPC objects
160         CHECK(handle == nullptr) << handle;
161     },
__anon7775d65a0c02() 162     [] (const ::android::hardware::Parcel& p, uint8_t size) {
163         FUZZ_LOG() << "about to readNullableEmbeddedNativeHandle";
164         size_t parent_buffer_handle = size & 0xf;
165         size_t parent_offset = size >> 4;
166         const native_handle_t* handle = nullptr;
167         status_t status = p.readNullableEmbeddedNativeHandle(parent_buffer_handle, parent_offset, &handle);
168         FUZZ_LOG() << "readNullableEmbeddedNativeHandle status: " << status << " handle: " << handle << " handle: " << handle;
169 
170         // should be null since we don't create any IPC objects
171         CHECK(handle == nullptr) << handle;
172     },
__anon7775d65a0d02() 173     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
174         FUZZ_LOG() << "about to readNativeHandleNoDup";
175         const native_handle_t* handle = nullptr;
176         status_t status = p.readNativeHandleNoDup(&handle);
177         FUZZ_LOG() << "readNativeHandleNoDup status: " << status << " handle: " << handle;
178 
179         // should be null since we don't create any IPC objects
180         CHECK(handle == nullptr) << handle;
181         CHECK(status != ::android::OK);
182     },
__anon7775d65a0e02() 183     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
184         FUZZ_LOG() << "about to readNullableNativeHandleNoDup";
185         const native_handle_t* handle = nullptr;
186         status_t status = p.readNullableNativeHandleNoDup(&handle);
187         FUZZ_LOG() << "readNullableNativeHandleNoDup status: " << status << " handle: " << handle;
188 
189         // should be null since we don't create any IPC objects
190         CHECK(handle == nullptr) << handle;
191     },
192 };
193 // clang-format on
194