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 return onTransact(code, data, reply, flags, [&](auto& replyParcel) {
133 replyParcel.setDataPosition(0);
134 if (callback != nullptr) {
135 callback(replyParcel);
136 }
137 });
138 }
139
linkToDeath(const sp<DeathRecipient> &,void *,uint32_t)140 status_t BHwBinder::linkToDeath(
141 const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
142 uint32_t /*flags*/)
143 {
144 return INVALID_OPERATION;
145 }
146
unlinkToDeath(const wp<DeathRecipient> &,void *,uint32_t,wp<DeathRecipient> *)147 status_t BHwBinder::unlinkToDeath(
148 const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
149 uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
150 {
151 return INVALID_OPERATION;
152 }
153
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)154 void BHwBinder::attachObject(
155 const void* objectID, void* object, void* cleanupCookie,
156 object_cleanup_func func)
157 {
158 Extras* e = getOrCreateExtras();
159 if (!e) return; // out of memory
160
161 AutoMutex _l(e->mLock);
162 e->mObjects.attach(objectID, object, cleanupCookie, func);
163 }
164
findObject(const void * objectID) const165 void* BHwBinder::findObject(const void* objectID) const
166 {
167 Extras* e = mExtras.load(std::memory_order_acquire);
168 if (!e) return nullptr;
169
170 AutoMutex _l(e->mLock);
171 return e->mObjects.find(objectID);
172 }
173
detachObject(const void * objectID)174 void BHwBinder::detachObject(const void* objectID)
175 {
176 Extras* e = mExtras.load(std::memory_order_acquire);
177 if (!e) return;
178
179 AutoMutex _l(e->mLock);
180 e->mObjects.detach(objectID);
181 }
182
localBinder()183 BHwBinder* BHwBinder::localBinder()
184 {
185 return this;
186 }
187
~BHwBinder()188 BHwBinder::~BHwBinder()
189 {
190 Extras* e = mExtras.load(std::memory_order_relaxed);
191 if (e) delete e;
192 }
193
194
onTransact(uint32_t,const Parcel &,Parcel *,uint32_t,TransactCallback)195 status_t BHwBinder::onTransact(
196 uint32_t /*code*/, const Parcel& /*data*/, Parcel* /*reply*/, uint32_t /*flags*/,
197 TransactCallback /*callback*/)
198 {
199 return UNKNOWN_TRANSACTION;
200 }
201
getOrCreateExtras()202 BHwBinder::Extras* BHwBinder::getOrCreateExtras()
203 {
204 Extras* e = mExtras.load(std::memory_order_acquire);
205
206 if (!e) {
207 e = new Extras;
208 Extras* expected = nullptr;
209 if (!mExtras.compare_exchange_strong(expected, e,
210 std::memory_order_release,
211 std::memory_order_acquire)) {
212 delete e;
213 e = expected; // Filled in by CAS
214 }
215 if (e == nullptr) return nullptr; // out of memory
216 }
217
218 return e;
219 }
220
221 // ---------------------------------------------------------------------------
222
223 enum {
224 // This is used to transfer ownership of the remote binder from
225 // the BpHwRefBase object holding it (when it is constructed), to the
226 // owner of the BpHwRefBase object when it first acquires that BpHwRefBase.
227 kRemoteAcquired = 0x00000001
228 };
229
BpHwRefBase(const sp<IBinder> & o)230 BpHwRefBase::BpHwRefBase(const sp<IBinder>& o)
231 : mRemote(o.get()), mRefs(nullptr), mState(0)
232 {
233 if (mRemote) {
234 mRemote->incStrong(this); // Removed on first IncStrong().
235 }
236 }
237
~BpHwRefBase()238 BpHwRefBase::~BpHwRefBase()
239 {
240 if (mRemote) {
241 if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
242 mRemote->decStrong(this);
243 }
244 }
245 }
246
onFirstRef()247 void BpHwRefBase::onFirstRef()
248 {
249 mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
250 }
251
onLastStrongRef(const void *)252 void BpHwRefBase::onLastStrongRef(const void* /*id*/)
253 {
254 if (mRemote) {
255 mRemote->decStrong(this);
256 }
257 }
258
onIncStrongAttempted(uint32_t,const void *)259 bool BpHwRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
260 {
261 return false;
262 }
263
264 // ---------------------------------------------------------------------------
265
266 } // namespace hardware
267 } // namespace android
268