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