1 /* 2 * Copyright (C) 2016 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 17 #define LOG_TAG "HidlSupport" 18 19 #include <hidl/HidlBinderSupport.h> 20 21 #include <android/hidl/base/1.0/BpHwBase.h> 22 #include <android/hidl/manager/1.0/BpHwServiceManager.h> 23 #include <android/hidl/manager/1.1/BpHwServiceManager.h> 24 #include <android/hidl/manager/1.2/BpHwServiceManager.h> 25 #include <hwbinder/IPCThreadState.h> 26 #include "InternalStatic.h" // TODO(b/69122224): remove this include, for getOrCreateCachedBinder 27 28 // C includes 29 #include <inttypes.h> 30 #include <unistd.h> 31 32 // C++ includes 33 #include <fstream> 34 #include <sstream> 35 36 namespace android { 37 namespace hardware { 38 39 hidl_binder_death_recipient::hidl_binder_death_recipient(const sp<hidl_death_recipient> &recipient, 40 uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base) : 41 mRecipient(recipient), mCookie(cookie), mBase(base) { 42 } 43 44 void hidl_binder_death_recipient::binderDied(const wp<IBinder>& /*who*/) { 45 sp<hidl_death_recipient> recipient = mRecipient.promote(); 46 if (recipient != nullptr && mBase != nullptr) { 47 recipient->serviceDied(mCookie, mBase); 48 } 49 mBase = nullptr; 50 } 51 52 wp<hidl_death_recipient> hidl_binder_death_recipient::getRecipient() { 53 return mRecipient; 54 } 55 56 const size_t hidl_handle::kOffsetOfNativeHandle = offsetof(hidl_handle, mHandle); 57 static_assert(hidl_handle::kOffsetOfNativeHandle == 0, "wrong offset"); 58 59 status_t readEmbeddedFromParcel(const hidl_handle& /* handle */, 60 const Parcel &parcel, size_t parentHandle, size_t parentOffset) { 61 const native_handle_t *handle; 62 status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle( 63 parentHandle, 64 parentOffset + hidl_handle::kOffsetOfNativeHandle, 65 &handle); 66 67 return _hidl_err; 68 } 69 70 status_t writeEmbeddedToParcel(const hidl_handle &handle, 71 Parcel *parcel, size_t parentHandle, size_t parentOffset) { 72 status_t _hidl_err = parcel->writeEmbeddedNativeHandle( 73 handle.getNativeHandle(), 74 parentHandle, 75 parentOffset + hidl_handle::kOffsetOfNativeHandle); 76 77 return _hidl_err; 78 } 79 80 const size_t hidl_memory::kOffsetOfHandle = offsetof(hidl_memory, mHandle); 81 const size_t hidl_memory::kOffsetOfName = offsetof(hidl_memory, mName); 82 static_assert(hidl_memory::kOffsetOfHandle == 0, "wrong offset"); 83 static_assert(hidl_memory::kOffsetOfName == 24, "wrong offset"); 84 85 status_t readEmbeddedFromParcel(const hidl_memory& memory, 86 const Parcel &parcel, size_t parentHandle, size_t parentOffset) { 87 // TODO(b/111883309): Invoke readEmbeddedFromParcel(hidl_handle, ...). 88 const native_handle_t *handle; 89 ::android::status_t _hidl_err = parcel.readNullableEmbeddedNativeHandle( 90 parentHandle, 91 parentOffset + hidl_memory::kOffsetOfHandle, 92 &handle); 93 94 if (_hidl_err == ::android::OK) { 95 _hidl_err = readEmbeddedFromParcel( 96 memory.name(), 97 parcel, 98 parentHandle, 99 parentOffset + hidl_memory::kOffsetOfName); 100 } 101 102 // hidl_memory's size is stored in uint64_t, but mapMemory's mmap will map 103 // size in size_t. If size is over SIZE_MAX, mapMemory could succeed 104 // but the mapped memory's actual size will be smaller than the reported size. 105 if (memory.size() > SIZE_MAX) { 106 ALOGE("Cannot use memory with %" PRId64 " bytes because it is too large.", memory.size()); 107 android_errorWriteLog(0x534e4554, "79376389"); 108 return BAD_VALUE; 109 } 110 111 return _hidl_err; 112 } 113 114 status_t writeEmbeddedToParcel(const hidl_memory &memory, 115 Parcel *parcel, size_t parentHandle, size_t parentOffset) { 116 // TODO(b/111883309): Invoke writeEmbeddedToParcel(hidl_handle, ...). 117 status_t _hidl_err = parcel->writeEmbeddedNativeHandle( 118 memory.handle(), 119 parentHandle, 120 parentOffset + hidl_memory::kOffsetOfHandle); 121 122 if (_hidl_err == ::android::OK) { 123 _hidl_err = writeEmbeddedToParcel( 124 memory.name(), 125 parcel, 126 parentHandle, 127 parentOffset + hidl_memory::kOffsetOfName); 128 } 129 130 return _hidl_err; 131 } 132 const size_t hidl_string::kOffsetOfBuffer = offsetof(hidl_string, mBuffer); 133 static_assert(hidl_string::kOffsetOfBuffer == 0, "wrong offset"); 134 135 status_t readEmbeddedFromParcel(const hidl_string &string , 136 const Parcel &parcel, size_t parentHandle, size_t parentOffset) { 137 const void *out; 138 139 status_t status = parcel.readEmbeddedBuffer( 140 string.size() + 1, 141 nullptr /* buffer_handle */, 142 parentHandle, 143 parentOffset + hidl_string::kOffsetOfBuffer, 144 &out); 145 146 if (status != OK) { 147 return status; 148 } 149 150 // Always safe to access out[string.size()] because we read size+1 bytes 151 if (static_cast<const char *>(out)[string.size()] != '\0') { 152 ALOGE("Received unterminated hidl_string buffer."); 153 return BAD_VALUE; 154 } 155 156 return OK; 157 } 158 159 status_t writeEmbeddedToParcel(const hidl_string &string, 160 Parcel *parcel, size_t parentHandle, size_t parentOffset) { 161 return parcel->writeEmbeddedBuffer( 162 string.c_str(), 163 string.size() + 1, 164 nullptr /* handle */, 165 parentHandle, 166 parentOffset + hidl_string::kOffsetOfBuffer); 167 } 168 169 status_t readFromParcel(Status *s, const Parcel& parcel) { 170 int32_t exception; 171 status_t status = parcel.readInt32(&exception); 172 if (status != OK) { 173 s->setFromStatusT(status); 174 return status; 175 } 176 177 if (exception == Status::EX_NONE) { 178 *s = Status::ok(); 179 return status; 180 } 181 182 // The remote threw an exception. Get the message back. 183 String16 message; 184 status = parcel.readString16(&message); 185 if (status != OK) { 186 s->setFromStatusT(status); 187 return status; 188 } 189 190 s->setException(exception, String8(message)); 191 192 return status; 193 } 194 195 status_t writeToParcel(const Status &s, Parcel* parcel) { 196 // Something really bad has happened, and we're not going to even 197 // try returning rich error data. 198 if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) { 199 return s.transactionError(); 200 } 201 202 status_t status = parcel->writeInt32(s.exceptionCode()); 203 if (status != OK) { return status; } 204 if (s.exceptionCode() == Status::EX_NONE) { 205 // We have no more information to write. 206 return status; 207 } 208 status = parcel->writeString16(String16(s.exceptionMessage())); 209 return status; 210 } 211 212 // assume: iface != nullptr, iface isRemote 213 // This function is to sandbox a cast through a BpHw* class into a function, so 214 // that we can remove cfi sanitization from it. Do not add additional 215 // functionality here. 216 __attribute__((no_sanitize("cfi"))) static inline BpHwRefBase* forceGetRefBase( 217 ::android::hidl::base::V1_0::IBase* ifacePtr) { 218 using ::android::hidl::base::V1_0::BpHwBase; 219 220 // canary only 221 static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_0::BpHwServiceManager)); 222 static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_1::BpHwServiceManager)); 223 static_assert(sizeof(BpHwBase) == sizeof(hidl::manager::V1_2::BpHwServiceManager)); 224 225 // All BpHw* are generated the same. This may be BpHwServiceManager, 226 // BpHwFoo, or any other class. For ABI compatibility, we can't modify the 227 // class hierarchy of these, so we have no way to get BpHwRefBase from a 228 // remote ifacePtr. 229 BpHwBase* bpBase = static_cast<BpHwBase*>(ifacePtr); 230 return static_cast<BpHwRefBase*>(bpBase); 231 } 232 233 sp<IBinder> getOrCreateCachedBinder(::android::hidl::base::V1_0::IBase* ifacePtr) { 234 if (ifacePtr == nullptr) { 235 return nullptr; 236 } 237 238 if (ifacePtr->isRemote()) { 239 BpHwRefBase* bpRefBase = forceGetRefBase(ifacePtr); 240 return sp<IBinder>(bpRefBase->remote()); 241 } 242 243 std::string descriptor = details::getDescriptor(ifacePtr); 244 if (descriptor.empty()) { 245 // interfaceDescriptor fails 246 return nullptr; 247 } 248 249 // for get + set 250 std::unique_lock<std::mutex> _lock = details::gBnMap->lock(); 251 252 wp<BHwBinder> wBnObj = details::gBnMap->getLocked(ifacePtr, nullptr); 253 sp<IBinder> sBnObj = wBnObj.promote(); 254 255 if (sBnObj == nullptr) { 256 auto func = details::getBnConstructorMap().get(descriptor, nullptr); 257 if (!func) { 258 // TODO(b/69122224): remove this static variable when prebuilts updated 259 func = details::gBnConstructorMap->get(descriptor, nullptr); 260 } 261 LOG_ALWAYS_FATAL_IF(func == nullptr, "%s gBnConstructorMap returned null for %s", __func__, 262 descriptor.c_str()); 263 264 sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr))); 265 LOG_ALWAYS_FATAL_IF(sBnObj == nullptr, "%s Bn constructor function returned null for %s", 266 __func__, descriptor.c_str()); 267 268 details::gBnMap->setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get())); 269 } 270 271 return sBnObj; 272 } 273 274 static bool gThreadPoolConfigured = false; 275 276 void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) { 277 status_t ret = ProcessState::self()->setThreadPoolConfiguration( 278 maxThreads, callerWillJoin /*callerJoinsPool*/); 279 LOG_ALWAYS_FATAL_IF(ret != OK, "Could not setThreadPoolConfiguration: %d", ret); 280 281 gThreadPoolConfigured = true; 282 } 283 284 void joinBinderRpcThreadpool() { 285 LOG_ALWAYS_FATAL_IF(!gThreadPoolConfigured, 286 "HIDL joinRpcThreadpool without calling configureRpcThreadPool."); 287 IPCThreadState::self()->joinThreadPool(); 288 } 289 290 int setupBinderPolling() { 291 int fd; 292 int err = IPCThreadState::self()->setupPolling(&fd); 293 294 LOG_ALWAYS_FATAL_IF(err != OK, "Failed to setup binder polling: %d (%s)", err, strerror(err)); 295 296 return err == OK ? fd : -1; 297 } 298 299 status_t handleBinderPoll() { 300 return IPCThreadState::self()->handlePolledCommands(); 301 } 302 303 void addPostCommandTask(const std::function<void(void)> task) { 304 IPCThreadState::self()->addPostCommandTask(task); 305 } 306 307 } // namespace hardware 308 } // namespace android 309