• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "binder_invoker.h"
17 
18 #include <chrono>
19 #include <securec.h>
20 #include "access_token_adapter.h"
21 #include "binder_debug.h"
22 #include "dbinder_error_code.h"
23 #include "hilog/log.h"
24 #include "hitrace_invoker.h"
25 #include "ipc_object_proxy.h"
26 #include "ipc_object_stub.h"
27 #include "ipc_process_skeleton.h"
28 #include "ipc_thread_skeleton.h"
29 #include "log_tags.h"
30 #include "string_ex.h"
31 #include "sys_binder.h"
32 
33 namespace OHOS {
34 #ifdef CONFIG_IPC_SINGLE
35 namespace IPC_SINGLE {
36 #endif
37 
38 using namespace OHOS::HiviewDFX;
39 static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC, "BinderInvoker" };
40 enum {
41     GET_SERVICE_TRANSACTION = 0x1,
42     CHECK_SERVICE_TRANSACTION,
43     ADD_SERVICE_TRANSACTION,
44 };
45 
BinderInvoker()46 BinderInvoker::BinderInvoker()
47     : isMainWorkThread(false), stopWorkThread(false), callerPid_(getpid()), callerUid_(getuid()),
48     callerTokenID_(0), firstTokenID_(0), status_(0)
49 {
50     input_.SetDataCapacity(IPC_DEFAULT_PARCEL_SIZE);
51     binderConnector_ = BinderConnector::GetInstance();
52 }
53 
AcquireHandle(int32_t handle)54 bool BinderInvoker::AcquireHandle(int32_t handle)
55 {
56     size_t rewindPos = output_.GetWritePosition();
57     if (!output_.WriteUint32(BC_ACQUIRE)) {
58         return false;
59     }
60 
61     if (!output_.WriteInt32(handle)) {
62         if (!output_.RewindWrite(rewindPos)) {
63             output_.FlushBuffer();
64         }
65         return false;
66     }
67     /* invoke remote to receive acquire handle event, don't care ping result */
68     if (handle != 0) {
69         (void)FlushCommands(nullptr);
70     }
71     return true;
72 }
73 
ReleaseHandle(int32_t handle)74 bool BinderInvoker::ReleaseHandle(int32_t handle)
75 {
76     size_t rewindPos = output_.GetWritePosition();
77     if (!output_.WriteUint32(BC_RELEASE)) {
78         return false;
79     }
80 
81     if (!output_.WriteInt32(handle)) {
82         if (!output_.RewindWrite(rewindPos)) {
83             output_.FlushBuffer();
84         }
85         return false;
86     }
87     FlushCommands(nullptr);
88     return true;
89 }
90 
SendRequest(int handle,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)91 int BinderInvoker::SendRequest(int handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
92     MessageOption &option)
93 {
94     int error = ERR_NONE;
95     uint32_t flags = static_cast<uint32_t>(option.GetFlags());
96     MessageParcel &newData = const_cast<MessageParcel &>(data);
97     size_t oldWritePosition = newData.GetWritePosition();
98     HiTraceId traceId = HiTraceChain::GetId();
99     // set client send trace point if trace is enabled
100     HiTraceId childId = HitraceInvoker::TraceClientSend(handle, code, newData, flags, traceId);
101     if (!TranslateDBinderProxy(handle, data)) {
102         return IPC_INVOKER_WRITE_TRANS_ERR;
103     }
104     if (!WriteTransaction(BC_TRANSACTION, flags, handle, code, data, nullptr)) {
105         newData.RewindWrite(oldWritePosition);
106         ZLOGE(LABEL, "WriteTransaction ERROR");
107 #ifndef BUILD_PUBLIC_VERSION
108         ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, std::string(DbinderErrorCode::ERROR_TYPE),
109             DbinderErrorCode::IPC_DRIVER, std::string(DbinderErrorCode::ERROR_CODE),
110             DbinderErrorCode::TRANSACT_DATA_FAILURE);
111 #endif
112         return IPC_INVOKER_WRITE_TRANS_ERR;
113     }
114 
115     if ((flags & TF_ONE_WAY) != 0) {
116         error = WaitForCompletion(nullptr);
117     } else {
118         error = WaitForCompletion(&reply);
119     }
120     HitraceInvoker::TraceClientReceieve(handle, code, flags, traceId, childId);
121     // restore Parcel data
122     newData.RewindWrite(oldWritePosition);
123     if (error != ERR_NONE) {
124         ZLOGE(LABEL, "%{public}s: handle=%{public}d result = %{public}d", __func__, handle, error);
125     }
126     return error;
127 }
128 
TranslateDBinderProxy(int handle,MessageParcel & parcel)129 bool BinderInvoker::TranslateDBinderProxy(int handle, MessageParcel &parcel)
130 {
131     uintptr_t dataOffset = parcel.GetData();
132     binder_size_t *objOffset = reinterpret_cast<binder_size_t *>(parcel.GetObjectOffsets());
133     for (size_t i = 0; i < parcel.GetOffsetsSize(); i++) {
134         auto flat = reinterpret_cast<flat_binder_object *>(dataOffset + *(objOffset + i));
135 #ifdef CONFIG_IPC_SINGLE
136         if (flat->hdr.type == BINDER_TYPE_HANDLE && flat->cookie != IRemoteObject::IF_PROT_BINDER) {
137             ZLOGE(LABEL, "sending a dbinder proxy in ipc_single.z.so is not allowed");
138             return false;
139         }
140 #else
141         if (flat->hdr.type == BINDER_TYPE_HANDLE && flat->cookie == IRemoteObject::IF_PROT_DATABUS
142             && flat->handle < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
143             MessageParcel data;
144             MessageParcel reply;
145             MessageOption option;
146             if (SendRequest(handle, GET_PID_UID, data, reply, option) != ERR_NONE) {
147                 ZLOGE(LABEL, "get pid and uid failed");
148                 return false;
149             }
150             MessageParcel data2;
151             MessageParcel reply2;
152             MessageOption option2;
153             data2.WriteUint32(reply.ReadUint32()); // pid
154             data2.WriteUint32(reply.ReadUint32()); // uid
155             IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
156             data2.WriteString(current->GetLocalDeviceID()); // deviceId
157             std::shared_ptr<DBinderSessionObject> session = current->ProxyQueryDBinderSession(flat->handle);
158             if (session == nullptr) {
159                 ZLOGE(LABEL, "no session found for handle: %{public}d", flat->handle);
160                 return false;
161             }
162             data2.WriteUint64(session->GetStubIndex()); // stubIndex
163             data2.WriteUint32(session->GetTokenId()); // tokenId
164             IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS);
165             if (invoker == nullptr) {
166                 ZLOGE(LABEL, "%{public}s: invoker is null", __func__);
167                 return false;
168             }
169             if (invoker->SendRequest(flat->handle, DBINDER_ADD_COMMAUTH, data2, reply2, option2) != ERR_NONE) {
170                 ZLOGE(LABEL, "dbinder add auth info failed");
171                 return false;
172             }
173         }
174 #endif
175     }
176     return true;
177 }
178 
AddDeathRecipient(int32_t handle,void * cookie)179 bool BinderInvoker::AddDeathRecipient(int32_t handle, void *cookie)
180 {
181     size_t rewindPos = output_.GetWritePosition();
182     if (!output_.WriteInt32(BC_REQUEST_DEATH_NOTIFICATION)) {
183         ZLOGE(LABEL, "fail to write command field:%d", handle);
184         return false;
185     }
186 
187     if (!output_.WriteInt32(handle)) {
188         if (!output_.RewindWrite(rewindPos)) {
189             output_.FlushBuffer();
190         }
191         return false;
192     }
193 
194     if (!output_.WritePointer((uintptr_t)cookie)) {
195         /* rewind written size notification and handle. */
196         if (!output_.RewindWrite(rewindPos)) {
197             output_.FlushBuffer();
198         }
199         return false;
200     }
201 
202     // pass in nullptr directly
203     int error = FlushCommands(nullptr);
204     if (error == ERR_NONE) {
205         auto *proxy = reinterpret_cast<IPCObjectProxy *>(cookie);
206         if (proxy != nullptr) {
207             proxy->IncStrongRef(this);
208         }
209     }
210     return error == ERR_NONE;
211 }
212 
RemoveDeathRecipient(int32_t handle,void * cookie)213 bool BinderInvoker::RemoveDeathRecipient(int32_t handle, void *cookie)
214 {
215     size_t rewindPos = output_.GetWritePosition();
216     if (!output_.WriteInt32(BC_CLEAR_DEATH_NOTIFICATION)) {
217         return false;
218     }
219 
220     if (!output_.WriteInt32(handle)) {
221         if (!output_.RewindWrite(rewindPos)) {
222             output_.FlushBuffer();
223         }
224         return false;
225     }
226 
227     if (!output_.WritePointer((uintptr_t)cookie)) {
228         if (!output_.RewindWrite(rewindPos)) {
229             output_.FlushBuffer();
230         }
231         return false;
232     }
233 
234     // pass in nullptr directly
235     int error = FlushCommands(nullptr);
236     if (error != ERR_NONE) {
237         ZLOGE(LABEL, "Remove Death Recipient handle =%{public}d result = %{public}d", handle, error);
238         return false;
239     }
240 
241     return true;
242 }
243 
244 #ifndef CONFIG_IPC_SINGLE
TranslateIRemoteObject(int32_t cmd,const sptr<IRemoteObject> & obj)245 int BinderInvoker::TranslateIRemoteObject(int32_t cmd, const sptr<IRemoteObject> &obj)
246 {
247     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
248         return -IPC_INVOKER_CONNECT_ERR;
249     }
250     size_t rewindPos = output_.GetWritePosition();
251     if (!output_.WriteInt32(cmd)) {
252         if (!output_.RewindWrite(rewindPos)) {
253             output_.FlushBuffer();
254         }
255         return -IPC_INVOKER_TRANSLATE_ERR;
256     }
257     if (!FlattenObject(output_, obj.GetRefPtr())) {
258         if (!output_.RewindWrite(rewindPos)) {
259             output_.FlushBuffer();
260         }
261         return -IPC_INVOKER_TRANSLATE_ERR;
262     }
263     MessageParcel reply;
264     int error = WaitForCompletion(&reply);
265     if (error == ERR_NONE) {
266         uint32_t handle = reply.ReadUint32();
267         if (handle > 0) {
268             return handle;
269         }
270     }
271     ZLOGE(LABEL, "failed to TranslateIRemoteObject");
272     return -IPC_INVOKER_TRANSLATE_ERR;
273 }
274 
GetSAMgrObject()275 sptr<IRemoteObject> BinderInvoker::GetSAMgrObject()
276 {
277     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
278     if (current != nullptr) {
279         return current->GetRegistryObject();
280     }
281     return nullptr;
282 }
283 
284 #endif
SetMaxWorkThread(int maxThreadNum)285 bool BinderInvoker::SetMaxWorkThread(int maxThreadNum)
286 {
287     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
288         ZLOGE(LABEL, "%{public}s driver died", __func__);
289         return false;
290     }
291 
292     int error = binderConnector_->WriteBinder(BINDER_SET_MAX_THREADS, &maxThreadNum);
293     if (error != ERR_NONE) {
294         ZLOGE(LABEL, "SetMaxWorkThread error = %{public}d", error);
295         return false;
296     }
297 
298     return true;
299 }
300 
FlushCommands(IRemoteObject * object)301 int BinderInvoker::FlushCommands(IRemoteObject *object)
302 {
303     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
304         ZLOGE(LABEL, "driver is died");
305         return IPC_INVOKER_CONNECT_ERR;
306     }
307     int error = TransactWithDriver(false);
308     if (error != ERR_NONE) {
309         ZLOGE(LABEL, "fail to flush commands with error = %{public}d", error);
310     }
311 
312     if (output_.GetDataSize() > 0) {
313         error = TransactWithDriver(false);
314         ZLOGE(LABEL, "flush commands again with return value = %{public}d", error);
315     }
316     if (error != ERR_NONE || output_.GetDataSize() > 0) {
317         ZLOGE(LABEL, "flush commands with error = %{public}d, left data size = %{public}zu", error,
318             output_.GetDataSize());
319     }
320 
321     return error;
322 }
323 
ExitCurrentThread()324 void BinderInvoker::ExitCurrentThread()
325 {
326     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
327         ZLOGE(LABEL, "%{public}s driver died when exit current thread", __func__);
328         return;
329     }
330     binderConnector_->ExitCurrentThread(BINDER_THREAD_EXIT);
331 }
332 
StartWorkLoop()333 void BinderInvoker::StartWorkLoop()
334 {
335     int error;
336     do {
337         error = TransactWithDriver();
338         if (error < ERR_NONE && error != -ECONNREFUSED && error != -EBADF) {
339             ZLOGE(LABEL, "returned unexpected error %d, aborting", error);
340             break;
341         }
342         uint32_t cmd = input_.ReadUint32();
343         int userError = HandleCommands(cmd);
344         if ((userError == -ERR_TIMED_OUT || userError == IPC_INVOKER_INVALID_DATA_ERR) && !isMainWorkThread) {
345             break;
346         }
347     } while (error != -ECONNREFUSED && error != -EBADF && !stopWorkThread);
348 }
349 
SendReply(MessageParcel & reply,uint32_t flags,int32_t result)350 int BinderInvoker::SendReply(MessageParcel &reply, uint32_t flags, int32_t result)
351 {
352     int error = WriteTransaction(BC_REPLY, flags, -1, 0, reply, &result);
353     if (error < ERR_NONE) {
354         return error;
355     }
356 
357     return WaitForCompletion();
358 }
359 
OnBinderDied()360 void BinderInvoker::OnBinderDied()
361 {
362     uintptr_t cookie = input_.ReadPointer();
363     auto *proxy = reinterpret_cast<IPCObjectProxy *>(cookie);
364     ZLOGD(LABEL, "%s, enter", __func__);
365     if (proxy != nullptr) {
366         proxy->SendObituary();
367     }
368 
369     size_t rewindPos = output_.GetWritePosition();
370     if (!output_.WriteInt32(BC_DEAD_BINDER_DONE)) {
371         return;
372     }
373 
374     if (!output_.WritePointer((uintptr_t)cookie)) {
375         if (!output_.RewindWrite(rewindPos)) {
376             output_.FlushBuffer();
377         }
378     }
379 }
380 
OnAcquireObject(uint32_t cmd)381 void BinderInvoker::OnAcquireObject(uint32_t cmd)
382 {
383     bool result = false;
384     uintptr_t refsPointer = input_.ReadPointer();
385     uintptr_t objectPointer = input_.ReadPointer();
386     RefCounter *refs = reinterpret_cast<RefCounter *>(refsPointer);
387     IRemoteObject *obj = reinterpret_cast<IRemoteObject *>(objectPointer);
388     if ((obj == nullptr) || (refs == nullptr)) {
389         ZLOGE(LABEL, "OnAcquireObject FAIL!");
390         return;
391     }
392 
393     size_t rewindPos = output_.GetWritePosition();
394     if (cmd == BR_ACQUIRE) {
395         obj->IncStrongRef(this);
396         result = output_.WriteInt32(BC_ACQUIRE_DONE);
397     } else {
398         refs->IncWeakRefCount(this);
399         result = output_.WriteInt32(BC_INCREFS_DONE);
400     }
401 
402     if (!result || !output_.WritePointer(refsPointer)) {
403         if (!output_.RewindWrite(rewindPos)) {
404             output_.FlushBuffer();
405         }
406         return;
407     }
408 
409     if (!output_.WritePointer(objectPointer)) {
410         if (!output_.RewindWrite(rewindPos)) {
411             output_.FlushBuffer();
412         }
413     }
414 }
415 
OnReleaseObject(uint32_t cmd)416 void BinderInvoker::OnReleaseObject(uint32_t cmd)
417 {
418     uintptr_t refsPointer = input_.ReadPointer();
419     uintptr_t objectPointer = input_.ReadPointer();
420     RefCounter *refs = reinterpret_cast<RefCounter *>(refsPointer);
421     IRemoteObject *obj = reinterpret_cast<IRemoteObject *>(objectPointer);
422     if ((refs == nullptr) || (obj == nullptr)) {
423         ZLOGE(LABEL, "OnReleaseObject FAIL!");
424         return;
425     }
426     ZLOGD(LABEL, "OnReleaseObject refcount=%{public}d", refs->GetStrongRefCount());
427     if (cmd == BR_RELEASE) {
428         obj->DecStrongRef(this);
429     } else {
430         refs->DecWeakRefCount(this);
431     }
432 }
433 
GetAccessToken(uint64_t & callerTokenID,uint64_t & firstTokenID)434 void BinderInvoker::GetAccessToken(uint64_t &callerTokenID, uint64_t &firstTokenID)
435 {
436     struct access_token token{};
437     int error = binderConnector_->WriteBinder(BINDER_GET_ACCESS_TOKEN, &token);
438     if (error != ERR_NONE) {
439         token.sender_tokenid = 0;
440         token.first_tokenid = 0;
441     }
442     callerTokenID = token.sender_tokenid;
443     firstTokenID = token.first_tokenid;
444 }
445 
OnTransaction(const uint8_t * buffer)446 void BinderInvoker::OnTransaction(const uint8_t *buffer)
447 {
448     const binder_transaction_data *tr = reinterpret_cast<const binder_transaction_data *>(buffer);
449     auto binderAllocator = new (std::nothrow) BinderAllocator();
450     if (binderAllocator == nullptr) {
451         ZLOGE(LABEL, "BinderAllocator Creation failed");
452         return;
453     }
454     auto data = std::make_unique<MessageParcel>(binderAllocator);
455     data->ParseFrom(tr->data.ptr.buffer, tr->data_size);
456     if (tr->offsets_size > 0) {
457         data->InjectOffsets(tr->data.ptr.offsets, tr->offsets_size / sizeof(binder_size_t));
458     }
459     uint32_t &newflags = const_cast<uint32_t &>(tr->flags);
460     int isServerTraced = HitraceInvoker::TraceServerReceieve(static_cast<uint64_t>(tr->target.handle),
461         tr->code, *data, newflags);
462     const pid_t oldPid = callerPid_;
463     const auto oldUid = static_cast<const uid_t>(callerUid_);
464     const uint64_t oldToken = callerTokenID_;
465     const uint64_t oldFirstToken = firstTokenID_;
466     uint32_t oldStatus = status_;
467     callerPid_ = tr->sender_pid;
468     callerUid_ = tr->sender_euid;
469     if (binderConnector_ != nullptr && binderConnector_->IsAccessTokenSupported()) {
470         GetAccessToken(callerTokenID_, firstTokenID_);
471     }
472     SetStatus(IRemoteInvoker::ACTIVE_INVOKER);
473     int error = ERR_DEAD_OBJECT;
474     MessageParcel reply;
475     MessageOption option;
476     uint32_t flagValue = static_cast<uint32_t>(tr->flags) & ~static_cast<uint32_t>(MessageOption::TF_ACCEPT_FDS);
477     option.SetFlags(static_cast<int>(flagValue));
478     std::string service;
479     auto start = std::chrono::steady_clock::now();
480     if (tr->target.ptr != 0) {
481         auto *refs = reinterpret_cast<RefCounter *>(tr->target.ptr);
482         int count = 0;
483         if ((refs != nullptr) && (tr->cookie) && (refs->AttemptIncStrongRef(this, count))) {
484             auto *targetObject = reinterpret_cast<IPCObjectStub *>(tr->cookie);
485             if (targetObject != nullptr) {
486                 error = targetObject->SendRequest(tr->code, *data, reply, option);
487                 service = Str16ToStr8(targetObject->GetObjectDescriptor());
488                 targetObject->DecStrongRef(this);
489             }
490         }
491     } else {
492         auto targetObject = IPCProcessSkeleton::GetCurrent()->GetRegistryObject();
493         if (targetObject == nullptr) {
494             ZLOGE(LABEL, "Invalid samgr stub object");
495         } else {
496             error = targetObject->SendRequest(tr->code, *data, reply, option);
497         }
498         service = "samgr";
499     }
500     auto finish = std::chrono::steady_clock::now();
501     int duration = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(
502         finish - start).count());
503     if (duration >= IPC_CMD_PROCESS_WARN_TIME) {
504         ZLOGW(LABEL, "stub: %{public}s deal request code: %{public}u cost time: %{public}dms",
505             service.c_str(), tr->code, duration);
506     }
507     HitraceInvoker::TraceServerSend(static_cast<uint64_t>(tr->target.handle), tr->code, isServerTraced, newflags);
508     if (!(flagValue & TF_ONE_WAY)) {
509         SendReply(reply, 0, error);
510     }
511     callerPid_ = oldPid;
512     callerUid_ = oldUid;
513     callerTokenID_ = oldToken;
514     firstTokenID_ = oldFirstToken;
515     SetStatus(oldStatus);
516 }
517 
OnAttemptAcquire()518 void BinderInvoker::OnAttemptAcquire()
519 {
520     bool success = false;
521     uintptr_t refsPtr = input_.ReadPointer();
522     uintptr_t objectPtr = input_.ReadPointer();
523     auto *refs = reinterpret_cast<RefCounter *>(refsPtr);
524 
525     size_t rewindPos = output_.GetWritePosition();
526     if ((refs != nullptr) && (!objectPtr)) {
527         int count = 0;
528         success = refs->AttemptIncStrongRef(this, count);
529     }
530 
531     if (!output_.WriteUint32(BC_ACQUIRE_RESULT)) {
532         return;
533     }
534 
535     if (!output_.WriteUint32((uint32_t)success)) {
536         if (!output_.RewindWrite(rewindPos)) {
537             output_.FlushBuffer();
538         }
539     }
540 }
541 
OnRemoveRecipientDone()542 void BinderInvoker::OnRemoveRecipientDone()
543 {
544     uintptr_t cookie = input_.ReadPointer();
545     auto *proxy = reinterpret_cast<IPCObjectProxy *>(cookie);
546     if (proxy != nullptr) {
547         proxy->DecStrongRef(this);
548     }
549 }
550 
HandleReply(MessageParcel * reply)551 int BinderInvoker::HandleReply(MessageParcel *reply)
552 {
553     const size_t readSize = sizeof(binder_transaction_data);
554     const uint8_t *buffer = input_.ReadBuffer(readSize);
555     if (buffer == nullptr) {
556         ZLOGE(LABEL, "HandleReply read tr failed");
557         return IPC_INVOKER_INVALID_DATA_ERR;
558     }
559     const binder_transaction_data *tr = reinterpret_cast<const binder_transaction_data *>(buffer);
560 
561     if (reply == nullptr) {
562         ZLOGD(LABEL, "no need reply, free the buffer");
563         FreeBuffer(reinterpret_cast<void *>(tr->data.ptr.buffer));
564         return IPC_INVOKER_INVALID_REPLY_ERR;
565     }
566 
567     if (tr->flags & TF_STATUS_CODE) {
568         int32_t status = *reinterpret_cast<const int32_t *>(tr->data.ptr.buffer);
569         FreeBuffer(reinterpret_cast<void *>(tr->data.ptr.buffer));
570         return status;
571     }
572 
573     if (tr->data_size > 0) {
574         auto allocator = new (std::nothrow) BinderAllocator();
575         if (allocator == nullptr) {
576             ZLOGE(LABEL, "create BinderAllocator object failed");
577             return IPC_INVOKER_INVALID_DATA_ERR;
578         }
579         if (!reply->SetAllocator(allocator)) {
580             ZLOGD(LABEL, "SetAllocator failed");
581             delete allocator;
582             FreeBuffer(reinterpret_cast<void *>(tr->data.ptr.buffer));
583             return IPC_INVOKER_INVALID_DATA_ERR;
584         }
585         reply->ParseFrom(tr->data.ptr.buffer, tr->data_size);
586     }
587 
588     if (tr->offsets_size > 0) {
589         reply->InjectOffsets(tr->data.ptr.offsets, tr->offsets_size / sizeof(binder_size_t));
590         reply->SetClearFdFlag();
591     }
592     return ERR_NONE;
593 }
594 
HandleCommandsInner(uint32_t cmd)595 int BinderInvoker::HandleCommandsInner(uint32_t cmd)
596 {
597     int error = ERR_NONE;
598     switch (cmd) {
599         case BR_ERROR:
600             error = input_.ReadInt32();
601             break;
602         case BR_ACQUIRE:
603         case BR_INCREFS:
604             OnAcquireObject(cmd);
605             break;
606         case BR_RELEASE:
607         case BR_DECREFS:
608             OnReleaseObject(cmd);
609             break;
610         case BR_ATTEMPT_ACQUIRE:
611             OnAttemptAcquire();
612             break;
613         case BR_TRANSACTION: {
614             const uint8_t *buffer = input_.ReadBuffer(sizeof(binder_transaction_data));
615             if (buffer == nullptr) {
616                 error = IPC_INVOKER_INVALID_DATA_ERR;
617                 break;
618             }
619             OnTransaction(buffer);
620             break;
621         }
622         case BR_SPAWN_LOOPER: {
623             IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
624             if (current != nullptr) {
625                 current->SpawnThread();
626             }
627             break;
628         }
629         case BR_FINISHED:
630             error = -ERR_TIMED_OUT;
631             break;
632         case BR_DEAD_BINDER:
633             OnBinderDied();
634             break;
635         case BR_CLEAR_DEATH_NOTIFICATION_DONE:
636             OnRemoveRecipientDone();
637             break;
638         case BR_OK:
639         case BR_NOOP:
640             break;
641         default:
642             error = IPC_INVOKER_ON_TRANSACT_ERR;
643             break;
644     }
645     return error;
646 }
647 
HandleCommands(uint32_t cmd)648 int BinderInvoker::HandleCommands(uint32_t cmd)
649 {
650     auto start = std::chrono::steady_clock::now();
651     int error = HandleCommandsInner(cmd);
652     if (error != ERR_NONE) {
653         ZLOGE(LABEL, "HandleCommands cmd = %{public}u, error = %{public}d", cmd, error);
654     }
655     if (cmd != BR_TRANSACTION) {
656         auto finish = std::chrono::steady_clock::now();
657         int duration = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(
658             finish - start).count());
659         if (duration >= IPC_CMD_PROCESS_WARN_TIME) {
660             ZLOGW(LABEL, "HandleCommands cmd: %{public}u cost time: %{public}dms", cmd, duration);
661         }
662     }
663     return error;
664 }
665 
JoinThread(bool initiative)666 void BinderInvoker::JoinThread(bool initiative)
667 {
668     isMainWorkThread = initiative;
669     output_.WriteUint32(initiative ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
670     StartWorkLoop();
671     output_.WriteUint32(BC_EXIT_LOOPER);
672     // pass in nullptr directly
673     FlushCommands(nullptr);
674     ZLOGE(LABEL, "Current Thread %d is leaving", getpid());
675 }
676 
JoinProcessThread(bool initiative)677 void BinderInvoker::JoinProcessThread(bool initiative) {}
678 
TransactWithDriver(bool doRead)679 int BinderInvoker::TransactWithDriver(bool doRead)
680 {
681     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
682         ZLOGE(LABEL, "%{public}s: Binder Driver died", __func__);
683         return IPC_INVOKER_CONNECT_ERR;
684     }
685 
686     binder_write_read bwr;
687     const bool readAvail = input_.GetReadableBytes() == 0;
688     const size_t outAvail = (!doRead || readAvail) ? output_.GetDataSize() : 0;
689 
690     bwr.write_size = (binder_size_t)outAvail;
691     bwr.write_buffer = output_.GetData();
692 
693     if (doRead && readAvail) {
694         bwr.read_size = input_.GetDataCapacity();
695         bwr.read_buffer = input_.GetData();
696     } else {
697         bwr.read_size = 0;
698         bwr.read_buffer = 0;
699     }
700     if ((bwr.write_size == 0) && (bwr.read_size == 0)) {
701         return ERR_NONE;
702     }
703 
704     bwr.write_consumed = 0;
705     bwr.read_consumed = 0;
706     int error = binderConnector_->WriteBinder(BINDER_WRITE_READ, &bwr);
707     if (bwr.write_consumed > 0) {
708         if (bwr.write_consumed < output_.GetDataSize()) {
709             // we still have some bytes not been handled.
710         } else {
711             output_.FlushBuffer();
712         }
713     }
714     if (bwr.read_consumed > 0) {
715         input_.SetDataSize(bwr.read_consumed);
716         input_.RewindRead(0);
717     }
718     if (error != ERR_NONE) {
719         ZLOGE(LABEL, "TransactWithDriver result = %{public}d", error);
720     }
721 
722     return error;
723 }
724 
WriteTransaction(int cmd,uint32_t flags,int32_t handle,uint32_t code,const MessageParcel & data,const int32_t * status)725 bool BinderInvoker::WriteTransaction(int cmd, uint32_t flags, int32_t handle, uint32_t code, const MessageParcel &data,
726     const int32_t *status)
727 {
728     binder_transaction_data tr {};
729     tr.target.handle = (uint32_t)handle;
730     tr.code = code;
731     tr.flags = flags;
732     tr.flags |= TF_ACCEPT_FDS;
733     if (data.GetDataSize() > 0) {
734         // Send this parcel's data through the binder.
735         tr.data_size = data.GetDataSize();
736         tr.data.ptr.buffer = (binder_uintptr_t)data.GetData();
737         tr.offsets_size = data.GetOffsetsSize() * sizeof(binder_size_t);
738         tr.data.ptr.offsets = data.GetObjectOffsets();
739     } else if (status != nullptr) {
740         // Send this parcel's status through the binder.
741         tr.flags |= TF_STATUS_CODE;
742         tr.data_size = sizeof(int32_t);
743         tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(status);
744         tr.offsets_size = 0;
745         tr.data.ptr.offsets = 0;
746     }
747 
748     if (!output_.WriteInt32(cmd)) {
749         ZLOGE(LABEL, "WriteTransaction Command failure");
750         return false;
751     }
752     return output_.WriteBuffer(&tr, sizeof(binder_transaction_data));
753 }
754 
WaitForCompletion(MessageParcel * reply,int32_t * acquireResult)755 int BinderInvoker::WaitForCompletion(MessageParcel *reply, int32_t *acquireResult)
756 {
757     uint32_t cmd;
758     bool continueLoop = true;
759     int error = ERR_NONE;
760     while (continueLoop) {
761         if ((error = TransactWithDriver()) < ERR_NONE) {
762             break;
763         }
764         if (input_.GetReadableBytes() == 0) {
765             continue;
766         }
767         cmd = input_.ReadUint32();
768         switch (cmd) {
769             case BR_TRANSACTION_COMPLETE: {
770                 if (reply == nullptr && acquireResult == nullptr) {
771                     continueLoop = false;
772                 }
773                 break;
774             }
775             case BR_DEAD_REPLY: // fall-through
776             case BR_FAILED_REPLY: {
777                 error = static_cast<int>(cmd);
778                 if (acquireResult != nullptr) {
779                     *acquireResult = cmd;
780                 }
781                 continueLoop = false;
782                 break;
783             }
784             case BR_ACQUIRE_RESULT: {
785                 int32_t result = input_.ReadInt32();
786                 if (acquireResult != nullptr) {
787                     *acquireResult = result ? ERR_NONE : ERR_INVALID_OPERATION;
788                     continueLoop = false;
789                 }
790                 break;
791             }
792             case BR_REPLY: {
793                 error = HandleReply(reply);
794                 if (error != IPC_INVOKER_INVALID_REPLY_ERR) {
795                     continueLoop = false;
796                     break;
797                 }
798                 error = ERR_NONE;
799                 break;
800             }
801             case BR_TRANSLATION_COMPLETE: {
802                 uint32_t handle = input_.ReadUint32();
803                 if (reply != nullptr) {
804                     reply->WriteUint32(handle);
805                 }
806                 continueLoop = false;
807                 break;
808             }
809             default: {
810                 error = HandleCommands(cmd);
811                 if (error != ERR_NONE) {
812                     continueLoop = false;
813                 }
814                 break;
815             }
816         }
817     }
818     return error;
819 }
820 
StopWorkThread()821 void BinderInvoker::StopWorkThread()
822 {
823     stopWorkThread = true;
824 }
825 
PingService(int32_t handle)826 bool BinderInvoker::PingService(int32_t handle)
827 {
828     MessageParcel data;
829     MessageParcel reply;
830     MessageOption option;
831     int result = SendRequest(handle, PING_TRANSACTION, data, reply, option);
832     return (result == ERR_NONE);
833 }
834 
SetRegistryObject(sptr<IRemoteObject> & object)835 bool BinderInvoker::SetRegistryObject(sptr<IRemoteObject> &object)
836 {
837     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
838         return false;
839     }
840 
841     if (object->IsProxyObject()) {
842         ZLOGE(LABEL, "%{public}s: set wrong object!", __func__);
843         return false;
844     }
845 
846     Parcel dummy;
847     int result = binderConnector_->WriteBinder(BINDER_SET_CONTEXT_MGR, &dummy);
848     if (result != ERR_NONE) {
849         ZLOGE(LABEL, "%{public}s:set registry fail, driver error %{public}d", __func__, result);
850         return false;
851     }
852 
853     return true;
854 }
855 
FreeBuffer(void * data)856 void BinderInvoker::FreeBuffer(void *data)
857 {
858     size_t rewindPos = output_.GetWritePosition();
859     if (!output_.WriteUint32(BC_FREE_BUFFER)) {
860         return;
861     }
862 
863     if (!output_.WritePointer((uintptr_t)data)) {
864         if (!output_.RewindWrite(rewindPos)) {
865             output_.FlushBuffer();
866         }
867     }
868 }
869 
Dealloc(void * data)870 void BinderInvoker::BinderAllocator::Dealloc(void *data)
871 {
872     IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
873     if (invoker != nullptr) {
874         invoker->FreeBuffer(data);
875     }
876 }
877 
GetCallerPid() const878 pid_t BinderInvoker::GetCallerPid() const
879 {
880     return callerPid_;
881 }
882 
GetCallerUid() const883 uid_t BinderInvoker::GetCallerUid() const
884 {
885     return callerUid_;
886 }
887 
GetCallerTokenID() const888 uint64_t BinderInvoker::GetCallerTokenID() const
889 {
890     // If a process does NOT have a tokenid, the UID should be returned accordingly.
891     if (callerTokenID_ == 0) {
892         return callerUid_;
893     }
894     return callerTokenID_;
895 }
896 
GetFirstCallerTokenID() const897 uint64_t BinderInvoker::GetFirstCallerTokenID() const
898 {
899     return firstTokenID_;
900 }
901 
GetSelfTokenID() const902 uint64_t BinderInvoker::GetSelfTokenID() const
903 {
904     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
905         return 0;
906     }
907     uint64_t selfTokenId = binderConnector_->GetSelfTokenID();
908     return (selfTokenId == 0) ? static_cast<uint64_t>(getuid()) : selfTokenId;
909 }
910 
GetSelfFirstCallerTokenID() const911 uint64_t BinderInvoker::GetSelfFirstCallerTokenID() const
912 {
913     if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
914         return 0;
915     }
916     uint64_t selfFirstCallerTokenId = binderConnector_->GetSelfFirstCallerTokenID();
917     return (selfFirstCallerTokenId == 0) ? static_cast<uint32_t>(getuid()) : selfFirstCallerTokenId;
918 }
919 
GetStatus() const920 uint32_t BinderInvoker::GetStatus() const
921 {
922     return status_;
923 }
924 
SetStatus(uint32_t status)925 void BinderInvoker::SetStatus(uint32_t status)
926 {
927     status_ = status;
928 }
929 
GetLocalDeviceID()930 std::string BinderInvoker::GetLocalDeviceID()
931 {
932     return "";
933 }
934 
GetCallerDeviceID() const935 std::string BinderInvoker::GetCallerDeviceID() const
936 {
937     return "";
938 }
939 
IsLocalCalling()940 bool BinderInvoker::IsLocalCalling()
941 {
942     return true;
943 }
944 
FlattenObject(Parcel & parcel,const IRemoteObject * object) const945 bool BinderInvoker::FlattenObject(Parcel &parcel, const IRemoteObject *object) const
946 {
947     if (object == nullptr) {
948         return false;
949     }
950     flat_binder_object flat;
951     if (object->IsProxyObject()) {
952         const IPCObjectProxy *proxy = reinterpret_cast<const IPCObjectProxy *>(object);
953         const int32_t handle = proxy ? static_cast<int32_t>(proxy->GetHandle()) : -1;
954         flat.hdr.type = BINDER_TYPE_HANDLE;
955         flat.binder = 0;
956         flat.handle = (uint32_t)handle;
957         flat.cookie = proxy ? static_cast<binder_uintptr_t>(proxy->GetProto()) : 0;
958     } else {
959         flat.hdr.type = BINDER_TYPE_BINDER;
960         flat.binder = reinterpret_cast<uintptr_t>(object->GetRefCounter());
961         flat.cookie = reinterpret_cast<uintptr_t>(object);
962     }
963 
964     flat.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
965     bool status = parcel.WriteBuffer(&flat, sizeof(flat_binder_object));
966     if (!status) {
967         ZLOGE(LABEL, "Fail to flatten object");
968 #ifndef BUILD_PUBLIC_VERSION
969         ReportDriverEvent(DbinderErrorCode::COMMON_DRIVER_ERROR, std::string(DbinderErrorCode::ERROR_TYPE),
970             DbinderErrorCode::IPC_DRIVER, std::string(DbinderErrorCode::ERROR_CODE),
971             DbinderErrorCode::FLATTEN_OBJECT_FAILURE);
972 #endif
973     }
974     return status;
975 }
976 
UnflattenObject(Parcel & parcel)977 sptr<IRemoteObject> BinderInvoker::UnflattenObject(Parcel &parcel)
978 {
979     const uint8_t *buffer = parcel.ReadBuffer(sizeof(flat_binder_object));
980     if (buffer == nullptr) {
981         ZLOGE(LABEL, "UnflattenObject null object buffer");
982         return nullptr;
983     }
984 
985     IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
986     if (current == nullptr) {
987         return nullptr;
988     }
989 
990     sptr<IRemoteObject> remoteObject = nullptr;
991     auto *flat = reinterpret_cast<const flat_binder_object *>(buffer);
992     switch (flat->hdr.type) {
993         case BINDER_TYPE_BINDER: {
994             remoteObject = reinterpret_cast<IRemoteObject *>(flat->cookie);
995             if (!current->IsContainsObject(remoteObject)) {
996                 remoteObject = nullptr;
997             }
998             break;
999         }
1000         case BINDER_TYPE_HANDLE: {
1001             remoteObject = current->FindOrNewObject(flat->handle);
1002             break;
1003         }
1004         default:
1005             ZLOGE(LABEL, "%s: unknown binder type %u", __func__, flat->hdr.type);
1006             remoteObject = nullptr;
1007             break;
1008     }
1009 
1010     return remoteObject;
1011 }
1012 
ReadFileDescriptor(Parcel & parcel)1013 int BinderInvoker::ReadFileDescriptor(Parcel &parcel)
1014 {
1015     int fd = -1;
1016     const uint8_t *buffer = parcel.ReadBuffer(sizeof(flat_binder_object));
1017     if (buffer == nullptr) {
1018         ZLOGE(LABEL, "UnflattenObject null object buffer");
1019         return fd;
1020     }
1021 
1022     auto *flat = reinterpret_cast<const flat_binder_object *>(buffer);
1023     if (flat->hdr.type == BINDER_TYPE_FD || flat->hdr.type == BINDER_TYPE_FDR) {
1024         fd = flat->handle;
1025     } else {
1026         ZLOGE(LABEL, "%s: unknown binder type %u", __func__, flat->hdr.type);
1027     }
1028 
1029     return fd;
1030 }
1031 
WriteFileDescriptor(Parcel & parcel,int fd,bool takeOwnership)1032 bool BinderInvoker::WriteFileDescriptor(Parcel &parcel, int fd, bool takeOwnership)
1033 {
1034     flat_binder_object flat;
1035     flat.hdr.type = BINDER_TYPE_FD;
1036     flat.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
1037     flat.binder = 0; // Don't pass uninitialized stack data to a remote process
1038     flat.handle = static_cast<__u32>(fd);
1039     flat.cookie = takeOwnership ? 1 : 0;
1040 
1041     return parcel.WriteBuffer(&flat, sizeof(flat_binder_object));
1042 }
1043 
ResetCallingIdentity()1044 std::string BinderInvoker::ResetCallingIdentity()
1045 {
1046     char buf[ACCESS_TOKEN_MAX_LEN + 1] = {0};
1047     int ret = sprintf_s(buf, ACCESS_TOKEN_MAX_LEN + 1, "%010" PRIu64, callerTokenID_);
1048     if (ret < 0) {
1049         ZLOGE(LABEL, "%{public}s: sprintf callerTokenID_ %{public}" PRIu64 " failed", __func__, callerTokenID_);
1050         return "";
1051     }
1052     std::string accessToken(buf);
1053     std::string pidUid = std::to_string(((static_cast<uint64_t>(callerUid_) << PID_LEN)
1054         | static_cast<uint64_t>(callerPid_)));
1055     callerUid_ = static_cast<pid_t>(getuid());
1056     callerPid_ = getpid();
1057     callerTokenID_ = GetSelfTokenID();
1058     return accessToken + pidUid;
1059 }
1060 
SetCallingIdentity(std::string & identity)1061 bool BinderInvoker::SetCallingIdentity(std::string &identity)
1062 {
1063     if (identity.empty() || identity.length() <= ACCESS_TOKEN_MAX_LEN) {
1064         return false;
1065     }
1066 
1067     uint64_t pidUid =
1068         std::stoull(identity.substr(ACCESS_TOKEN_MAX_LEN, identity.length() - ACCESS_TOKEN_MAX_LEN).c_str());
1069     callerUid_ = static_cast<int>(pidUid >> PID_LEN);
1070     callerPid_ = static_cast<int>(pidUid);
1071     callerTokenID_ = std::stoull(identity.substr(0, ACCESS_TOKEN_MAX_LEN).c_str());
1072     return true;
1073 }
1074 #ifdef CONFIG_IPC_SINGLE
1075 } // namespace IPC_SINGLE
1076 #endif
1077 } // namespace OHOS
1078