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 
ObjectManager()53 BpBinder::ObjectManager::ObjectManager()
54 {
55 }
56 
~ObjectManager()57 BpBinder::ObjectManager::~ObjectManager()
58 {
59     kill();
60 }
61 
attach(const void * objectID,void * object,void * cleanupCookie,IBinder::object_cleanup_func func)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 
find(const void * objectID) const80 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 
detach(const void * objectID)87 void BpBinder::ObjectManager::detach(const void* objectID)
88 {
89     mObjects.removeItem(objectID);
90 }
91 
kill()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 
create(int32_t handle)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 
BpBinder(int32_t handle,int32_t trackedUid)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 
isDescriptorCached() const151 bool BpBinder::isDescriptorCached() const {
152     Mutex::Autolock _l(mLock);
153     return mDescriptorCache.size() ? true : false;
154 }
155 
getInterfaceDescriptor() const156 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 
isBinderAlive() const180 bool BpBinder::isBinderAlive() const
181 {
182     return mAlive != 0;
183 }
184 
pingBinder()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 
dump(int fd,const Vector<String16> & args)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 
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)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 
linkToDeath(const sp<DeathRecipient> & recipient,void * cookie,uint32_t flags)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 
unlinkToDeath(const wp<DeathRecipient> & recipient,void * cookie,uint32_t flags,wp<DeathRecipient> * outRecipient)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 
sendObituary()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 
reportOneDeath(const Obituary & obit)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 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)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 
findObject(const void * objectID) const344 void* BpBinder::findObject(const void* objectID) const
345 {
346     AutoMutex _l(mLock);
347     return mObjects.find(objectID);
348 }
349 
detachObject(const void * objectID)350 void BpBinder::detachObject(const void* objectID)
351 {
352     AutoMutex _l(mLock);
353     mObjects.detach(objectID);
354 }
355 
remoteBinder()356 BpBinder* BpBinder::remoteBinder()
357 {
358     return this;
359 }
360 
~BpBinder()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 
onFirstRef()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 
onLastStrongRef(const void *)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 
onIncStrongAttempted(uint32_t,const void *)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 
getBinderProxyCount(uint32_t uid)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 
getCountByUid(Vector<uint32_t> & uids,Vector<uint32_t> & counts)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 
enableCountByUid()453 void BpBinder::enableCountByUid() { sCountByUidEnabled.store(true); }
disableCountByUid()454 void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
setCountByUidEnabled(bool enable)455 void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
456 
setLimitCallback(binder_proxy_limit_callback cb)457 void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
458     AutoMutex _l(sTrackingLock);
459     sLimitCallback = cb;
460 }
461 
setBinderProxyCountWatermarks(int high,int low)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