• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <hwbinder/Binder.h>
18 
19 #include <android-base/macros.h>
20 #include <cutils/android_filesystem_config.h>
21 #include <cutils/multiuser.h>
22 #include <hwbinder/BpHwBinder.h>
23 #include <hwbinder/IInterface.h>
24 #include <hwbinder/IPCThreadState.h>
25 #include <hwbinder/Parcel.h>
26 #include <utils/Log.h>
27 #include <utils/misc.h>
28 
29 #include <linux/sched.h>
30 #include <stdio.h>
31 
32 #include <atomic>
33 
34 namespace android {
35 namespace hardware {
36 
37 // ---------------------------------------------------------------------------
38 
IBinder()39 IBinder::IBinder()
40     : RefBase()
41 {
42 }
43 
~IBinder()44 IBinder::~IBinder()
45 {
46 }
47 
48 // ---------------------------------------------------------------------------
49 
localBinder()50 BHwBinder* IBinder::localBinder()
51 {
52     return nullptr;
53 }
54 
remoteBinder()55 BpHwBinder* IBinder::remoteBinder()
56 {
57     return nullptr;
58 }
59 
checkSubclass(const void *) const60 bool IBinder::checkSubclass(const void* /*subclassID*/) const
61 {
62     return false;
63 }
64 
65 // ---------------------------------------------------------------------------
66 
67 class BHwBinder::Extras
68 {
69 public:
70     // unlocked objects
71     bool mRequestingSid = false;
72 
73     // for below objects
74     Mutex mLock;
75     BpHwBinder::ObjectManager mObjects;
76 };
77 
78 // ---------------------------------------------------------------------------
79 
BHwBinder()80 BHwBinder::BHwBinder() : mSchedPolicy(SCHED_NORMAL), mSchedPriority(0), mExtras(nullptr)
81 {
82 }
83 
getMinSchedulingPolicy()84 int BHwBinder::getMinSchedulingPolicy() {
85     return mSchedPolicy;
86 }
87 
getMinSchedulingPriority()88 int BHwBinder::getMinSchedulingPriority() {
89     return mSchedPriority;
90 }
91 
isRequestingSid()92 bool BHwBinder::isRequestingSid() {
93     Extras* e = mExtras.load(std::memory_order_acquire);
94 
95     return e && e->mRequestingSid;
96 }
97 
setRequestingSid(bool requestingSid)98 void BHwBinder::setRequestingSid(bool requestingSid) {
99     Extras* e = mExtras.load(std::memory_order_acquire);
100 
101     if (!e) {
102         // default is false. Most things don't need sids, so avoiding allocations when possible.
103         if (!requestingSid) {
104             return;
105         }
106 
107         e = getOrCreateExtras();
108         if (!e) return; // out of memory
109     }
110 
111     e->mRequestingSid = requestingSid;
112 }
113 
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags,TransactCallback callback)114 status_t BHwBinder::transact(
115     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
116 {
117     data.setDataPosition(0);
118 
119     if (reply != nullptr && (flags & FLAG_CLEAR_BUF)) {
120         reply->markSensitive();
121     }
122 
123     // extra comment to try to force running all tests
124     if (UNLIKELY(code == HIDL_DEBUG_TRANSACTION)) {
125         uid_t uid = IPCThreadState::self()->getCallingUid();
126         if (multiuser_get_app_id(uid) >= AID_APP_START) {
127             ALOGE("Can not call IBase::debug from apps");
128             return PERMISSION_DENIED;
129         }
130     }
131 
132     status_t err = NO_ERROR;
133     switch (code) {
134         default:
135             err = onTransact(code, data, reply, flags,
136                     [&](auto &replyParcel) {
137                         replyParcel.setDataPosition(0);
138                         if (callback != nullptr) {
139                             callback(replyParcel);
140                         }
141                     });
142             break;
143     }
144 
145     return err;
146 }
147 
linkToDeath(const sp<DeathRecipient> &,void *,uint32_t)148 status_t BHwBinder::linkToDeath(
149     const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
150     uint32_t /*flags*/)
151 {
152     return INVALID_OPERATION;
153 }
154 
unlinkToDeath(const wp<DeathRecipient> &,void *,uint32_t,wp<DeathRecipient> *)155 status_t BHwBinder::unlinkToDeath(
156     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
157     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
158 {
159     return INVALID_OPERATION;
160 }
161 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)162 void BHwBinder::attachObject(
163     const void* objectID, void* object, void* cleanupCookie,
164     object_cleanup_func func)
165 {
166     Extras* e = getOrCreateExtras();
167     if (!e) return; // out of memory
168 
169     AutoMutex _l(e->mLock);
170     e->mObjects.attach(objectID, object, cleanupCookie, func);
171 }
172 
findObject(const void * objectID) const173 void* BHwBinder::findObject(const void* objectID) const
174 {
175     Extras* e = mExtras.load(std::memory_order_acquire);
176     if (!e) return nullptr;
177 
178     AutoMutex _l(e->mLock);
179     return e->mObjects.find(objectID);
180 }
181 
detachObject(const void * objectID)182 void BHwBinder::detachObject(const void* objectID)
183 {
184     Extras* e = mExtras.load(std::memory_order_acquire);
185     if (!e) return;
186 
187     AutoMutex _l(e->mLock);
188     e->mObjects.detach(objectID);
189 }
190 
localBinder()191 BHwBinder* BHwBinder::localBinder()
192 {
193     return this;
194 }
195 
~BHwBinder()196 BHwBinder::~BHwBinder()
197 {
198     Extras* e = mExtras.load(std::memory_order_relaxed);
199     if (e) delete e;
200 }
201 
202 
onTransact(uint32_t,const Parcel &,Parcel *,uint32_t,TransactCallback)203 status_t BHwBinder::onTransact(
204     uint32_t /*code*/, const Parcel& /*data*/, Parcel* /*reply*/, uint32_t /*flags*/,
205     TransactCallback /*callback*/)
206 {
207     return UNKNOWN_TRANSACTION;
208 }
209 
getOrCreateExtras()210 BHwBinder::Extras* BHwBinder::getOrCreateExtras()
211 {
212     Extras* e = mExtras.load(std::memory_order_acquire);
213 
214     if (!e) {
215         e = new Extras;
216         Extras* expected = nullptr;
217         if (!mExtras.compare_exchange_strong(expected, e,
218                                              std::memory_order_release,
219                                              std::memory_order_acquire)) {
220             delete e;
221             e = expected;  // Filled in by CAS
222         }
223         if (e == nullptr) return nullptr; // out of memory
224     }
225 
226     return e;
227 }
228 
229 // ---------------------------------------------------------------------------
230 
231 enum {
232     // This is used to transfer ownership of the remote binder from
233     // the BpHwRefBase object holding it (when it is constructed), to the
234     // owner of the BpHwRefBase object when it first acquires that BpHwRefBase.
235     kRemoteAcquired = 0x00000001
236 };
237 
BpHwRefBase(const sp<IBinder> & o)238 BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)
239     : mRemote(o.get()), mRefs(nullptr), mState(0)
240 {
241     if (mRemote) {
242         mRemote->incStrong(this);           // Removed on first IncStrong().
243     }
244 }
245 
~BpHwRefBase()246 BpHwRefBase::~BpHwRefBase()
247 {
248     if (mRemote) {
249         if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
250             mRemote->decStrong(this);
251         }
252     }
253 }
254 
onFirstRef()255 void BpHwRefBase::onFirstRef()
256 {
257     mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
258 }
259 
onLastStrongRef(const void *)260 void BpHwRefBase::onLastStrongRef(const void* /*id*/)
261 {
262     if (mRemote) {
263         mRemote->decStrong(this);
264     }
265 }
266 
onIncStrongAttempted(uint32_t,const void *)267 bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
268 {
269     return false;
270 }
271 
272 // ---------------------------------------------------------------------------
273 
274 } // namespace hardware
275 } // namespace android
276