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 39 IBinder::IBinder() 40 : RefBase() 41 { 42 } 43 44 IBinder::~IBinder() 45 { 46 } 47 48 // --------------------------------------------------------------------------- 49 50 BHwBinder* IBinder::localBinder() 51 { 52 return nullptr; 53 } 54 55 BpHwBinder* IBinder::remoteBinder() 56 { 57 return nullptr; 58 } 59 60 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 80 BHwBinder::BHwBinder() : mSchedPolicy(SCHED_NORMAL), mSchedPriority(0), mExtras(nullptr) 81 { 82 } 83 84 int BHwBinder::getMinSchedulingPolicy() { 85 return mSchedPolicy; 86 } 87 88 int BHwBinder::getMinSchedulingPriority() { 89 return mSchedPriority; 90 } 91 92 bool BHwBinder::isRequestingSid() { 93 Extras* e = mExtras.load(std::memory_order_acquire); 94 95 return e && e->mRequestingSid; 96 } 97 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 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 148 status_t BHwBinder::linkToDeath( 149 const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/, 150 uint32_t /*flags*/) 151 { 152 return INVALID_OPERATION; 153 } 154 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 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 173 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 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 191 BHwBinder* BHwBinder::localBinder() 192 { 193 return this; 194 } 195 196 BHwBinder::~BHwBinder() 197 { 198 Extras* e = mExtras.load(std::memory_order_relaxed); 199 if (e) delete e; 200 } 201 202 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 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 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 246 BpHwRefBase::~BpHwRefBase() 247 { 248 if (mRemote) { 249 if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) { 250 mRemote->decStrong(this); 251 } 252 } 253 } 254 255 void BpHwRefBase::onFirstRef() 256 { 257 mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed); 258 } 259 260 void BpHwRefBase::onLastStrongRef(const void* /*id*/) 261 { 262 if (mRemote) { 263 mRemote->decStrong(this); 264 } 265 } 266 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