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/hex.h>
22 #include <android-base/logging.h>
23 #include <hwbinder/Parcel.h>
24
25 using ::android::status_t;
26 using ::android::base::HexString;
27
28 // TODO: support scatter-gather types
29
operator <<(std::ostream & os,const::android::sp<::android::hardware::IBinder> & binder)30 std::ostream& operator<<(std::ostream& os, const ::android::sp<::android::hardware::IBinder>& binder) {
31 os << binder.get();
32 return os;
33 }
34
35 #define PARCEL_READ_OPT_STATUS(T, FUN) \
36 PARCEL_READ_NO_STATUS(T, FUN), PARCEL_READ_WITH_STATUS(T, FUN)
37
38 #define PARCEL_READ_NO_STATUS(T, FUN) \
39 [](const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) { \
40 FUZZ_LOG() << "about to read " #T " using " #FUN " with no status"; \
41 T t = p.FUN(); \
42 FUZZ_LOG() << #T " value: " << t; \
43 }
44
45 #define PARCEL_READ_WITH_STATUS(T, FUN) \
46 [](const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) { \
47 FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
48 T t; \
49 status_t status = p.FUN(&t); \
50 FUZZ_LOG() << #T " status: " << status << " value: " << t; \
51 }
52
53 // clang-format off
54 std::vector<ParcelRead<::android::hardware::Parcel>> HWBINDER_PARCEL_READ_FUNCTIONS {
55 PARCEL_READ_NO_STATUS(size_t, dataSize),
56 PARCEL_READ_NO_STATUS(size_t, dataAvail),
57 PARCEL_READ_NO_STATUS(size_t, dataPosition),
58 PARCEL_READ_NO_STATUS(size_t, dataCapacity),
__anon91eea8370102() 59 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
60 // aborts on larger values
61 size_t pos = provider.ConsumeIntegralInRange<size_t>(0, INT32_MAX);
62 FUZZ_LOG() << "about to setDataPosition: " << pos;
63 p.setDataPosition(pos);
64 FUZZ_LOG() << "setDataPosition done";
65 },
__anon91eea8370202() 66 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
67 FUZZ_LOG() << "about to enforceInterface";
68 bool okay = p.enforceInterface(provider.ConsumeRandomLengthString().c_str());
69 FUZZ_LOG() << "enforceInterface status: " << okay;
70 },
71 PARCEL_READ_NO_STATUS(size_t, objectsCount),
__anon91eea8370302() 72 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
73 // Read at least a bit. Unbounded allocation would OOM.
74 size_t length = provider.ConsumeIntegralInRange<size_t>(0, 1024);
75 FUZZ_LOG() << "about to read";
76 std::vector<uint8_t> data (length);
77 status_t status = p.read(data.data(), length);
78 FUZZ_LOG() << "read status: " << status << " data: " << HexString(data.data(), data.size());
79 },
__anon91eea8370402() 80 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
81 size_t length = provider.ConsumeIntegral<size_t>();
82 FUZZ_LOG() << "about to read";
83 const void* inplace = p.readInplace(length);
84 FUZZ_LOG() << "read status: " << (inplace ? HexString(inplace, length) : "null");
85 },
86 PARCEL_READ_WITH_STATUS(int8_t, readInt8),
87 PARCEL_READ_WITH_STATUS(uint8_t, readUint8),
88 PARCEL_READ_WITH_STATUS(int16_t, readInt16),
89 PARCEL_READ_WITH_STATUS(uint16_t, readUint16),
90 PARCEL_READ_OPT_STATUS(int32_t, readInt32),
91 PARCEL_READ_OPT_STATUS(uint32_t, readUint32),
92 PARCEL_READ_OPT_STATUS(int64_t, readInt64),
93 PARCEL_READ_OPT_STATUS(uint64_t, readUint64),
94 PARCEL_READ_OPT_STATUS(float, readFloat),
95 PARCEL_READ_OPT_STATUS(double, readDouble),
96 PARCEL_READ_OPT_STATUS(bool, readBool),
__anon91eea8370502() 97 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
98 FUZZ_LOG() << "about to readCString";
99 const char* str = p.readCString();
100 FUZZ_LOG() << "readCString " << (str ? str : "<null>");
101 },
102 PARCEL_READ_OPT_STATUS(::android::String16, readString16),
103 PARCEL_READ_WITH_STATUS(std::unique_ptr<::android::String16>, readString16),
__anon91eea8370602() 104 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
105 FUZZ_LOG() << "about to readString16Inplace";
106 size_t outSize = 0;
107 const char16_t* str = p.readString16Inplace(&outSize);
108 FUZZ_LOG() << "readString16Inplace: " << HexString(str, sizeof(char16_t) * outSize);
109 },
110 PARCEL_READ_OPT_STATUS(::android::sp<::android::hardware::IBinder>, readStrongBinder),
111 PARCEL_READ_WITH_STATUS(::android::sp<::android::hardware::IBinder>, readNullableStrongBinder),
__anon91eea8370702() 112 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
113 size_t size = provider.ConsumeIntegral<size_t>();
114 FUZZ_LOG() << "about to readBuffer";
115 size_t handle = 0;
116 const void* data = nullptr;
117 status_t status = p.readBuffer(size, &handle, &data);
118 FUZZ_LOG() << "readBuffer status: " << status << " handle: " << handle << " data: " << data;
119
120 // should be null since we don't create any IPC objects
121 CHECK(data == nullptr) << data;
122 },
__anon91eea8370802() 123 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
124 size_t size = provider.ConsumeIntegral<size_t>();
125 FUZZ_LOG() << "about to readNullableBuffer";
126 size_t handle = 0;
127 const void* data = nullptr;
128 status_t status = p.readNullableBuffer(size, &handle, &data);
129 FUZZ_LOG() << "readNullableBuffer status: " << status << " handle: " << handle << " data: " << data;
130
131 // should be null since we don't create any IPC objects
132 CHECK(data == nullptr) << data;
133 },
__anon91eea8370902() 134 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
135 size_t size = provider.ConsumeIntegral<size_t>();
136 FUZZ_LOG() << "about to readEmbeddedBuffer";
137 size_t handle = 0;
138 size_t parent_buffer_handle = 0;
139 size_t parent_offset = 3;
140 const void* data = nullptr;
141 status_t status = p.readEmbeddedBuffer(size, &handle, parent_buffer_handle, parent_offset, &data);
142 FUZZ_LOG() << "readEmbeddedBuffer status: " << status << " handle: " << handle << " data: " << data;
143
144 // should be null since we don't create any IPC objects
145 CHECK(data == nullptr) << data;
146 },
__anon91eea8370a02() 147 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& provider) {
148 size_t size = provider.ConsumeIntegral<size_t>();
149 FUZZ_LOG() << "about to readNullableEmbeddedBuffer";
150 size_t handle = 0;
151 size_t parent_buffer_handle = 0;
152 size_t parent_offset = 3;
153 const void* data = nullptr;
154 status_t status = p.readNullableEmbeddedBuffer(size, &handle, parent_buffer_handle, parent_offset, &data);
155 FUZZ_LOG() << "readNullableEmbeddedBuffer status: " << status << " handle: " << handle << " data: " << data;
156
157 // should be null since we don't create any IPC objects
158 CHECK(data == nullptr) << data;
159 },
__anon91eea8370b02() 160 [] (const ::android::hardware::Parcel& p, FuzzedDataProvider& /*provider*/) {
161 FUZZ_LOG() << "about to readNativeHandleNoDup";
162 const native_handle_t* handle = nullptr;
163 status_t status = p.readNativeHandleNoDup(&handle);
164 FUZZ_LOG() << "readNativeHandleNoDup status: " << status << " handle: " << handle;
165
166 // should be null since we don't create any IPC objects
167 CHECK(handle == nullptr) << handle;
168 CHECK(status != ::android::OK);
169 },
170 };
171 // clang-format on
172