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