1/* 2 * Copyright (C) 2005 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 "BpBinder" 18//#define LOG_NDEBUG 0 19 20#include <binder/BpBinder.h> 21 22#include <binder/IPCThreadState.h> 23#include <binder/IResultReceiver.h> 24#include <cutils/compiler.h> 25#include <utils/Log.h> 26 27#include <stdio.h> 28 29//#undef ALOGV 30//#define ALOGV(...) fprintf(stderr, __VA_ARGS__) 31 32namespace android { 33 34// --------------------------------------------------------------------------- 35 36Mutex BpBinder::sTrackingLock; 37std::unordered_map<int32_t,uint32_t> BpBinder::sTrackingMap; 38int BpBinder::sNumTrackedUids = 0; 39std::atomic_bool BpBinder::sCountByUidEnabled(false); 40binder_proxy_limit_callback BpBinder::sLimitCallback; 41bool BpBinder::sBinderProxyThrottleCreate = false; 42 43// Arbitrarily high value that probably distinguishes a bad behaving app 44uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500; 45// Another arbitrary value a binder count needs to drop below before another callback will be called 46uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000; 47 48enum { 49 LIMIT_REACHED_MASK = 0x80000000, // A flag denoting that the limit has been reached 50 COUNTING_VALUE_MASK = 0x7FFFFFFF, // A mask of the remaining bits for the count value 51}; 52 53BpBinder::ObjectManager::ObjectManager() 54{ 55} 56 57BpBinder::ObjectManager::~ObjectManager() 58{ 59 kill(); 60} 61 62void BpBinder::ObjectManager::attach( 63 const void* objectID, void* object, void* cleanupCookie, 64 IBinder::object_cleanup_func func) 65{ 66 entry_t e; 67 e.object = object; 68 e.cleanupCookie = cleanupCookie; 69 e.func = func; 70 71 if (mObjects.indexOfKey(objectID) >= 0) { 72 ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use", 73 objectID, this, object); 74 return; 75 } 76 77 mObjects.add(objectID, e); 78} 79 80void* BpBinder::ObjectManager::find(const void* objectID) const 81{ 82 const ssize_t i = mObjects.indexOfKey(objectID); 83 if (i < 0) return NULL; 84 return mObjects.valueAt(i).object; 85} 86 87void BpBinder::ObjectManager::detach(const void* objectID) 88{ 89 mObjects.removeItem(objectID); 90} 91 92void BpBinder::ObjectManager::kill() 93{ 94 const size_t N = mObjects.size(); 95 ALOGV("Killing %zu objects in manager %p", N, this); 96 for (size_t i=0; i<N; i++) { 97 const entry_t& e = mObjects.valueAt(i); 98 if (e.func != NULL) { 99 e.func(mObjects.keyAt(i), e.object, e.cleanupCookie); 100 } 101 } 102 103 mObjects.clear(); 104} 105 106// --------------------------------------------------------------------------- 107 108 109BpBinder* BpBinder::create(int32_t handle) { 110 int32_t trackedUid = -1; 111 if (sCountByUidEnabled) { 112 trackedUid = IPCThreadState::self()->getCallingUid(); 113 AutoMutex _l(sTrackingLock); 114 uint32_t trackedValue = sTrackingMap[trackedUid]; 115 if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) { 116 if (sBinderProxyThrottleCreate) { 117 return nullptr; 118 } 119 } else { 120 if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) { 121 ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)", 122 getuid(), trackedUid, trackedValue); 123 sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK; 124 if (sLimitCallback) sLimitCallback(trackedUid); 125 if (sBinderProxyThrottleCreate) { 126 ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy" 127 " count drops below %d", 128 trackedUid, getuid(), sBinderProxyCountLowWatermark); 129 return nullptr; 130 } 131 } 132 } 133 sTrackingMap[trackedUid]++; 134 } 135 return new BpBinder(handle, trackedUid); 136} 137 138BpBinder::BpBinder(int32_t handle, int32_t trackedUid) 139 : mHandle(handle) 140 , mAlive(1) 141 , mObitsSent(0) 142 , mObituaries(NULL) 143 , mTrackedUid(trackedUid) 144{ 145 ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); 146 147 extendObjectLifetime(OBJECT_LIFETIME_WEAK); 148 IPCThreadState::self()->incWeakHandle(handle, this); 149} 150 151bool BpBinder::isDescriptorCached() const { 152 Mutex::Autolock _l(mLock); 153 return mDescriptorCache.size() ? true : false; 154} 155 156const String16& BpBinder::getInterfaceDescriptor() const 157{ 158 if (isDescriptorCached() == false) { 159 Parcel send, reply; 160 // do the IPC without a lock held. 161 status_t err = const_cast<BpBinder*>(this)->transact( 162 INTERFACE_TRANSACTION, send, &reply); 163 if (err == NO_ERROR) { 164 String16 res(reply.readString16()); 165 Mutex::Autolock _l(mLock); 166 // mDescriptorCache could have been assigned while the lock was 167 // released. 168 if (mDescriptorCache.size() == 0) 169 mDescriptorCache = res; 170 } 171 } 172 173 // we're returning a reference to a non-static object here. Usually this 174 // is not something smart to do, however, with binder objects it is 175 // (usually) safe because they are reference-counted. 176 177 return mDescriptorCache; 178} 179 180bool BpBinder::isBinderAlive() const 181{ 182 return mAlive != 0; 183} 184 185status_t BpBinder::pingBinder() 186{ 187 Parcel send; 188 Parcel reply; 189 status_t err = transact(PING_TRANSACTION, send, &reply); 190 if (err != NO_ERROR) return err; 191 if (reply.dataSize() < sizeof(status_t)) return NOT_ENOUGH_DATA; 192 return (status_t)reply.readInt32(); 193} 194 195status_t BpBinder::dump(int fd, const Vector<String16>& args) 196{ 197 Parcel send; 198 Parcel reply; 199 send.writeFileDescriptor(fd); 200 const size_t numArgs = args.size(); 201 send.writeInt32(numArgs); 202 for (size_t i = 0; i < numArgs; i++) { 203 send.writeString16(args[i]); 204 } 205 status_t err = transact(DUMP_TRANSACTION, send, &reply); 206 return err; 207} 208 209status_t BpBinder::transact( 210 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 211{ 212 // Once a binder has died, it will never come back to life. 213 if (mAlive) { 214 status_t status = IPCThreadState::self()->transact( 215 mHandle, code, data, reply, flags); 216 if (status == DEAD_OBJECT) mAlive = 0; 217 return status; 218 } 219 220 return DEAD_OBJECT; 221} 222 223status_t BpBinder::linkToDeath( 224 const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) 225{ 226 Obituary ob; 227 ob.recipient = recipient; 228 ob.cookie = cookie; 229 ob.flags = flags; 230 231 LOG_ALWAYS_FATAL_IF(recipient == NULL, 232 "linkToDeath(): recipient must be non-NULL"); 233 234 { 235 AutoMutex _l(mLock); 236 237 if (!mObitsSent) { 238 if (!mObituaries) { 239 mObituaries = new Vector<Obituary>; 240 if (!mObituaries) { 241 return NO_MEMORY; 242 } 243 ALOGV("Requesting death notification: %p handle %d\n", this, mHandle); 244 getWeakRefs()->incWeak(this); 245 IPCThreadState* self = IPCThreadState::self(); 246 self->requestDeathNotification(mHandle, this); 247 self->flushCommands(); 248 } 249 ssize_t res = mObituaries->add(ob); 250 return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res; 251 } 252 } 253 254 return DEAD_OBJECT; 255} 256 257status_t BpBinder::unlinkToDeath( 258 const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, 259 wp<DeathRecipient>* outRecipient) 260{ 261 AutoMutex _l(mLock); 262 263 if (mObitsSent) { 264 return DEAD_OBJECT; 265 } 266 267 const size_t N = mObituaries ? mObituaries->size() : 0; 268 for (size_t i=0; i<N; i++) { 269 const Obituary& obit = mObituaries->itemAt(i); 270 if ((obit.recipient == recipient 271 || (recipient == NULL && obit.cookie == cookie)) 272 && obit.flags == flags) { 273 if (outRecipient != NULL) { 274 *outRecipient = mObituaries->itemAt(i).recipient; 275 } 276 mObituaries->removeAt(i); 277 if (mObituaries->size() == 0) { 278 ALOGV("Clearing death notification: %p handle %d\n", this, mHandle); 279 IPCThreadState* self = IPCThreadState::self(); 280 self->clearDeathNotification(mHandle, this); 281 self->flushCommands(); 282 delete mObituaries; 283 mObituaries = NULL; 284 } 285 return NO_ERROR; 286 } 287 } 288 289 return NAME_NOT_FOUND; 290} 291 292void BpBinder::sendObituary() 293{ 294 ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", 295 this, mHandle, mObitsSent ? "true" : "false"); 296 297 mAlive = 0; 298 if (mObitsSent) return; 299 300 mLock.lock(); 301 Vector<Obituary>* obits = mObituaries; 302 if(obits != NULL) { 303 ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle); 304 IPCThreadState* self = IPCThreadState::self(); 305 self->clearDeathNotification(mHandle, this); 306 self->flushCommands(); 307 mObituaries = NULL; 308 } 309 mObitsSent = 1; 310 mLock.unlock(); 311 312 ALOGV("Reporting death of proxy %p for %zu recipients\n", 313 this, obits ? obits->size() : 0U); 314 315 if (obits != NULL) { 316 const size_t N = obits->size(); 317 for (size_t i=0; i<N; i++) { 318 reportOneDeath(obits->itemAt(i)); 319 } 320 321 delete obits; 322 } 323} 324 325void BpBinder::reportOneDeath(const Obituary& obit) 326{ 327 sp<DeathRecipient> recipient = obit.recipient.promote(); 328 ALOGV("Reporting death to recipient: %p\n", recipient.get()); 329 if (recipient == NULL) return; 330 331 recipient->binderDied(this); 332} 333 334 335void BpBinder::attachObject( 336 const void* objectID, void* object, void* cleanupCookie, 337 object_cleanup_func func) 338{ 339 AutoMutex _l(mLock); 340 ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects); 341 mObjects.attach(objectID, object, cleanupCookie, func); 342} 343 344void* BpBinder::findObject(const void* objectID) const 345{ 346 AutoMutex _l(mLock); 347 return mObjects.find(objectID); 348} 349 350void BpBinder::detachObject(const void* objectID) 351{ 352 AutoMutex _l(mLock); 353 mObjects.detach(objectID); 354} 355 356BpBinder* BpBinder::remoteBinder() 357{ 358 return this; 359} 360 361BpBinder::~BpBinder() 362{ 363 ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle); 364 365 IPCThreadState* ipc = IPCThreadState::self(); 366 367 if (mTrackedUid >= 0) { 368 AutoMutex _l(sTrackingLock); 369 uint32_t trackedValue = sTrackingMap[mTrackedUid]; 370 if (CC_UNLIKELY((trackedValue & COUNTING_VALUE_MASK) == 0)) { 371 ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, mHandle); 372 } else { 373 if (CC_UNLIKELY( 374 (trackedValue & LIMIT_REACHED_MASK) && 375 ((trackedValue & COUNTING_VALUE_MASK) <= sBinderProxyCountLowWatermark) 376 )) { 377 ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)", 378 getuid(), mTrackedUid, sBinderProxyCountLowWatermark); 379 sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK; 380 } 381 if (--sTrackingMap[mTrackedUid] == 0) { 382 sTrackingMap.erase(mTrackedUid); 383 } 384 } 385 } 386 387 mLock.lock(); 388 Vector<Obituary>* obits = mObituaries; 389 if(obits != NULL) { 390 if (ipc) ipc->clearDeathNotification(mHandle, this); 391 mObituaries = NULL; 392 } 393 mLock.unlock(); 394 395 if (obits != NULL) { 396 // XXX Should we tell any remaining DeathRecipient 397 // objects that the last strong ref has gone away, so they 398 // are no longer linked? 399 delete obits; 400 } 401 402 if (ipc) { 403 ipc->expungeHandle(mHandle, this); 404 ipc->decWeakHandle(mHandle); 405 } 406} 407 408void BpBinder::onFirstRef() 409{ 410 ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle); 411 IPCThreadState* ipc = IPCThreadState::self(); 412 if (ipc) ipc->incStrongHandle(mHandle, this); 413} 414 415void BpBinder::onLastStrongRef(const void* /*id*/) 416{ 417 ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle); 418 IF_ALOGV() { 419 printRefs(); 420 } 421 IPCThreadState* ipc = IPCThreadState::self(); 422 if (ipc) ipc->decStrongHandle(mHandle); 423} 424 425bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/) 426{ 427 ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle); 428 IPCThreadState* ipc = IPCThreadState::self(); 429 return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false; 430} 431 432uint32_t BpBinder::getBinderProxyCount(uint32_t uid) 433{ 434 AutoMutex _l(sTrackingLock); 435 auto it = sTrackingMap.find(uid); 436 if (it != sTrackingMap.end()) { 437 return it->second & COUNTING_VALUE_MASK; 438 } 439 return 0; 440} 441 442void BpBinder::getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts) 443{ 444 AutoMutex _l(sTrackingLock); 445 uids.setCapacity(sTrackingMap.size()); 446 counts.setCapacity(sTrackingMap.size()); 447 for (const auto& it : sTrackingMap) { 448 uids.push_back(it.first); 449 counts.push_back(it.second & COUNTING_VALUE_MASK); 450 } 451} 452 453void BpBinder::enableCountByUid() { sCountByUidEnabled.store(true); } 454void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); } 455void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); } 456 457void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) { 458 AutoMutex _l(sTrackingLock); 459 sLimitCallback = cb; 460} 461 462void BpBinder::setBinderProxyCountWatermarks(int high, int low) { 463 AutoMutex _l(sTrackingLock); 464 sBinderProxyCountHighWatermark = high; 465 sBinderProxyCountLowWatermark = low; 466} 467 468// --------------------------------------------------------------------------- 469 470}; // namespace android 471