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 <binder/Binder.h>
18 
19 #include <atomic>
20 #include <utils/misc.h>
21 #include <binder/BpBinder.h>
22 #include <binder/IInterface.h>
23 #include <binder/IResultReceiver.h>
24 #include <binder/IShellCallback.h>
25 #include <binder/Parcel.h>
26 
27 #include <linux/sched.h>
28 #include <stdio.h>
29 
30 namespace android {
31 
32 // ---------------------------------------------------------------------------
33 
IBinder()34 IBinder::IBinder()
35     : RefBase()
36 {
37 }
38 
~IBinder()39 IBinder::~IBinder()
40 {
41 }
42 
43 // ---------------------------------------------------------------------------
44 
queryLocalInterface(const String16 &)45 sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
46 {
47     return nullptr;
48 }
49 
localBinder()50 BBinder* IBinder::localBinder()
51 {
52     return nullptr;
53 }
54 
remoteBinder()55 BpBinder* 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 
shellCommand(const sp<IBinder> & target,int in,int out,int err,Vector<String16> & args,const sp<IShellCallback> & callback,const sp<IResultReceiver> & resultReceiver)66 status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int err,
67     Vector<String16>& args, const sp<IShellCallback>& callback,
68     const sp<IResultReceiver>& resultReceiver)
69 {
70     Parcel send;
71     Parcel reply;
72     send.writeFileDescriptor(in);
73     send.writeFileDescriptor(out);
74     send.writeFileDescriptor(err);
75     const size_t numArgs = args.size();
76     send.writeInt32(numArgs);
77     for (size_t i = 0; i < numArgs; i++) {
78         send.writeString16(args[i]);
79     }
80     send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);
81     send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);
82     return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
83 }
84 
getExtension(sp<IBinder> * out)85 status_t IBinder::getExtension(sp<IBinder>* out) {
86     BBinder* local = this->localBinder();
87     if (local != nullptr) {
88         *out = local->getExtension();
89         return OK;
90     }
91 
92     BpBinder* proxy = this->remoteBinder();
93     LOG_ALWAYS_FATAL_IF(proxy == nullptr);
94 
95     Parcel data;
96     Parcel reply;
97     status_t status = transact(EXTENSION_TRANSACTION, data, &reply);
98     if (status != OK) return status;
99 
100     return reply.readNullableStrongBinder(out);
101 }
102 
getDebugPid(pid_t * out)103 status_t IBinder::getDebugPid(pid_t* out) {
104     BBinder* local = this->localBinder();
105     if (local != nullptr) {
106       *out = local->getDebugPid();
107       return OK;
108     }
109 
110     BpBinder* proxy = this->remoteBinder();
111     LOG_ALWAYS_FATAL_IF(proxy == nullptr);
112 
113     Parcel data;
114     Parcel reply;
115     status_t status = transact(DEBUG_PID_TRANSACTION, data, &reply);
116     if (status != OK) return status;
117 
118     int32_t pid;
119     status = reply.readInt32(&pid);
120     if (status != OK) return status;
121 
122     if (pid < 0 || pid > std::numeric_limits<pid_t>::max()) {
123         return BAD_VALUE;
124     }
125     *out = pid;
126     return OK;
127 }
128 
129 // ---------------------------------------------------------------------------
130 
131 class BBinder::Extras
132 {
133 public:
134     // unlocked objects
135     bool mRequestingSid = false;
136     sp<IBinder> mExtension;
137     int mPolicy = SCHED_NORMAL;
138     int mPriority = 0;
139 
140     // for below objects
141     Mutex mLock;
142     BpBinder::ObjectManager mObjects;
143 };
144 
145 // ---------------------------------------------------------------------------
146 
BBinder()147 BBinder::BBinder() : mExtras(nullptr), mStability(0)
148 {
149 }
150 
isBinderAlive() const151 bool BBinder::isBinderAlive() const
152 {
153     return true;
154 }
155 
pingBinder()156 status_t BBinder::pingBinder()
157 {
158     return NO_ERROR;
159 }
160 
getInterfaceDescriptor() const161 const String16& BBinder::getInterfaceDescriptor() const
162 {
163     // This is a local static rather than a global static,
164     // to avoid static initializer ordering issues.
165     static String16 sEmptyDescriptor;
166     ALOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
167     return sEmptyDescriptor;
168 }
169 
170 // NOLINTNEXTLINE(google-default-arguments)
transact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)171 status_t BBinder::transact(
172     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
173 {
174     data.setDataPosition(0);
175 
176     status_t err = NO_ERROR;
177     switch (code) {
178         case PING_TRANSACTION:
179             err = pingBinder();
180             break;
181         case EXTENSION_TRANSACTION:
182             err = reply->writeStrongBinder(getExtension());
183             break;
184         case DEBUG_PID_TRANSACTION:
185             err = reply->writeInt32(getDebugPid());
186             break;
187         default:
188             err = onTransact(code, data, reply, flags);
189             break;
190     }
191 
192     // In case this is being transacted on in the same process.
193     if (reply != nullptr) {
194         reply->setDataPosition(0);
195     }
196 
197     return err;
198 }
199 
200 // NOLINTNEXTLINE(google-default-arguments)
linkToDeath(const sp<DeathRecipient> &,void *,uint32_t)201 status_t BBinder::linkToDeath(
202     const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
203     uint32_t /*flags*/)
204 {
205     return INVALID_OPERATION;
206 }
207 
208 // NOLINTNEXTLINE(google-default-arguments)
unlinkToDeath(const wp<DeathRecipient> &,void *,uint32_t,wp<DeathRecipient> *)209 status_t BBinder::unlinkToDeath(
210     const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
211     uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
212 {
213     return INVALID_OPERATION;
214 }
215 
dump(int,const Vector<String16> &)216 status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/)
217 {
218     return NO_ERROR;
219 }
220 
attachObject(const void * objectID,void * object,void * cleanupCookie,object_cleanup_func func)221 void BBinder::attachObject(
222     const void* objectID, void* object, void* cleanupCookie,
223     object_cleanup_func func)
224 {
225     Extras* e = getOrCreateExtras();
226     if (!e) return; // out of memory
227 
228     AutoMutex _l(e->mLock);
229     e->mObjects.attach(objectID, object, cleanupCookie, func);
230 }
231 
findObject(const void * objectID) const232 void* BBinder::findObject(const void* objectID) const
233 {
234     Extras* e = mExtras.load(std::memory_order_acquire);
235     if (!e) return nullptr;
236 
237     AutoMutex _l(e->mLock);
238     return e->mObjects.find(objectID);
239 }
240 
detachObject(const void * objectID)241 void BBinder::detachObject(const void* objectID)
242 {
243     Extras* e = mExtras.load(std::memory_order_acquire);
244     if (!e) return;
245 
246     AutoMutex _l(e->mLock);
247     e->mObjects.detach(objectID);
248 }
249 
localBinder()250 BBinder* BBinder::localBinder()
251 {
252     return this;
253 }
254 
isRequestingSid()255 bool BBinder::isRequestingSid()
256 {
257     Extras* e = mExtras.load(std::memory_order_acquire);
258 
259     return e && e->mRequestingSid;
260 }
261 
setRequestingSid(bool requestingSid)262 void BBinder::setRequestingSid(bool requestingSid)
263 {
264     Extras* e = mExtras.load(std::memory_order_acquire);
265 
266     if (!e) {
267         // default is false. Most things don't need sids, so avoiding allocations when possible.
268         if (!requestingSid) {
269             return;
270         }
271 
272         e = getOrCreateExtras();
273         if (!e) return; // out of memory
274     }
275 
276     e->mRequestingSid = requestingSid;
277 }
278 
getExtension()279 sp<IBinder> BBinder::getExtension() {
280     Extras* e = mExtras.load(std::memory_order_acquire);
281     if (e == nullptr) return nullptr;
282     return e->mExtension;
283 }
284 
setMinSchedulerPolicy(int policy,int priority)285 void BBinder::setMinSchedulerPolicy(int policy, int priority) {
286     switch (policy) {
287     case SCHED_NORMAL:
288       LOG_ALWAYS_FATAL_IF(priority < -20 || priority > 19, "Invalid priority for SCHED_NORMAL: %d", priority);
289       break;
290     case SCHED_RR:
291     case SCHED_FIFO:
292       LOG_ALWAYS_FATAL_IF(priority < 1 || priority > 99, "Invalid priority for sched %d: %d", policy, priority);
293       break;
294     default:
295       LOG_ALWAYS_FATAL("Unrecognized scheduling policy: %d", policy);
296     }
297 
298     Extras* e = mExtras.load(std::memory_order_acquire);
299 
300     if (e == nullptr) {
301         // Avoid allocations if called with default.
302         if (policy == SCHED_NORMAL && priority == 0) {
303             return;
304         }
305 
306         e = getOrCreateExtras();
307         if (!e) return; // out of memory
308     }
309 
310     e->mPolicy = policy;
311     e->mPriority = priority;
312 }
313 
getMinSchedulerPolicy()314 int BBinder::getMinSchedulerPolicy() {
315     Extras* e = mExtras.load(std::memory_order_acquire);
316     if (e == nullptr) return SCHED_NORMAL;
317     return e->mPolicy;
318 }
319 
getMinSchedulerPriority()320 int BBinder::getMinSchedulerPriority() {
321     Extras* e = mExtras.load(std::memory_order_acquire);
322     if (e == nullptr) return 0;
323     return e->mPriority;
324 }
325 
getDebugPid()326 pid_t BBinder::getDebugPid() {
327     return getpid();
328 }
329 
setExtension(const sp<IBinder> & extension)330 void BBinder::setExtension(const sp<IBinder>& extension) {
331     Extras* e = getOrCreateExtras();
332     e->mExtension = extension;
333 }
334 
~BBinder()335 BBinder::~BBinder()
336 {
337     Extras* e = mExtras.load(std::memory_order_relaxed);
338     if (e) delete e;
339 }
340 
341 
342 // NOLINTNEXTLINE(google-default-arguments)
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t)343 status_t BBinder::onTransact(
344     uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
345 {
346     switch (code) {
347         case INTERFACE_TRANSACTION:
348             reply->writeString16(getInterfaceDescriptor());
349             return NO_ERROR;
350 
351         case DUMP_TRANSACTION: {
352             int fd = data.readFileDescriptor();
353             int argc = data.readInt32();
354             Vector<String16> args;
355             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
356                args.add(data.readString16());
357             }
358             return dump(fd, args);
359         }
360 
361         case SHELL_COMMAND_TRANSACTION: {
362             int in = data.readFileDescriptor();
363             int out = data.readFileDescriptor();
364             int err = data.readFileDescriptor();
365             int argc = data.readInt32();
366             Vector<String16> args;
367             for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
368                args.add(data.readString16());
369             }
370             sp<IShellCallback> shellCallback = IShellCallback::asInterface(
371                     data.readStrongBinder());
372             sp<IResultReceiver> resultReceiver = IResultReceiver::asInterface(
373                     data.readStrongBinder());
374 
375             // XXX can't add virtuals until binaries are updated.
376             //return shellCommand(in, out, err, args, resultReceiver);
377             (void)in;
378             (void)out;
379             (void)err;
380 
381             if (resultReceiver != nullptr) {
382                 resultReceiver->send(INVALID_OPERATION);
383             }
384 
385             return NO_ERROR;
386         }
387 
388         case SYSPROPS_TRANSACTION: {
389             report_sysprop_change();
390             return NO_ERROR;
391         }
392 
393         default:
394             return UNKNOWN_TRANSACTION;
395     }
396 }
397 
getOrCreateExtras()398 BBinder::Extras* BBinder::getOrCreateExtras()
399 {
400     Extras* e = mExtras.load(std::memory_order_acquire);
401 
402     if (!e) {
403         e = new Extras;
404         Extras* expected = nullptr;
405         if (!mExtras.compare_exchange_strong(expected, e,
406                                              std::memory_order_release,
407                                              std::memory_order_acquire)) {
408             delete e;
409             e = expected;  // Filled in by CAS
410         }
411         if (e == nullptr) return nullptr; // out of memory
412     }
413 
414     return e;
415 }
416 
417 // ---------------------------------------------------------------------------
418 
419 enum {
420     // This is used to transfer ownership of the remote binder from
421     // the BpRefBase object holding it (when it is constructed), to the
422     // owner of the BpRefBase object when it first acquires that BpRefBase.
423     kRemoteAcquired = 0x00000001
424 };
425 
BpRefBase(const sp<IBinder> & o)426 BpRefBase::BpRefBase(const sp<IBinder>& o)
427     : mRemote(o.get()), mRefs(nullptr), mState(0)
428 {
429     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
430 
431     if (mRemote) {
432         mRemote->incStrong(this);           // Removed on first IncStrong().
433         mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
434     }
435 }
436 
~BpRefBase()437 BpRefBase::~BpRefBase()
438 {
439     if (mRemote) {
440         if (!(mState.load(std::memory_order_relaxed)&kRemoteAcquired)) {
441             mRemote->decStrong(this);
442         }
443         mRefs->decWeak(this);
444     }
445 }
446 
onFirstRef()447 void BpRefBase::onFirstRef()
448 {
449     mState.fetch_or(kRemoteAcquired, std::memory_order_relaxed);
450 }
451 
onLastStrongRef(const void *)452 void BpRefBase::onLastStrongRef(const void* /*id*/)
453 {
454     if (mRemote) {
455         mRemote->decStrong(this);
456     }
457 }
458 
onIncStrongAttempted(uint32_t,const void *)459 bool BpRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
460 {
461     return mRemote ? mRefs->attemptIncStrong(this) : false;
462 }
463 
464 // ---------------------------------------------------------------------------
465 
466 } // namespace android
467