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