| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 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 |  | 
 | 28 | std::ostream& operator<<(std::ostream& os, const ::android::sp<::android::hardware::IBinder>& binder) { | 
 | 29 |     os << binder.get(); | 
 | 30 |     return os; | 
 | 31 | } | 
 | 32 |  | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 33 | #define PARCEL_READ_OPT_STATUS(T, FUN) \ | 
 | 34 |     PARCEL_READ_NO_STATUS(T, FUN), PARCEL_READ_WITH_STATUS(T, FUN) | 
 | 35 |  | 
| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 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 |  | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 51 | // clang-format off | 
| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 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), | 
 | 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 |     }, | 
 | 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), | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 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 |     }, | 
 | 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 |     }, | 
| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 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), | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 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), | 
 | 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>"); | 
| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 96 |     }, | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 97 |     PARCEL_READ_OPT_STATUS(::android::String16, readString16), | 
 | 98 |     PARCEL_READ_WITH_STATUS(std::unique_ptr<::android::String16>, readString16), | 
 | 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), | 
| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 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 |     }, | 
 | 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 |     }, | 
 | 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 |     }, | 
 | 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 |     }, | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 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 |     }, | 
 | 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 |     }, | 
| Steven Moreland | 46e0da7 | 2019-09-05 15:52:02 -0700 | [diff] [blame] | 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 |     }, | 
 | 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 | }; | 
| Steven Moreland | 7eac78a | 2019-10-11 18:46:24 -0700 | [diff] [blame] | 193 | // clang-format on |