Home | History | Annotate | Download | only in binder
      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 
     32 namespace android {
     33 
     34 // ---------------------------------------------------------------------------
     35 
     36 Mutex BpBinder::sTrackingLock;
     37 std::unordered_map<int32_t,uint32_t> BpBinder::sTrackingMap;
     38 int BpBinder::sNumTrackedUids = 0;
     39 std::atomic_bool BpBinder::sCountByUidEnabled(false);
     40 binder_proxy_limit_callback BpBinder::sLimitCallback;
     41 bool BpBinder::sBinderProxyThrottleCreate = false;
     42 
     43 // Arbitrarily high value that probably distinguishes a bad behaving app
     44 uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
     45 // Another arbitrary value a binder count needs to drop below before another callback will be called
     46 uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
     47 
     48 enum {
     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 
     53 BpBinder::ObjectManager::ObjectManager()
     54 {
     55 }
     56 
     57 BpBinder::ObjectManager::~ObjectManager()
     58 {
     59     kill();
     60 }
     61 
     62 void 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 
     80 void* 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 
     87 void BpBinder::ObjectManager::detach(const void* objectID)
     88 {
     89     mObjects.removeItem(objectID);
     90 }
     91 
     92 void 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 
    109 BpBinder* 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 
    138 BpBinder::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 
    151 bool BpBinder::isDescriptorCached() const {
    152     Mutex::Autolock _l(mLock);
    153     return mDescriptorCache.size() ? true : false;
    154 }
    155 
    156 const 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 
    180 bool BpBinder::isBinderAlive() const
    181 {
    182     return mAlive != 0;
    183 }
    184 
    185 status_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 
    195 status_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 
    209 status_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 
    223 status_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 
    257 status_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 
    292 void 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 
    325 void 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 
    335 void 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 
    344 void* BpBinder::findObject(const void* objectID) const
    345 {
    346     AutoMutex _l(mLock);
    347     return mObjects.find(objectID);
    348 }
    349 
    350 void BpBinder::detachObject(const void* objectID)
    351 {
    352     AutoMutex _l(mLock);
    353     mObjects.detach(objectID);
    354 }
    355 
    356 BpBinder* BpBinder::remoteBinder()
    357 {
    358     return this;
    359 }
    360 
    361 BpBinder::~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 
    408 void 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 
    415 void 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 
    425 bool 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 
    432 uint32_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 
    442 void 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 
    453 void BpBinder::enableCountByUid() { sCountByUidEnabled.store(true); }
    454 void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
    455 void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
    456 
    457 void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
    458     AutoMutex _l(sTrackingLock);
    459     sLimitCallback = cb;
    460 }
    461 
    462 void BpBinder::setBinderProxyCountWatermarks(int high, int low) {
    463     AutoMutex _l(sTrackingLock);
    464     sBinderProxyCountHighWatermark = high;
    465     sBinderProxyCountLowWatermark = low;
    466 }
    467 
    468 // ---------------------------------------------------------------------------
    469 
    470 }; // namespace android
    471