1  /*
2   * Copyright (C) 2021-2024 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  
21  #include "access_token_adapter.h"
22  #include "backtrace_local.h"
23  #include "binder_debug.h"
24  #include "hilog/log.h"
25  #include "hitrace_invoker.h"
26  #include "ipc_object_proxy.h"
27  #include "ipc_object_stub.h"
28  #include "ipc_process_skeleton.h"
29  #include "ipc_thread_skeleton.h"
30  #include "log_tags.h"
31  #include "string_ex.h"
32  #include "sys_binder.h"
33  #ifdef FFRT_IPC_ENABLE
34  #include "c/ffrt_ipc.h"
35  #endif
36  
37  #if defined(__arm__) || defined(__aarch64__)
38  #define TLS_SLOT_MIGRATION_DISABLE_COUNT (-10)
39  class ThreadMigrationDisabler {
GetTls()40      unsigned long *GetTls()
41      {
42          unsigned long *tls = nullptr;
43  #ifdef __aarch64__
44          asm("mrs %0, tpidr_el0" : "=r"(tls));
45  #else
46          asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(tls));
47  #endif
48          return tls;
49      }
50  
51  public:
ThreadMigrationDisabler()52      ThreadMigrationDisabler()
53      {
54          GetTls()[TLS_SLOT_MIGRATION_DISABLE_COUNT]++;
55      }
~ThreadMigrationDisabler()56      ~ThreadMigrationDisabler()
57      {
58          GetTls()[TLS_SLOT_MIGRATION_DISABLE_COUNT]--;
59      }
60  };
61  #else
62  class ThreadMigrationDisabler {};
63  #endif
64  
65  namespace OHOS {
66  #ifdef CONFIG_IPC_SINGLE
67  namespace IPC_SINGLE {
68  #endif
69  
70  #define PIDUID_OFFSET 2
71  using namespace OHOS::HiviewDFX;
72  static constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC_BINDER_INVOKER, "BinderInvoker" };
73  #ifndef CONFIG_IPC_SINGLE
74  static constexpr pid_t INVALID_PID = -1;
75  static constexpr int32_t BINDER_ALIGN_BYTES = 8;
76  #endif
77  
78  enum {
79      GET_SERVICE_TRANSACTION = 0x1,
80      CHECK_SERVICE_TRANSACTION,
81      ADD_SERVICE_TRANSACTION,
82  };
83  
BinderInvoker()84  BinderInvoker::BinderInvoker()
85      : isMainWorkThread(false), stopWorkThread(false), callerPid_(getpid()),
86      callerRealPid_(getprocpid()), callerUid_(getuid()),
87      callerTokenID_(0), firstTokenID_(0), callerSid_(""), status_(0)
88  {
89      invokerInfo_ = { callerPid_, callerRealPid_, callerUid_, callerTokenID_, firstTokenID_, callerSid_,
90          reinterpret_cast<uintptr_t>(this) };
91      input_.SetDataCapacity(IPC_DEFAULT_PARCEL_SIZE);
92      binderConnector_ = BinderConnector::GetInstance();
93      ZLOGD(LABEL, ":%{public}u", ProcessSkeleton::ConvertAddr(this));
94  }
95  
~BinderInvoker()96  BinderInvoker::~BinderInvoker()
97  {
98      ZLOGD(LABEL, ":%{public}u", ProcessSkeleton::ConvertAddr(this));
99      auto current = ProcessSkeleton::GetInstance();
100      if (current != nullptr) {
101          current->DetachInvokerProcInfo(true);
102      }
103      ProcDeferredDecRefs();
104      FlushCommands(nullptr);
105  }
106  
AcquireHandle(int32_t handle)107  bool BinderInvoker::AcquireHandle(int32_t handle)
108  {
109      size_t rewindPos = output_.GetWritePosition();
110      if (!output_.WriteUint32(BC_ACQUIRE)) {
111          return false;
112      }
113  
114      if (!output_.WriteInt32(handle)) {
115          if (!output_.RewindWrite(rewindPos)) {
116              output_.FlushBuffer();
117          }
118          return false;
119      }
120      /* invoke remote to receive acquire handle event, don't care ping result */
121      if (handle != 0) {
122          (void)FlushCommands(nullptr);
123      }
124      ZLOGD(LABEL, "handle:%{public}d", handle);
125      return true;
126  }
127  
ReleaseHandle(int32_t handle)128  bool BinderInvoker::ReleaseHandle(int32_t handle)
129  {
130      size_t rewindPos = output_.GetWritePosition();
131      if (!output_.WriteUint32(BC_RELEASE)) {
132          return false;
133      }
134  
135      if (!output_.WriteInt32(handle)) {
136          if (!output_.RewindWrite(rewindPos)) {
137              output_.FlushBuffer();
138          }
139          return false;
140      }
141      FlushCommands(nullptr);
142      ZLOGD(LABEL, "handle:%{public}d", handle);
143      return true;
144  }
145  
SendRequest(int handle,uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)146  int BinderInvoker::SendRequest(int handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
147      MessageOption &option)
148  {
149      int error = ERR_NONE;
150      uint32_t flags = static_cast<uint32_t>(option.GetFlags());
151      [[maybe_unused]] ThreadMigrationDisabler _d;
152  
153      if (!TranslateDBinderProxy(handle, data)) {
154          return IPC_INVOKER_WRITE_TRANS_ERR;
155      }
156  
157      size_t totalDBinderBufSize = 0;
158  #ifndef CONFIG_IPC_SINGLE
159      if (!TranslateDBinderStub(handle, data, false, totalDBinderBufSize)) {
160          return IPC_TRANSLATE_DBINDER_STUB_ERR;
161      }
162      auto dataSize = data.GetDataSize();
163      if (totalDBinderBufSize > 0 && dataSize % BINDER_ALIGN_BYTES != 0) {
164          ZLOGI(LABEL, "not 8 bytes aligned(%{public}zu), padding it", dataSize);
165          data.WriteInt8(0);
166      }
167  #endif
168      MessageParcel &newData = const_cast<MessageParcel &>(data);
169      size_t oldWritePosition = newData.GetWritePosition();
170      HiTraceId traceId = HiTraceChain::GetId();
171      // set client send trace point if trace is enabled
172      HiTraceId childId = HitraceInvoker::TraceClientSend(handle, code, newData, flags, traceId);
173  
174      int cmd = (totalDBinderBufSize > 0) ? BC_TRANSACTION_SG : BC_TRANSACTION;
175      if (!WriteTransaction(cmd, flags, handle, code, data, nullptr, totalDBinderBufSize)) {
176          ZLOGE(LABEL, "WriteTransaction ERROR");
177          newData.RewindWrite(oldWritePosition);
178          return IPC_INVOKER_WRITE_TRANS_ERR;
179      }
180  
181      ++sendRequestCount_;
182      if ((flags & TF_ONE_WAY) != 0) {
183          error = WaitForCompletion(nullptr);
184      } else {
185  #ifdef FFRT_IPC_ENABLE
186          ffrt_this_task_set_legacy_mode(true);
187  #endif
188          error = WaitForCompletion(&reply);
189  #ifdef FFRT_IPC_ENABLE
190          ffrt_this_task_set_legacy_mode(false);
191  #endif
192      }
193      HitraceInvoker::TraceClientReceieve(handle, code, flags, traceId, childId);
194      // restore Parcel data
195      newData.RewindWrite(oldWritePosition);
196      --sendRequestCount_;
197      return error;
198  }
199  
TranslateDBinderProxy(int handle,MessageParcel & parcel)200  bool BinderInvoker::TranslateDBinderProxy(int handle, MessageParcel &parcel)
201  {
202      uintptr_t dataOffset = parcel.GetData();
203      binder_size_t *objOffset = reinterpret_cast<binder_size_t *>(parcel.GetObjectOffsets());
204      for (size_t i = 0; i < parcel.GetOffsetsSize(); i++) {
205          auto flat = reinterpret_cast<flat_binder_object *>(dataOffset + *(objOffset + i));
206  #ifdef CONFIG_IPC_SINGLE
207          if (flat->hdr.type == BINDER_TYPE_HANDLE && flat->cookie != IRemoteObject::IF_PROT_BINDER) {
208              ZLOGE(LABEL, "sending a dbinder proxy in ipc_single.z.so is not allowed");
209              return false;
210          }
211  #else
212          if (flat->hdr.type == BINDER_TYPE_HANDLE && flat->cookie == IRemoteObject::IF_PROT_DATABUS
213              && flat->handle < IPCProcessSkeleton::DBINDER_HANDLE_BASE) {
214              if (!AddCommAuth(handle, flat)) {
215                  return false;
216              }
217          }
218  #endif
219      }
220      return true;
221  }
222  
AddDeathRecipient(int32_t handle,void * cookie)223  bool BinderInvoker::AddDeathRecipient(int32_t handle, void *cookie)
224  {
225      ZLOGD(LABEL, "for handle:%{public}d", handle);
226      size_t rewindPos = output_.GetWritePosition();
227      if (!output_.WriteInt32(BC_REQUEST_DEATH_NOTIFICATION)) {
228          ZLOGE(LABEL, "fail to write command field, handle:%{public}d", handle);
229          return false;
230      }
231  
232      if (!output_.WriteInt32(handle)) {
233          if (!output_.RewindWrite(rewindPos)) {
234              output_.FlushBuffer();
235          }
236          return false;
237      }
238  
239      if (!output_.WritePointer((uintptr_t)cookie)) {
240          /* rewind written size notification and handle. */
241          if (!output_.RewindWrite(rewindPos)) {
242              output_.FlushBuffer();
243          }
244          return false;
245      }
246  
247      // pass in nullptr directly
248      int error = FlushCommands(nullptr);
249      if (error == ERR_NONE) {
250          auto *proxy = reinterpret_cast<IPCObjectProxy *>(cookie);
251          if (proxy != nullptr) {
252              proxy->IncStrongRef(this);
253          }
254      }
255      return error == ERR_NONE;
256  }
257  
RemoveDeathRecipient(int32_t handle,void * cookie)258  bool BinderInvoker::RemoveDeathRecipient(int32_t handle, void *cookie)
259  {
260      size_t rewindPos = output_.GetWritePosition();
261      if (!output_.WriteInt32(BC_CLEAR_DEATH_NOTIFICATION)) {
262          return false;
263      }
264  
265      if (!output_.WriteInt32(handle)) {
266          if (!output_.RewindWrite(rewindPos)) {
267              output_.FlushBuffer();
268          }
269          return false;
270      }
271  
272      if (!output_.WritePointer((uintptr_t)cookie)) {
273          if (!output_.RewindWrite(rewindPos)) {
274              output_.FlushBuffer();
275          }
276          return false;
277      }
278  
279      // pass in nullptr directly
280      int error = FlushCommands(nullptr);
281      if (error != ERR_NONE) {
282          ZLOGE(LABEL, "failed, handle:%{public}d error:%{public}d", handle, error);
283          return false;
284      }
285  
286      return true;
287  }
288  
289  #ifndef CONFIG_IPC_SINGLE
TranslateIRemoteObject(int32_t cmd,const sptr<IRemoteObject> & obj)290  int BinderInvoker::TranslateIRemoteObject(int32_t cmd, const sptr<IRemoteObject> &obj)
291  {
292      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
293          return -IPC_INVOKER_CONNECT_ERR;
294      }
295      size_t rewindPos = output_.GetWritePosition();
296      if (!output_.WriteInt32(cmd)) {
297          if (!output_.RewindWrite(rewindPos)) {
298              output_.FlushBuffer();
299          }
300          return -IPC_INVOKER_TRANSLATE_ERR;
301      }
302      if (!FlattenObject(output_, obj.GetRefPtr())) {
303          if (!output_.RewindWrite(rewindPos)) {
304              output_.FlushBuffer();
305          }
306          return -IPC_INVOKER_TRANSLATE_ERR;
307      }
308      MessageParcel reply;
309      int error = WaitForCompletion(&reply);
310      if (error == ERR_NONE) {
311          uint32_t handle = reply.ReadUint32();
312          if (handle > 0) {
313              return handle;
314          }
315      }
316      ZLOGE(LABEL, "failed to TranslateIRemoteObject");
317      return -IPC_INVOKER_TRANSLATE_ERR;
318  }
319  
GetSAMgrObject()320  sptr<IRemoteObject> BinderInvoker::GetSAMgrObject()
321  {
322      ZLOGI(LABEL, "get samgr object!");
323      IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
324      if (current != nullptr) {
325          return current->GetRegistryObject();
326      }
327      return nullptr;
328  }
329  
AddCommAuth(int32_t handle,flat_binder_object * flat)330  bool BinderInvoker::AddCommAuth(int32_t handle, flat_binder_object *flat)
331  {
332      MessageParcel data;
333      MessageParcel reply;
334      MessageOption option;
335      if (SendRequest(handle, GET_PID_UID, data, reply, option) != ERR_NONE) {
336          ZLOGE(LABEL, "get pid and uid failed");
337          return false;
338      }
339      MessageParcel data2;
340      MessageParcel reply2;
341      MessageOption option2;
342      data2.WriteUint32(reply.ReadUint32()); // pid
343      data2.WriteUint32(reply.ReadUint32()); // uid
344      IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
345      if (current == nullptr) {
346          ZLOGE(LABEL, "current is null");
347          return false;
348      }
349      data2.WriteString(current->GetLocalDeviceID()); // deviceId
350      std::shared_ptr<DBinderSessionObject> session = current->ProxyQueryDBinderSession(flat->handle);
351      if (session == nullptr) {
352          ZLOGE(LABEL, "no session found for handle:%{public}d", flat->handle);
353          return false;
354      }
355      data2.WriteUint64(session->GetStubIndex()); // stubIndex
356      data2.WriteUint32(session->GetTokenId()); // tokenId
357      IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS);
358      if (invoker == nullptr) {
359          ZLOGE(LABEL, "invoker is null");
360          return false;
361      }
362      if (invoker->SendRequest(flat->handle, DBINDER_ADD_COMMAUTH, data2, reply2, option2) != ERR_NONE) {
363          ZLOGE(LABEL, "dbinder add auth info failed");
364          return false;
365      }
366      return true;
367  }
368  
GetDBinderCallingPidUid(int handle,bool isReply,pid_t & pid,uid_t & uid)369  bool BinderInvoker::GetDBinderCallingPidUid(int handle, bool isReply, pid_t &pid, uid_t &uid)
370  {
371      if (pid == INVALID_PID) {
372          if (!isReply) {
373              MessageParcel data;
374              MessageParcel reply;
375              MessageOption option;
376              auto ret = SendRequest(handle, GET_PID_UID, data, reply, option);
377              if (ret != ERR_NONE) {
378                  ZLOGE(LABEL, "GET_PID_UID failed, error:%{public}d", ret);
379                  return false;
380              }
381              uint32_t tempPid = reply.ReadUint32();
382              if (tempPid > static_cast<uint32_t>(std::numeric_limits<pid_t>::max())) {
383                  ZLOGE(LABEL, "PID overflow: %{public}u", tempPid);
384                  return false;
385              }
386              pid = static_cast<pid_t>(tempPid);
387              uid = reply.ReadUint32();
388          } else {
389              pid = GetCallerPid();
390              uid = GetCallerUid();
391          }
392          ZLOGI(LABEL, "pid:%{public}d uid:%{public}d", pid, uid);
393      }
394      return true;
395  }
396  
TranslateDBinderStub(int handle,MessageParcel & parcel,bool isReply,size_t & totalDBinderBufSize)397  bool BinderInvoker::TranslateDBinderStub(int handle, MessageParcel &parcel, bool isReply, size_t &totalDBinderBufSize)
398  {
399      pid_t pid = INVALID_PID;
400      uid_t uid = INVALID_PID;
401      uintptr_t dataBuf = parcel.GetData();
402      size_t totalSize = parcel.GetDataSize();
403      size_t objCount = parcel.GetOffsetsSize();
404      binder_size_t *objOffset = reinterpret_cast<binder_size_t *>(parcel.GetObjectOffsets());
405      size_t alignSize = 0;
406  
407      for (size_t i = 0; i < objCount; ++i) {
408          auto obj = reinterpret_cast<binder_buffer_object *>(dataBuf + objOffset[i]);
409          if ((obj->hdr.type == BINDER_TYPE_PTR) && (obj->length == sizeof(dbinder_negotiation_data))) {
410              alignSize = (obj->length + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t) - 1);
411              if (alignSize != obj->length) {
412                  ZLOGW(LABEL, "alignSize(%{public}zu) != obj.length(%{public}llu)", alignSize, obj->length);
413              }
414              totalDBinderBufSize += alignSize;
415              // skip to next object
416              ++i;
417              if ((i >= objCount) || (objOffset[i] + sizeof(flat_binder_object) > totalSize)) {
418                  ZLOGW(LABEL, "over length, i:%{public}zu count:%{public}zu offset:%{public}llu totalSize:%{public}zu",
419                      i, objCount, objOffset[i], totalSize);
420                  break;
421              }
422              auto flat = reinterpret_cast<flat_binder_object *>(dataBuf + objOffset[i]);
423              if (flat->hdr.type != BINDER_TYPE_BINDER) {
424                  ZLOGE(LABEL, "unexpected binder type:%{public}d", flat->hdr.type);
425                  return false;
426              }
427              if (!GetDBinderCallingPidUid(handle, isReply, pid, uid)) {
428                  ZLOGE(LABEL, "GetDBinderCallingPidUid fail, cookie:%{public}llu", flat->cookie);
429                  return false;
430              }
431  
432              auto stub = reinterpret_cast<IPCObjectStub *>(flat->cookie);
433              if (stub->GetAndSaveDBinderData(pid, uid) != ERR_NONE) {
434                  ZLOGE(LABEL, "GetAndSaveDBinderData fail, cookie:%{public}llu", flat->cookie);
435                  return false;
436              }
437              ZLOGI(LABEL, "succ, cookie:%{public}llu", flat->cookie);
438          }
439      }
440      return true;
441  }
442  
UnFlattenDBinderObject(Parcel & parcel,dbinder_negotiation_data & dbinderData)443  bool BinderInvoker::UnFlattenDBinderObject(Parcel &parcel, dbinder_negotiation_data &dbinderData)
444  {
445      auto offset = parcel.GetReadPosition();
446      auto *buffer = parcel.ReadBuffer(sizeof(binder_object_header), false);
447      if (buffer == nullptr) {
448          ZLOGE(LABEL, "null object buffer");
449          return false;
450      }
451      auto *hdr = reinterpret_cast<const binder_object_header *>(buffer);
452      if (hdr->type != BINDER_TYPE_PTR) {
453          parcel.RewindRead(offset);
454          return false;
455      }
456      ZLOGI(LABEL, "PTR");
457      parcel.RewindRead(offset);
458      buffer = parcel.ReadBuffer(sizeof(binder_buffer_object), false);
459      if (buffer == nullptr) {
460          ZLOGE(LABEL, "null object buffer");
461          return false;
462      }
463      auto *obj = reinterpret_cast<const binder_buffer_object *>(buffer);
464      if (((obj->flags & BINDER_BUFFER_FLAG_HAS_DBINDER) == 0) || (obj->length != sizeof(dbinder_negotiation_data))) {
465          ZLOGW(LABEL, "no dbinder buffer flag");
466          parcel.RewindRead(offset);
467          return false;
468      }
469      dbinderData = *reinterpret_cast<dbinder_negotiation_data *>(obj->buffer);
470      return true;
471  }
472  #endif
473  
SetMaxWorkThread(int maxThreadNum)474  bool BinderInvoker::SetMaxWorkThread(int maxThreadNum)
475  {
476      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
477          ZLOGE(LABEL, "driver died");
478          return false;
479      }
480  
481      int error = binderConnector_->WriteBinder(BINDER_SET_MAX_THREADS, &maxThreadNum);
482      if (error != ERR_NONE) {
483          ZLOGE(LABEL, "SetMaxWorkThread error:%{public}d", error);
484          return false;
485      }
486  
487      return true;
488  }
489  
FlushCommands(IRemoteObject * object)490  int BinderInvoker::FlushCommands(IRemoteObject *object)
491  {
492      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
493          ZLOGE(LABEL, "driver is died");
494          return IPC_INVOKER_CONNECT_ERR;
495      }
496      int error = TransactWithDriver(false);
497      if (error != ERR_NONE) {
498          uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
499              std::chrono::steady_clock::now().time_since_epoch()).count());
500          ZLOGE(LABEL, "failed, error:%{public}d time:%{public}" PRIu64, error, curTime);
501      }
502  
503      if (output_.GetDataSize() > 0) {
504          error = TransactWithDriver(false);
505      }
506      if (error != ERR_NONE || output_.GetDataSize() > 0) {
507          ZLOGW(LABEL, "error:%{public}d, left data size:%{public}zu", error, output_.GetDataSize());
508          PrintParcelData(input_, "input_");
509          PrintParcelData(output_, "output_");
510          std::string backtrace;
511          if (!GetBacktrace(backtrace, false)) {
512              ZLOGE(LABEL, "GetBacktrace fail");
513          } else {
514              ZLOGW(LABEL, "backtrace info:\n%{public}s", backtrace.c_str());
515          }
516      }
517  
518      return error;
519  }
520  
ExitCurrentThread()521  void BinderInvoker::ExitCurrentThread()
522  {
523      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
524          ZLOGE(LABEL, "driver died when exit current thread");
525          return;
526      }
527      binderConnector_->ExitCurrentThread(BINDER_THREAD_EXIT);
528  }
529  
StartWorkLoop()530  void BinderInvoker::StartWorkLoop()
531  {
532      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
533          ZLOGE(LABEL, "driver is died");
534          return;
535      }
536      int error;
537      do {
538          ProcessSkeleton *process = ProcessSkeleton::GetInstance();
539          if (process == nullptr || process->GetThreadStopFlag()) {
540              break;
541          }
542          error = TransactWithDriver();
543          if (error < ERR_NONE && error != -ECONNREFUSED && error != -EBADF) {
544              ZLOGE(LABEL, "returned unexpected error:%{public}d, aborting", error);
545              break;
546          }
547          if (input_.GetReadableBytes() == 0) {
548              continue;
549          }
550          uint32_t cmd = input_.ReadUint32();
551          IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
552          if (current != nullptr) {
553              current->LockForNumExecuting();
554          }
555          int userError = HandleCommands(cmd);
556          if (current != nullptr) {
557              current->UnlockForNumExecuting();
558          }
559          if ((userError == -ERR_TIMED_OUT || userError == IPC_INVOKER_INVALID_DATA_ERR) && !isMainWorkThread) {
560              ZLOGW(LABEL, "exit, userError:%{public}d", userError);
561              break;
562          }
563          ProcDeferredDecRefs();
564      } while (error != -ECONNREFUSED && error != -EBADF && !stopWorkThread);
565  }
566  
SendReply(MessageParcel & reply,uint32_t flags,int32_t result)567  int BinderInvoker::SendReply(MessageParcel &reply, uint32_t flags, int32_t result)
568  {
569      size_t totalDBinderBufSize = 0;
570  #ifndef CONFIG_IPC_SINGLE
571      if (!TranslateDBinderStub(-1, reply, true, totalDBinderBufSize)) {
572          return IPC_TRANSLATE_DBINDER_STUB_ERR;
573      }
574      auto replySize = reply.GetDataSize();
575      if (totalDBinderBufSize > 0 && replySize % BINDER_ALIGN_BYTES != 0) {
576          ZLOGI(LABEL, "not 8 bytes aligned(%{public}zu), padding it", replySize);
577          reply.WriteInt8(0);
578      }
579  #endif
580  
581      int cmd = (totalDBinderBufSize > 0) ? BC_REPLY_SG : BC_REPLY;
582      int error = WriteTransaction(cmd, flags, -1, 0, reply, &result, totalDBinderBufSize);
583      if (error < ERR_NONE) {
584          return error;
585      }
586      return WaitForCompletion();
587  }
588  
OnBinderDied()589  void BinderInvoker::OnBinderDied()
590  {
591      ZLOGD(LABEL, "enter");
592      uintptr_t cookie = input_.ReadPointer();
593      auto *proxy = reinterpret_cast<IPCObjectProxy *>(cookie);
594      if ((proxy == nullptr) || (proxy->GetSptrRefCount() <= 0)) {
595          ZLOGE(LABEL, "Invalid proxy object %{public}u.", ProcessSkeleton::ConvertAddr(proxy));
596          return;
597      }
598      ProcessSkeleton *current = ProcessSkeleton::GetInstance();
599      std::u16string desc;
600      if ((current != nullptr) && !current->IsValidObject(proxy, desc)) {
601          ZLOGE(LABEL, "%{public}u is invalid", ProcessSkeleton::ConvertAddr(proxy));
602      } else {
603          std::string descTemp = Str16ToStr8(desc);
604          CrashObjDumper dumper(descTemp.c_str());
605          if (proxy->AttemptIncStrongRef(this)) {
606              proxy->SendObituary();
607              proxy->DecStrongRef(this);
608          } else {
609              ZLOGW(LABEL, "failed to increment strong reference count");
610          }
611      }
612      size_t rewindPos = output_.GetWritePosition();
613      if (!output_.WriteInt32(BC_DEAD_BINDER_DONE)) {
614          return;
615      }
616  
617      if (!output_.WritePointer((uintptr_t)cookie)) {
618          if (!output_.RewindWrite(rewindPos)) {
619              output_.FlushBuffer();
620          }
621      }
622  }
623  
OnAcquireObject(uint32_t cmd)624  void BinderInvoker::OnAcquireObject(uint32_t cmd)
625  {
626      bool result = false;
627      uintptr_t refsPointer = input_.ReadPointer();
628      uintptr_t objectPointer = input_.ReadPointer();
629      RefCounter *refs = reinterpret_cast<RefCounter *>(refsPointer);
630      IRemoteObject *obj = reinterpret_cast<IRemoteObject *>(objectPointer);
631      if ((obj == nullptr) || (refs == nullptr)) {
632          ZLOGE(LABEL, "Invalid stub object %{public}u.", ProcessSkeleton::ConvertAddr(obj));
633          return;
634      }
635      ProcessSkeleton *current = ProcessSkeleton::GetInstance();
636      std::u16string desc;
637      if ((current != nullptr) && !current->IsValidObject(obj, desc)) {
638          ZLOGE(LABEL, "%{public}u is invalid", ProcessSkeleton::ConvertAddr(obj));
639          return;
640      }
641      std::string descTemp = Str16ToStr8(desc);
642      CrashObjDumper dumper(descTemp.c_str());
643      if (obj->GetSptrRefCount() <= 0) {
644          ZLOGE(LABEL, "Invalid stub object %{public}u.", ProcessSkeleton::ConvertAddr(obj));
645          return;
646      }
647      size_t rewindPos = output_.GetWritePosition();
648      if (cmd == BR_ACQUIRE) {
649          obj->IncStrongRef(this);
650          result = output_.WriteInt32(BC_ACQUIRE_DONE);
651      } else {
652          refs->IncWeakRefCount(this);
653          result = output_.WriteInt32(BC_INCREFS_DONE);
654      }
655  
656      if (!result || !output_.WritePointer(refsPointer) || !output_.WritePointer(objectPointer)) {
657          if (!output_.RewindWrite(rewindPos)) {
658              output_.FlushBuffer();
659          }
660          return;
661      }
662  }
663  
OnReleaseObject(uint32_t cmd)664  void BinderInvoker::OnReleaseObject(uint32_t cmd)
665  {
666      uintptr_t refsPointer = input_.ReadPointer();
667      uintptr_t objectPointer = input_.ReadPointer();
668      RefCounter *refs = reinterpret_cast<RefCounter *>(refsPointer);
669      IRemoteObject *obj = reinterpret_cast<IRemoteObject *>(objectPointer);
670      if ((refs == nullptr) || (obj == nullptr)) {
671          ZLOGE(LABEL, "Invalid stub object %{public}u.", ProcessSkeleton::ConvertAddr(obj));
672          return;
673      }
674  
675      ZLOGD(LABEL, "refcount:%{public}d refs:%{public}u obj:%{public}u", refs->GetStrongRefCount(),
676          ProcessSkeleton::ConvertAddr(refs), ProcessSkeleton::ConvertAddr(obj));
677      if (cmd == BR_RELEASE) {
678          std::lock_guard<std::mutex> lock(strongRefMutex_);
679          decStrongRefs_.push_back(obj);
680      } else {
681          std::lock_guard<std::mutex> lock(weakRefMutex_);
682          decWeakRefs_.push_back(refs);
683      }
684  }
685  
GetAccessToken(uint64_t & callerTokenID,uint64_t & firstTokenID)686  void BinderInvoker::GetAccessToken(uint64_t &callerTokenID, uint64_t &firstTokenID)
687  {
688      struct access_token token{};
689      int error = binderConnector_->WriteBinder(BINDER_GET_ACCESS_TOKEN, &token);
690      if (error != ERR_NONE) {
691          token.sender_tokenid = 0;
692          token.first_tokenid = 0;
693      }
694      callerTokenID = token.sender_tokenid;
695      firstTokenID = token.first_tokenid;
696  }
697  
GetSenderInfo(uint64_t & callerTokenID,uint64_t & firstTokenID,pid_t & realPid)698  void BinderInvoker::GetSenderInfo(uint64_t &callerTokenID, uint64_t &firstTokenID, pid_t &realPid)
699  {
700      struct binder_sender_info sender{};
701      int error = binderConnector_->WriteBinder(BINDER_GET_SENDER_INFO, &sender);
702      if (error != ERR_NONE) {
703          sender.tokens.sender_tokenid = 0;
704          sender.tokens.first_tokenid = 0;
705          sender.sender_pid_nr = 0;
706      }
707      callerTokenID = sender.tokens.sender_tokenid;
708      firstTokenID = sender.tokens.first_tokenid;
709      realPid = static_cast<pid_t>(sender.sender_pid_nr);
710  }
711  
RestoreInvokerProcInfo(const InvokerProcInfo & info)712  void BinderInvoker::RestoreInvokerProcInfo(const InvokerProcInfo &info)
713  {
714      callerPid_ = info.pid;
715      callerRealPid_ = info.realPid;
716      callerUid_ = info.uid;
717      callerTokenID_ = info.tokenId;
718      firstTokenID_ = info.firstTokenId;
719      callerSid_ = info.sid;
720  }
721  
AttachInvokerProcInfoWrapper()722  void BinderInvoker::AttachInvokerProcInfoWrapper()
723  {
724      InvokerProcInfo invokerInfo = { callerPid_, callerRealPid_,
725          callerUid_, callerTokenID_, firstTokenID_, callerSid_, ProcessSkeleton::ConvertAddr(this) };
726      auto current = ProcessSkeleton::GetInstance();
727      if (current != nullptr) {
728          current->AttachInvokerProcInfo(true, invokerInfo);
729      }
730  }
731  
SamgrServiceSendRequest(const binder_transaction_data & tr,MessageParcel & data,MessageParcel & reply,MessageOption & option)732  int32_t BinderInvoker::SamgrServiceSendRequest(
733      const binder_transaction_data &tr, MessageParcel &data, MessageParcel &reply, MessageOption &option)
734  {
735      int error = ERR_DEAD_OBJECT;
736  
737      auto targetObject = IPCProcessSkeleton::GetCurrent()->GetRegistryObject();
738      if (targetObject == nullptr) {
739          ZLOGE(LABEL, "Invalid samgr stub object");
740      } else {
741          error = targetObject->SendRequest(tr.code, data, reply, option);
742      }
743      return error;
744  }
745  
GeneralServiceSendRequest(const binder_transaction_data & tr,MessageParcel & data,MessageParcel & reply,MessageOption & option)746  int32_t BinderInvoker::GeneralServiceSendRequest(
747      const binder_transaction_data &tr, MessageParcel &data, MessageParcel &reply, MessageOption &option)
748  {
749      int32_t error = ERR_DEAD_OBJECT;
750      auto *refs = reinterpret_cast<RefCounter *>(tr.target.ptr);
751      int count = 0;
752      if ((refs != nullptr) && (tr.cookie) && (refs->AttemptIncStrongRef(this, count))) {
753          auto *targetObject = reinterpret_cast<IPCObjectStub *>(tr.cookie);
754          if (targetObject == nullptr) {
755              ZLOGE(LABEL, "Invalid stub object");
756              return error;
757          }
758          auto current = ProcessSkeleton::GetInstance();
759          std::u16string desc;
760          if ((current != nullptr) && !current->IsValidObject(targetObject, desc)) {
761              ZLOGE(LABEL, "%{public}u is invalid", ProcessSkeleton::ConvertAddr(targetObject));
762          } else {
763              std::string descTemp = Str16ToStr8(desc);
764              CrashObjDumper dumper(descTemp.c_str());
765              if (targetObject->GetSptrRefCount() > 0) {
766                  error = targetObject->SendRequest(tr.code, data, reply, option);
767                  targetObject->DecStrongRef(this);
768              }
769          }
770      }
771      return error;
772  }
773  
TargetStubSendRequest(const binder_transaction_data & tr,MessageParcel & data,MessageParcel & reply,MessageOption & option,uint32_t & flagValue)774  int32_t BinderInvoker::TargetStubSendRequest(const binder_transaction_data &tr,
775      MessageParcel &data, MessageParcel &reply, MessageOption &option, uint32_t &flagValue)
776  {
777  #ifdef CONFIG_ACTV_BINDER
778      bool oldActvBinder = GetUseActvBinder();
779      SetUseActvBinder(false);
780  #endif
781  
782      int32_t error = ERR_DEAD_OBJECT;
783      flagValue = static_cast<uint32_t>(tr.flags) & ~static_cast<uint32_t>(MessageOption::TF_ACCEPT_FDS);
784      option.SetFlags(static_cast<int>(flagValue));
785      if (tr.target.ptr != 0) {
786          error = GeneralServiceSendRequest(tr, data, reply, option);
787      } else {
788          error = SamgrServiceSendRequest(tr, data, reply, option);
789      }
790  
791  #ifdef CONFIG_ACTV_BINDER
792      SetUseActvBinder(oldActvBinder);
793  #endif
794      return error;
795  }
796  
Transaction(binder_transaction_data_secctx & trSecctx)797  void BinderInvoker::Transaction(binder_transaction_data_secctx& trSecctx)
798  {
799      binder_transaction_data& tr = trSecctx.transaction_data;
800      auto binderAllocator = new (std::nothrow) BinderAllocator();
801      if (binderAllocator == nullptr) {
802          ZLOGE(LABEL, "BinderAllocator Creation failed");
803          return;
804      }
805      auto data = std::make_unique<MessageParcel>(binderAllocator);
806      data->ParseFrom(tr.data.ptr.buffer, tr.data_size);
807      if (tr.offsets_size > 0) {
808          data->InjectOffsets(tr.data.ptr.offsets, tr.offsets_size / sizeof(binder_size_t));
809      }
810  
811      uint32_t &newFlags = const_cast<uint32_t&>(tr.flags);
812      int isServerTraced = HitraceInvoker::TraceServerReceieve(static_cast<uint64_t>(tr.target.handle),
813          tr.code, *data, newFlags);
814  
815      InvokerProcInfo oldInvokerProcInfo = {
816          callerPid_, callerRealPid_, callerUid_, callerTokenID_, firstTokenID_, callerSid_, 0 };
817      uint32_t oldStatus = status_;
818      callerSid_ = (trSecctx.secctx != 0) ? reinterpret_cast<char *>(trSecctx.secctx) : "";
819      callerPid_ = tr.sender_pid;
820      callerUid_ = tr.sender_euid;
821      callerRealPid_ = callerPid_;
822      if (binderConnector_ != nullptr && binderConnector_->IsRealPidSupported()) {
823          GetSenderInfo(callerTokenID_, firstTokenID_, callerRealPid_);
824      } else if (binderConnector_ != nullptr && binderConnector_->IsAccessTokenSupported()) {
825          GetAccessToken(callerTokenID_, firstTokenID_);
826      }
827      // sync caller information to another binderinvoker
828      AttachInvokerProcInfoWrapper();
829      MessageParcel reply;
830      MessageOption option;
831      uint32_t flagValue;
832  
833      SetStatus(IRemoteInvoker::ACTIVE_INVOKER);
834      int32_t error = TargetStubSendRequest(tr, *data, reply, option, flagValue);
835      HitraceInvoker::TraceServerSend(static_cast<uint64_t>(tr.target.handle), tr.code, isServerTraced, newFlags);
836      if (!(flagValue & TF_ONE_WAY)) {
837          SendReply(reply, 0, error);
838      }
839  
840      RestoreInvokerProcInfo(oldInvokerProcInfo);
841      // restore caller information to another binderinvoker
842      AttachInvokerProcInfoWrapper();
843      SetStatus(oldStatus);
844  }
845  
OnAttemptAcquire()846  void BinderInvoker::OnAttemptAcquire()
847  {
848      bool success = false;
849      uintptr_t refsPtr = input_.ReadPointer();
850      uintptr_t objectPtr = input_.ReadPointer();
851      auto *refs = reinterpret_cast<RefCounter *>(refsPtr);
852  
853      size_t rewindPos = output_.GetWritePosition();
854      if ((refs != nullptr) && (!objectPtr)) {
855          int count = 0;
856          success = refs->AttemptIncStrongRef(this, count);
857      }
858  
859      if (!output_.WriteUint32(BC_ACQUIRE_RESULT)) {
860          return;
861      }
862  
863      if (!output_.WriteUint32((uint32_t)success)) {
864          if (!output_.RewindWrite(rewindPos)) {
865              output_.FlushBuffer();
866          }
867      }
868  }
869  
OnRemoveRecipientDone()870  void BinderInvoker::OnRemoveRecipientDone()
871  {
872      uintptr_t cookie = input_.ReadPointer();
873      auto *proxy = reinterpret_cast<IPCObjectProxy *>(cookie);
874      if (proxy != nullptr) {
875          proxy->DecStrongRef(this);
876      }
877  }
878  
OnSpawnThread()879  void BinderInvoker::OnSpawnThread()
880  {
881      IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
882      if (current != nullptr) {
883  #ifdef CONFIG_ACTV_BINDER
884          if (GetUseActvBinder()) {
885              current->SpawnThread(IPCWorkThread::ACTV_PASSIVE);
886          } else {
887              current->SpawnThread();
888          }
889  #else
890          current->SpawnThread();
891  #endif
892      }
893  }
894  
OnTransaction(uint32_t cmd,int32_t & error)895  void BinderInvoker::OnTransaction(uint32_t cmd, int32_t &error)
896  {
897      binder_transaction_data_secctx trSecctx = {
898          .secctx = 0,
899      };
900      const uint8_t *buffer = nullptr;
901      bool isSecctx = (cmd == static_cast<uint32_t>(BR_TRANSACTION_SEC_CTX));
902      uint32_t bufferSize = isSecctx ? sizeof(binder_transaction_data_secctx) : sizeof(binder_transaction_data);
903  
904      buffer = input_.ReadBuffer(bufferSize, false);
905      if (buffer == nullptr) {
906          error = IPC_INVOKER_INVALID_DATA_ERR;
907          return;
908      }
909  
910      if (isSecctx) {
911          trSecctx = *(reinterpret_cast<const binder_transaction_data_secctx *>(buffer));
912      } else {
913          trSecctx.transaction_data = *(reinterpret_cast<const binder_transaction_data *>(buffer));
914      }
915  
916      Transaction(trSecctx);
917  }
918  
HandleReply(MessageParcel * reply,bool & isStubRet)919  int BinderInvoker::HandleReply(MessageParcel *reply, bool &isStubRet)
920  {
921      const size_t readSize = sizeof(binder_transaction_data);
922      const uint8_t *buffer = input_.ReadBuffer(readSize, false);
923      if (buffer == nullptr) {
924          ZLOGE(LABEL, "HandleReply read tr failed");
925          return IPC_INVOKER_INVALID_DATA_ERR;
926      }
927      const binder_transaction_data *tr = reinterpret_cast<const binder_transaction_data *>(buffer);
928  
929      if (reply == nullptr) {
930          ZLOGD(LABEL, "no need reply, free the buffer");
931          FreeBuffer(reinterpret_cast<void *>(tr->data.ptr.buffer));
932          return IPC_INVOKER_INVALID_REPLY_ERR;
933      }
934  
935      if (tr->flags & TF_STATUS_CODE) {
936          isStubRet = true;
937          int32_t status = *reinterpret_cast<const int32_t *>(tr->data.ptr.buffer);
938          ZLOGD(LABEL, "received status code:%{public}d, free the buffer", status);
939          FreeBuffer(reinterpret_cast<void *>(tr->data.ptr.buffer));
940          return status;
941      }
942  
943      auto allocator = new (std::nothrow) BinderAllocator();
944      if (allocator == nullptr) {
945          ZLOGE(LABEL, "create BinderAllocator object failed");
946          return IPC_INVOKER_INVALID_DATA_ERR;
947      }
948      if (!reply->SetAllocator(allocator)) {
949          ZLOGD(LABEL, "SetAllocator failed");
950          delete allocator;
951          FreeBuffer(reinterpret_cast<void *>(tr->data.ptr.buffer));
952          return IPC_INVOKER_INVALID_DATA_ERR;
953      }
954      reply->ParseFrom(tr->data.ptr.buffer, tr->data_size);
955  
956      if (tr->offsets_size > 0) {
957          reply->InjectOffsets(tr->data.ptr.offsets, tr->offsets_size / sizeof(binder_size_t));
958          reply->SetClearFdFlag();
959      }
960  
961      return ERR_NONE;
962  }
963  
HandleCommandsInner(uint32_t cmd)964  int BinderInvoker::HandleCommandsInner(uint32_t cmd)
965  {
966      int error = ERR_NONE;
967  
968      switch (cmd) {
969          case BR_ERROR:
970              error = input_.ReadInt32();
971              break;
972          case BR_ACQUIRE:
973          case BR_INCREFS:
974              OnAcquireObject(cmd);
975              break;
976          case BR_RELEASE:
977          case BR_DECREFS:
978              OnReleaseObject(cmd);
979              break;
980          case BR_ATTEMPT_ACQUIRE:
981              OnAttemptAcquire();
982              break;
983          case BR_TRANSACTION_SEC_CTX:
984          case BR_TRANSACTION:
985              OnTransaction(cmd, error);
986              break;
987          case BR_SPAWN_LOOPER:
988              OnSpawnThread();
989              break;
990          case BR_FINISHED:
991              error = -ERR_TIMED_OUT;
992              break;
993          case BR_DEAD_BINDER:
994              OnBinderDied();
995              break;
996          case BR_OK:
997          case BR_NOOP:
998              break;
999          case BR_CLEAR_DEATH_NOTIFICATION_DONE:
1000              OnRemoveRecipientDone();
1001              break;
1002  
1003          default:
1004              error = IPC_INVOKER_ON_TRANSACT_ERR;
1005              break;
1006      }
1007  
1008      return error;
1009  }
1010  
HandleCommands(uint32_t cmd)1011  int BinderInvoker::HandleCommands(uint32_t cmd)
1012  {
1013      auto start = std::chrono::steady_clock::now();
1014      int error = HandleCommandsInner(cmd);
1015      if (error != ERR_NONE && error != -ERR_TIMED_OUT) {
1016          if (ProcessSkeleton::IsPrint(error, lastErr_, lastErrCnt_)) {
1017              ZLOGE(LABEL, "HandleCommands cmd:%{public}u error:%{public}d", cmd, error);
1018              PrintParcelData(input_, "input_");
1019              PrintParcelData(output_, "output_");
1020              std::string backtrace;
1021              if (!GetBacktrace(backtrace, false)) {
1022                  ZLOGE(LABEL, "GetBacktrace fail");
1023              } else {
1024                  ZLOGW(LABEL, "backtrace info:\n%{public}s", backtrace.c_str());
1025              }
1026          }
1027      }
1028      if (cmd != BR_TRANSACTION) {
1029          auto finish = std::chrono::steady_clock::now();
1030          int duration = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(
1031              finish - start).count());
1032          if (duration >= IPC_CMD_PROCESS_WARN_TIME) {
1033              ZLOGW(LABEL, "HandleCommands cmd:%{public}u cost time:%{public}dms", cmd, duration);
1034          }
1035      }
1036      return error;
1037  }
1038  
JoinThread(bool initiative)1039  void BinderInvoker::JoinThread(bool initiative)
1040  {
1041      [[maybe_unused]] ThreadMigrationDisabler _d;
1042      isMainWorkThread = initiative;
1043      output_.WriteUint32(initiative ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
1044      StartWorkLoop();
1045      output_.WriteUint32(BC_EXIT_LOOPER);
1046      // pass in nullptr directly
1047      FlushCommands(nullptr);
1048      ZLOGE(LABEL, "Current Thread:%{public}d is leaving", getpid());
1049  }
1050  
JoinProcessThread(bool initiative)1051  void BinderInvoker::JoinProcessThread(bool initiative) {}
1052  
UpdateConsumedData(const binder_write_read & bwr,const size_t outAvail)1053  void BinderInvoker::UpdateConsumedData(const binder_write_read &bwr, const size_t outAvail)
1054  {
1055      if (bwr.write_consumed > 0) {
1056          if (bwr.write_consumed < outAvail) {
1057              // we still have some bytes not been handled.
1058              PrintParcelData(input_, "input_");
1059              PrintParcelData(output_, "output_");
1060              ZLOGE(LABEL, "binder write_consumed:%{public}llu exception, "
1061                  "outAvail:%{public}zu read_consumed:%{public}llu",
1062                  bwr.write_consumed, outAvail, bwr.read_consumed);
1063          }
1064  
1065          // Moves the data that is not consumed by the binder to the output_ buffer header.
1066          if (bwr.write_consumed < output_.GetDataSize()) {
1067              ZLOGI(LABEL, "moves the data that is not consumed by the binder, "
1068                  "write_consumed:%{public}llu outAvail:%{public}zu GetDataSize:%{public}zu",
1069                  bwr.write_consumed, outAvail, output_.GetDataSize());
1070              Parcel temp;
1071              temp.WriteBuffer(reinterpret_cast<void *>(output_.GetData() + bwr.write_consumed),
1072                  output_.GetDataSize() - bwr.write_consumed);
1073              output_.FlushBuffer();
1074              output_.WriteBuffer(reinterpret_cast<void *>(temp.GetData()), temp.GetDataSize());
1075          } else {
1076              --sendNestCount_;
1077              if (sendNestCount_ > 0) {
1078                  ZLOGW(LABEL, "unexpected sendNestCount:%{public}d", sendNestCount_.load());
1079                  PrintParcelData(input_, "input_");
1080                  PrintParcelData(output_, "output_");
1081                  sendNestCount_ = 0;
1082              }
1083              output_.FlushBuffer();
1084          }
1085      }
1086      if (bwr.read_consumed > 0) {
1087          input_.SetDataSize(bwr.read_consumed);
1088          input_.RewindRead(0);
1089      }
1090  }
1091  
TransactWithDriver(bool doRead)1092  int BinderInvoker::TransactWithDriver(bool doRead)
1093  {
1094      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
1095          return IPC_INVOKER_CONNECT_ERR;
1096      }
1097  
1098      binder_write_read bwr;
1099      const bool needRead = input_.GetReadableBytes() == 0;
1100      const size_t outAvail = (!doRead || needRead) ? output_.GetDataSize() : 0;
1101  
1102      bwr.write_size = (binder_size_t)outAvail;
1103      bwr.write_buffer = output_.GetData();
1104  
1105      if (doRead && needRead) {
1106          bwr.read_size = input_.GetDataCapacity();
1107          bwr.read_buffer = input_.GetData();
1108      } else {
1109          bwr.read_size = 0;
1110          bwr.read_buffer = 0;
1111      }
1112      if ((bwr.write_size == 0) && (bwr.read_size == 0)) {
1113          return ERR_NONE;
1114      }
1115  
1116      bwr.write_consumed = 0;
1117      bwr.read_consumed = 0;
1118  #ifdef CONFIG_ACTV_BINDER
1119      int error = binderConnector_->WriteBinder(GetBWRCommand(), &bwr);
1120  #else
1121      int error = binderConnector_->WriteBinder(BINDER_WRITE_READ, &bwr);
1122  #endif
1123      UpdateConsumedData(bwr, outAvail);
1124      if (error != ERR_NONE) {
1125          uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
1126              std::chrono::steady_clock::now().time_since_epoch()).count());
1127          ZLOGE(LABEL, "fail, result:%{public}d time:%{public}" PRIu64, error, curTime);
1128      }
1129  
1130      return error;
1131  }
1132  
WriteTransaction(int cmd,uint32_t flags,int32_t handle,uint32_t code,const MessageParcel & data,const int32_t * status,size_t totalDBinderBufSize)1133  bool BinderInvoker::WriteTransaction(int cmd, uint32_t flags, int32_t handle, uint32_t code, const MessageParcel &data,
1134      const int32_t *status, size_t totalDBinderBufSize)
1135  {
1136      binder_transaction_data_sg tr_sg {};
1137      auto &tr = tr_sg.transaction_data;
1138      bool isContainPtrType = totalDBinderBufSize > 0;
1139  
1140      tr.target.handle = (uint32_t)handle;
1141      tr.code = code;
1142      tr.flags = flags;
1143      tr.flags |= TF_ACCEPT_FDS;
1144      if (data.GetDataSize() > 0) {
1145          // Send this parcel's data through the binder.
1146          tr.data_size = data.GetDataSize();
1147          tr.data.ptr.buffer = (binder_uintptr_t)data.GetData();
1148          tr.offsets_size = data.GetOffsetsSize() * sizeof(binder_size_t);
1149          tr.data.ptr.offsets = data.GetObjectOffsets();
1150          tr_sg.buffers_size = isContainPtrType ? totalDBinderBufSize : 0;
1151      } else if (status != nullptr) {
1152          // Send this parcel's status through the binder.
1153          tr.flags |= TF_STATUS_CODE;
1154          tr.data_size = sizeof(int32_t);
1155          tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(status);
1156          tr.offsets_size = 0;
1157          tr.data.ptr.offsets = 0;
1158      }
1159  
1160      if (!output_.WriteInt32(cmd)) {
1161          ZLOGE(LABEL, "write cmd fail");
1162          return false;
1163      }
1164      const void *buf = isContainPtrType ? static_cast<const void *>(&tr_sg) : static_cast<const void *>(&tr);
1165      size_t bufSize = isContainPtrType ? sizeof(tr_sg) : sizeof(tr);
1166      bool ret = output_.WriteBuffer(buf, bufSize);
1167  
1168      if (sendNestCount_ > 0) {
1169          ZLOGW(LABEL, "request nesting occurs, handle:%{public}d count:%{public}u", handle, sendNestCount_.load());
1170          PrintParcelData(input_, "input_");
1171          PrintParcelData(output_, "output_");
1172          std::string backtrace;
1173          if (!GetBacktrace(backtrace, false)) {
1174              ZLOGE(LABEL, "GetBacktrace fail");
1175          } else {
1176              ZLOGW(LABEL, "backtrace info:\n%{public}s", backtrace.c_str());
1177          }
1178      }
1179      ++sendNestCount_;
1180      return ret;
1181  }
1182  
OnTransactionComplete(MessageParcel * reply,int32_t * acquireResult,bool & continueLoop,int32_t & error,uint32_t cmd)1183  void BinderInvoker::OnTransactionComplete(
1184      MessageParcel *reply, int32_t *acquireResult, bool &continueLoop, int32_t &error, uint32_t cmd)
1185  {
1186      (void)continueLoop;
1187      (void)error;
1188      (void)cmd;
1189  
1190      if (reply == nullptr && acquireResult == nullptr) {
1191          continueLoop = false;
1192      }
1193  }
1194  
OnDeadOrFailedReply(MessageParcel * reply,int32_t * acquireResult,bool & continueLoop,int32_t & error,uint32_t cmd)1195  void BinderInvoker::OnDeadOrFailedReply(
1196      MessageParcel *reply, int32_t *acquireResult, bool &continueLoop, int32_t &error, uint32_t cmd)
1197  {
1198      (void)reply;
1199  
1200      error = static_cast<int32_t>(cmd);
1201      if (acquireResult != nullptr) {
1202          *acquireResult = cmd;
1203      }
1204      continueLoop = false;
1205  }
1206  
OnAcquireResult(MessageParcel * reply,int32_t * acquireResult,bool & continueLoop,int32_t & error,uint32_t cmd)1207  void BinderInvoker::OnAcquireResult(
1208      MessageParcel *reply, int32_t *acquireResult, bool &continueLoop, int32_t &error, uint32_t cmd)
1209  {
1210      (void)reply;
1211      (void)error;
1212      (void)cmd;
1213  
1214      int32_t result = input_.ReadInt32();
1215      if (acquireResult != nullptr) {
1216          *acquireResult = result ? ERR_NONE : ERR_INVALID_OPERATION;
1217          continueLoop = false;
1218      }
1219  }
1220  
OnReply(MessageParcel * reply,int32_t * acquireResult,bool & continueLoop,int32_t & error,uint32_t cmd)1221  void BinderInvoker::OnReply(
1222      MessageParcel *reply, int32_t *acquireResult, bool &continueLoop, int32_t &error, uint32_t cmd)
1223  {
1224      (void)reply;
1225      (void)acquireResult;
1226      (void)cmd;
1227  
1228      bool isStubRet = false;
1229      error = HandleReply(reply, isStubRet);
1230      if (isStubRet || error != IPC_INVOKER_INVALID_REPLY_ERR) {
1231          continueLoop = false;
1232          return;
1233      }
1234      error = ERR_NONE;
1235  }
1236  
OnTranslationComplete(MessageParcel * reply,int32_t * acquireResult,bool & continueLoop,int32_t & error,uint32_t cmd)1237  void BinderInvoker::OnTranslationComplete(
1238      MessageParcel *reply, int32_t *acquireResult, bool &continueLoop, int32_t &error, uint32_t cmd)
1239  {
1240      (void)reply;
1241      (void)acquireResult;
1242      (void)error;
1243      (void)cmd;
1244  
1245      uint32_t handle = input_.ReadUint32();
1246      if (reply != nullptr) {
1247          reply->WriteUint32(handle);
1248      }
1249      continueLoop = false;
1250  }
1251  
DealWithCmd(MessageParcel * reply,int32_t * acquireResult,bool & continueLoop,int32_t & error,uint32_t cmd)1252  void BinderInvoker::DealWithCmd(
1253      MessageParcel *reply, int32_t *acquireResult, bool &continueLoop, int32_t &error, uint32_t cmd)
1254  {
1255      switch (cmd) {
1256          case BR_TRANSACTION_COMPLETE:
1257              OnTransactionComplete(reply, acquireResult, continueLoop, error, cmd);
1258              break;
1259          case BR_DEAD_REPLY:
1260          case BR_FAILED_REPLY:
1261              OnDeadOrFailedReply(reply, acquireResult, continueLoop, error, cmd);
1262              break;
1263          case BR_ACQUIRE_RESULT:
1264              OnAcquireResult(reply, acquireResult, continueLoop, error, cmd);
1265              break;
1266          case BR_REPLY:
1267              OnReply(reply, acquireResult, continueLoop, error, cmd);
1268              break;
1269          case BR_TRANSLATION_COMPLETE:
1270              OnTranslationComplete(reply, acquireResult, continueLoop, error, cmd);
1271              break;
1272          default:
1273              error = HandleCommands(cmd);
1274              if (error != ERR_NONE) {
1275                  continueLoop = false;
1276              }
1277              break;
1278      }
1279  }
1280  
WaitForCompletion(MessageParcel * reply,int32_t * acquireResult)1281  int BinderInvoker::WaitForCompletion(MessageParcel *reply, int32_t *acquireResult)
1282  {
1283      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
1284          ZLOGE(LABEL, "driver is died");
1285          return IPC_INVOKER_CONNECT_ERR;
1286      }
1287      uint32_t cmd;
1288      bool continueLoop = true;
1289      int error = ERR_NONE;
1290      while (continueLoop) {
1291          if ((error = TransactWithDriver()) < ERR_NONE) {
1292              break;
1293          }
1294          if (input_.GetReadableBytes() == 0) {
1295              continue;
1296          }
1297          cmd = input_.ReadUint32();
1298          DealWithCmd(reply, acquireResult, continueLoop, error, cmd);
1299      }
1300      return error;
1301  }
1302  
StopWorkThread()1303  void BinderInvoker::StopWorkThread()
1304  {
1305      stopWorkThread = true;
1306  }
1307  
PingService(int32_t handle)1308  bool BinderInvoker::PingService(int32_t handle)
1309  {
1310      MessageParcel data;
1311      MessageParcel reply;
1312      MessageOption option;
1313      int result = SendRequest(handle, PING_TRANSACTION, data, reply, option);
1314      return (result == ERR_NONE);
1315  }
1316  
SetRegistryObject(sptr<IRemoteObject> & object)1317  bool BinderInvoker::SetRegistryObject(sptr<IRemoteObject> &object)
1318  {
1319      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive()) || (object == nullptr)) {
1320          return false;
1321      }
1322  
1323      if (object->IsProxyObject()) {
1324          ZLOGE(LABEL, "set wrong object!");
1325          return false;
1326      }
1327  
1328  #ifdef WITH_SELINUX
1329      flat_binder_object flat = {
1330          .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
1331      };
1332  
1333      int result = binderConnector_->WriteBinder(BINDER_SET_CONTEXT_MGR_EXT, &flat);
1334      if (result == ERR_NONE) {
1335          return true;
1336      }
1337      ZLOGI(LABEL, "fail, error:%{public}d", result);
1338  #endif
1339  
1340      int dummy = 0;
1341      int res = binderConnector_->WriteBinder(BINDER_SET_CONTEXT_MGR, &dummy);
1342      if (res != ERR_NONE) {
1343          ZLOGE(LABEL, "fail, error:%{public}d", res);
1344          return false;
1345      }
1346  
1347      return true;
1348  }
1349  
FreeBuffer(void * data)1350  void BinderInvoker::FreeBuffer(void *data)
1351  {
1352      size_t rewindPos = output_.GetWritePosition();
1353      if (!output_.WriteUint32(BC_FREE_BUFFER)) {
1354          return;
1355      }
1356  
1357      if (!output_.WritePointer((uintptr_t)data)) {
1358          if (!output_.RewindWrite(rewindPos)) {
1359              output_.FlushBuffer();
1360          }
1361      }
1362  
1363      // Distribute data from output_ to the kernel for processing.
1364      int error = FlushCommands(nullptr);
1365      if (error != ERR_NONE) {
1366          ZLOGE(LABEL, "failed, error:%{public}d", error);
1367      }
1368  }
1369  
Dealloc(void * data)1370  void BinderInvoker::BinderAllocator::Dealloc(void *data)
1371  {
1372      IRemoteInvoker *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
1373      if (invoker != nullptr) {
1374          invoker->FreeBuffer(data);
1375      }
1376  }
1377  
GetCallerPid() const1378  pid_t BinderInvoker::GetCallerPid() const
1379  {
1380      // when the current caller information is self, obtain another binderinvoker
1381      auto pid = getpid();
1382      if (!status_ && pid != invokerInfo_.pid) {
1383          return invokerInfo_.pid;
1384      }
1385      return callerPid_;
1386  }
1387  
GetCallerSid() const1388  std::string BinderInvoker::GetCallerSid() const
1389  {
1390      auto pid = getpid();
1391      if (!status_ && pid != invokerInfo_.pid) {
1392          return invokerInfo_.sid;
1393      }
1394      return callerSid_;
1395  }
1396  
GetCallerRealPid() const1397  pid_t BinderInvoker::GetCallerRealPid() const
1398  {
1399      auto pid = getpid();
1400      if (!status_ && pid != invokerInfo_.pid) {
1401          return invokerInfo_.realPid;
1402      }
1403      return callerRealPid_;
1404  }
1405  
GetCallerUid() const1406  uid_t BinderInvoker::GetCallerUid() const
1407  {
1408      auto pid = getpid();
1409      if (!status_ && pid != invokerInfo_.pid) {
1410          return invokerInfo_.uid;
1411      }
1412      return callerUid_;
1413  }
1414  
GetCallerTokenID() const1415  uint64_t BinderInvoker::GetCallerTokenID() const
1416  {
1417      // If a process does NOT have a tokenid, the UID should be returned accordingly.
1418      auto pid = getpid();
1419      if (!status_ && pid != invokerInfo_.pid) {
1420          return (invokerInfo_.tokenId == 0) ? invokerInfo_.uid : invokerInfo_.tokenId;
1421      }
1422      return (callerTokenID_ == 0) ? callerUid_ : callerTokenID_;
1423  }
1424  
GetFirstCallerTokenID() const1425  uint64_t BinderInvoker::GetFirstCallerTokenID() const
1426  {
1427      auto pid = getpid();
1428      if (!status_ && pid != invokerInfo_.pid) {
1429          return invokerInfo_.firstTokenId;
1430      }
1431      return firstTokenID_;
1432  }
1433  
GetSelfTokenID() const1434  uint64_t BinderInvoker::GetSelfTokenID() const
1435  {
1436      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
1437          return 0;
1438      }
1439      uint64_t selfTokenId = binderConnector_->GetSelfTokenID();
1440      return (selfTokenId == 0) ? static_cast<uint64_t>(getuid()) : selfTokenId;
1441  }
1442  
GetSelfFirstCallerTokenID() const1443  uint64_t BinderInvoker::GetSelfFirstCallerTokenID() const
1444  {
1445      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
1446          return 0;
1447      }
1448      uint64_t selfFirstCallerTokenId = binderConnector_->GetSelfFirstCallerTokenID();
1449      return (selfFirstCallerTokenId == 0) ? static_cast<uint32_t>(getuid()) : selfFirstCallerTokenId;
1450  }
1451  
GetStatus()1452  uint32_t BinderInvoker::GetStatus()
1453  {
1454      if (status_ != BinderInvoker::ACTIVE_INVOKER) {
1455          auto current = ProcessSkeleton::GetInstance();
1456          if (current != nullptr) {
1457              bool flag = current->QueryInvokerProcInfo(true, invokerInfo_) && (getpid() != invokerInfo_.pid);
1458              return flag ? BinderInvoker::ACTIVE_INVOKER : BinderInvoker::IDLE_INVOKER;
1459          }
1460      }
1461      return status_;
1462  }
1463  
SetStatus(uint32_t status)1464  void BinderInvoker::SetStatus(uint32_t status)
1465  {
1466      status_ = status;
1467  }
1468  
GetLocalDeviceID()1469  std::string BinderInvoker::GetLocalDeviceID()
1470  {
1471      return "";
1472  }
1473  
GetCallerDeviceID() const1474  std::string BinderInvoker::GetCallerDeviceID() const
1475  {
1476      return "";
1477  }
1478  
IsLocalCalling()1479  bool BinderInvoker::IsLocalCalling()
1480  {
1481      return true;
1482  }
1483  
FlattenObject(Parcel & parcel,const IRemoteObject * object) const1484  bool BinderInvoker::FlattenObject(Parcel &parcel, const IRemoteObject *object) const
1485  {
1486      if (object == nullptr) {
1487          return false;
1488      }
1489      flat_binder_object flat;
1490      flat.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
1491      if (object->IsProxyObject()) {
1492          const IPCObjectProxy *proxy = reinterpret_cast<const IPCObjectProxy *>(object);
1493          const int32_t handle = proxy ? static_cast<int32_t>(proxy->GetHandle()) : -1;
1494          flat.hdr.type = BINDER_TYPE_HANDLE;
1495          flat.binder = 0;
1496          flat.handle = (uint32_t)handle;
1497          flat.cookie = proxy ? static_cast<binder_uintptr_t>(proxy->GetProto()) : 0;
1498      } else {
1499          const IPCObjectStub *stub = reinterpret_cast<const IPCObjectStub *>(object);
1500          if (stub->GetRequestSidFlag()) {
1501              flat.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
1502          }
1503          flat.hdr.type = BINDER_TYPE_BINDER;
1504          flat.binder = reinterpret_cast<uintptr_t>(object->GetRefCounter());
1505          flat.cookie = reinterpret_cast<uintptr_t>(object);
1506      }
1507  
1508      bool status = parcel.WriteBuffer(&flat, sizeof(flat_binder_object));
1509      if (!status) {
1510          ZLOGE(LABEL, "Fail to flatten object");
1511      }
1512      return status;
1513  }
1514  
UnflattenObject(Parcel & parcel)1515  sptr<IRemoteObject> BinderInvoker::UnflattenObject(Parcel &parcel)
1516  {
1517  #ifndef CONFIG_IPC_SINGLE
1518      dbinder_negotiation_data dbinderData;
1519      bool isDBinderObj = UnFlattenDBinderObject(parcel, dbinderData);
1520  #endif
1521      if (!parcel.CheckOffsets()) {
1522          ZLOGE(LABEL, "Parcel CheckOffsets fail");
1523          return nullptr;
1524      }
1525      const uint8_t *buffer = parcel.ReadBuffer(sizeof(flat_binder_object), false);
1526      if (buffer == nullptr) {
1527          ZLOGE(LABEL, "null object buffer");
1528          return nullptr;
1529      }
1530      IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
1531      if (current == nullptr) {
1532          return nullptr;
1533      }
1534  
1535      sptr<IRemoteObject> remoteObject = nullptr;
1536      auto *flat = reinterpret_cast<const flat_binder_object *>(buffer);
1537      switch (flat->hdr.type) {
1538          case BINDER_TYPE_BINDER: {
1539              auto stubObject = reinterpret_cast<IRemoteObject *>(flat->cookie);
1540              if (!current->IsContainsObject(stubObject)) {
1541                  ZLOGE(LABEL, "invalid binder cookie:%{public}llu", flat->cookie);
1542                  return nullptr;
1543              }
1544              remoteObject = stubObject;
1545              break;
1546          }
1547          case BINDER_TYPE_HANDLE: {
1548  #ifndef CONFIG_IPC_SINGLE
1549              if (isDBinderObj) {
1550                  ZLOGI(LABEL, "dbinder BINDER_TYPE_HANDLE");
1551              }
1552              remoteObject = current->FindOrNewObject(flat->handle, isDBinderObj ? &dbinderData : nullptr);
1553  #else
1554              remoteObject = current->FindOrNewObject(flat->handle);
1555  #endif
1556              break;
1557          }
1558          default:
1559              ZLOGE(LABEL, "unknown binder type:%{public}u", flat->hdr.type);
1560              break;
1561      }
1562      return remoteObject;
1563  }
1564  
ReadFileDescriptor(Parcel & parcel)1565  int BinderInvoker::ReadFileDescriptor(Parcel &parcel)
1566  {
1567      int fd = -1;
1568      const uint8_t *buffer = parcel.ReadBuffer(sizeof(flat_binder_object), false);
1569      if (buffer == nullptr) {
1570          ZLOGE(LABEL, "UnflattenObject null object buffer");
1571          return fd;
1572      }
1573  
1574      auto *flat = reinterpret_cast<const flat_binder_object *>(buffer);
1575      if (flat->hdr.type == BINDER_TYPE_FD || flat->hdr.type == BINDER_TYPE_FDR) {
1576          fd = flat->handle;
1577          ZLOGD(LABEL, "fd:%{public}d", fd);
1578      } else {
1579          ZLOGE(LABEL, "unknown binder type:%{public}u", flat->hdr.type);
1580      }
1581  
1582      return fd;
1583  }
1584  
WriteFileDescriptor(Parcel & parcel,int fd,bool takeOwnership)1585  bool BinderInvoker::WriteFileDescriptor(Parcel &parcel, int fd, bool takeOwnership)
1586  {
1587      flat_binder_object flat;
1588      flat.hdr.type = BINDER_TYPE_FD;
1589      flat.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
1590      flat.binder = 0; // Don't pass uninitialized stack data to a remote process
1591      flat.handle = static_cast<__u32>(fd);
1592      flat.cookie = takeOwnership ? 1 : 0;
1593  
1594      return parcel.WriteBuffer(&flat, sizeof(flat_binder_object));
1595  }
1596  
ResetCallingIdentity()1597  std::string BinderInvoker::ResetCallingIdentity()
1598  {
1599      pid_t tempPid = callerPid_;
1600      pid_t tempRealPid = callerRealPid_;
1601      pid_t tempUid = callerUid_;
1602      uint64_t tempTokenId = callerTokenID_;
1603      std::string tempSid = callerSid_;
1604  
1605      auto pid = getpid();
1606      if (!status_ && pid != invokerInfo_.pid) {
1607          tempPid = invokerInfo_.pid;
1608          tempRealPid = invokerInfo_.realPid;
1609          tempUid = invokerInfo_.uid;
1610          tempTokenId = invokerInfo_.tokenId;
1611          tempSid = invokerInfo_.sid;
1612      }
1613  
1614      char buf[ACCESS_TOKEN_MAX_LEN + 1] = {0};
1615      int ret = sprintf_s(buf, ACCESS_TOKEN_MAX_LEN + 1, "%010" PRIu64, tempTokenId);
1616      if (ret < 0) {
1617          ZLOGE(LABEL, "sprintf callerTokenID:%{public}" PRIu64 " failed", tempTokenId);
1618          return "";
1619      }
1620      std::string accessToken(buf);
1621      ret = sprintf_s(buf, ACCESS_TOKEN_MAX_LEN + 1, "%010d", tempRealPid);
1622      if (ret < 0) {
1623          ZLOGE(LABEL, "sprintf callerRealPid_:%{public}d failed", tempRealPid);
1624          return "";
1625      }
1626      std::string realPid(buf);
1627      std::string pidUid = std::to_string(((static_cast<uint64_t>(tempUid) << PID_LEN)
1628          | static_cast<uint64_t>(tempPid)));
1629      callerUid_ = static_cast<pid_t>(getuid());
1630      callerPid_ = getpid();
1631      callerRealPid_ = getprocpid();
1632      callerTokenID_ = GetSelfTokenID();
1633      callerSid_ = "";
1634      return tempSid + "<" + accessToken + realPid + pidUid; // '<' is the separator character
1635  }
1636  
PrintIdentity(bool isPrint,bool isBefore)1637  void BinderInvoker::PrintIdentity(bool isPrint, bool isBefore)
1638  {
1639      if (!isPrint) {
1640          return;
1641      }
1642      ZLOGI(LABEL, "%{public}s callingIdentity, callerSid:%{public}s, callerTokenID:%{public}" PRIu64 ", \
1643          callerRealPid:%{public}u, callerUid:%{public}u, callerPid:%{public}u",
1644          isBefore ? "Before" : "After", callerSid_.c_str(), callerTokenID_, callerRealPid_, callerUid_, callerPid_);
1645  }
1646  
SetCallingIdentity(std::string & identity,bool flag)1647  bool BinderInvoker::SetCallingIdentity(std::string &identity, bool flag)
1648  {
1649      if (identity.empty() || identity.length() <= ACCESS_TOKEN_MAX_LEN) {
1650          return false;
1651      }
1652      auto pos = identity.find('<');
1653      if (pos == std::string::npos) {
1654          return false;
1655      }
1656      PrintIdentity(flag, true);
1657      std::string callerSid;
1658      if (!ProcessSkeleton::GetSubStr(identity, callerSid, 0, pos)) {
1659          ZLOGE(LABEL, "Identity param callerSid is invalid");
1660          return false;
1661      }
1662      std::string tokenIdStr;
1663      if (!ProcessSkeleton::GetSubStr(identity, tokenIdStr, pos + 1, ACCESS_TOKEN_MAX_LEN) ||
1664          !ProcessSkeleton::IsNumStr(tokenIdStr)) {
1665          ZLOGE(LABEL, "Identity param tokenId is invalid");
1666          return false;
1667      }
1668      std::string realPidStr;
1669      if (!ProcessSkeleton::GetSubStr(identity, realPidStr, pos + 1 + ACCESS_TOKEN_MAX_LEN, ACCESS_TOKEN_MAX_LEN) ||
1670          !ProcessSkeleton::IsNumStr(realPidStr)) {
1671          ZLOGE(LABEL, "Identity param realPid is invalid");
1672          return false;
1673      }
1674      std::string pidUidStr;
1675      size_t offset = pos + 1 + ACCESS_TOKEN_MAX_LEN * PIDUID_OFFSET;
1676      if (identity.length() <= offset) {
1677          ZLOGE(LABEL, "Identity param no pidUid, len:%{public}zu, offset:%{public}zu", identity.length(), offset);
1678          return false;
1679      }
1680      size_t subLen = identity.length() - offset;
1681      if (!ProcessSkeleton::GetSubStr(identity, pidUidStr, offset, subLen) || !ProcessSkeleton::IsNumStr(pidUidStr)) {
1682          ZLOGE(LABEL, "Identity param pidUid is invalid");
1683          return false;
1684      }
1685      callerSid_ = callerSid;
1686      callerTokenID_ = std::stoull(tokenIdStr.c_str());
1687      callerRealPid_ = static_cast<int>(std::stoull(realPidStr.c_str()));
1688      uint64_t pidUid = std::stoull(pidUidStr.c_str());
1689      callerUid_ = static_cast<int>(pidUid >> PID_LEN);
1690      callerPid_ = static_cast<int>(pidUid);
1691      PrintIdentity(flag, false);
1692      return true;
1693  }
1694  
GetStrongRefCountForStub(uint32_t handle)1695  uint32_t BinderInvoker::GetStrongRefCountForStub(uint32_t handle)
1696  {
1697      if ((binderConnector_ == nullptr) || (!binderConnector_->IsDriverAlive())) {
1698          return 0;  // 0 means get failed
1699      }
1700      binder_node_info_for_ref info;
1701      memset_s(&info, sizeof(binder_node_info_for_ref), 0, sizeof(binder_node_info_for_ref));
1702  
1703      info.handle = handle;
1704      int32_t result = binderConnector_->WriteBinder(BINDER_GET_NODE_INFO_FOR_REF, &info);
1705      if (result != ERR_NONE) {
1706          ZLOGE(LABEL, "WriteBinder failed, Error code %{public}d", result);
1707          return 0;  // 0 means get failed
1708      }
1709  
1710      return info.strong_count;
1711  }
1712  
PrintParcelData(Parcel & parcel,const std::string & parcelName)1713  void BinderInvoker::PrintParcelData(Parcel &parcel, const std::string &parcelName)
1714  {
1715      std::string formatStr;
1716      size_t size = parcel.GetDataSize();
1717      auto data = reinterpret_cast<const uint8_t *>(parcel.GetData());
1718      size_t idex = 0;
1719      while (idex < size) {
1720          formatStr += std::to_string(data[idex]) + ',';
1721          ++idex;
1722      }
1723      ZLOGE(LABEL,
1724          "parcel name:%{public}s, size:%{public}zu, readpos:%{public}zu, writepos:%{public}zu, data:%{public}s",
1725          parcelName.c_str(), size, parcel.GetReadPosition(), parcel.GetWritePosition(), formatStr.c_str());
1726  }
1727  
IsSendRequesting()1728  bool BinderInvoker::IsSendRequesting()
1729  {
1730      return sendRequestCount_ > 0;
1731  }
1732  
ProcDeferredDecRefs()1733  void BinderInvoker::ProcDeferredDecRefs()
1734  {
1735      if (input_.GetReadableBytes() > 0) {
1736          return;
1737      }
1738      {
1739          std::lock_guard<std::mutex> lock(weakRefMutex_);
1740          for (size_t idx = 0; idx < decWeakRefs_.size(); ++idx) {
1741              auto &ref = decWeakRefs_[idx];
1742              ref->DecWeakRefCount(this);
1743          }
1744          decWeakRefs_.clear();
1745      }
1746      {
1747          ProcessSkeleton *current = ProcessSkeleton::GetInstance();
1748          if (current == nullptr) {
1749              ZLOGE(LABEL, "ProcessSkeleton is null");
1750              return;
1751          }
1752          std::lock_guard<std::mutex> lock(strongRefMutex_);
1753          for (size_t idx = 0; idx < decStrongRefs_.size(); ++idx) {
1754              auto &obj = decStrongRefs_[idx];
1755              std::u16string desc;
1756              if (!current->IsValidObject(obj, desc)) {
1757                  ZLOGE(LABEL, "%{public}u is invalid", ProcessSkeleton::ConvertAddr(obj));
1758                  continue;
1759              }
1760              std::string descTemp = Str16ToStr8(desc);
1761              CrashObjDumper dumper(descTemp.c_str());
1762              obj->DecStrongRef(this);
1763          }
1764          decStrongRefs_.clear();
1765      }
1766  }
1767  
1768  #ifdef CONFIG_ACTV_BINDER
JoinActvThread(bool initiative)1769  void BinderInvoker::JoinActvThread(bool initiative)
1770  {
1771      IRemoteInvoker *remoteInvoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_BINDER);
1772      BinderInvoker *invoker = reinterpret_cast<BinderInvoker *>(remoteInvoker);
1773  
1774      if (invoker != nullptr) {
1775          invoker->SetUseActvBinder(true);
1776          invoker->JoinThread(initiative);
1777      }
1778  }
1779  
IsActvBinderService()1780  bool BinderInvoker::IsActvBinderService()
1781  {
1782      bool check = false;
1783      IRemoteInvoker *remoteInvoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_BINDER);
1784      BinderInvoker *invoker = reinterpret_cast<BinderInvoker *>(remoteInvoker);
1785  
1786      if ((invoker != nullptr) && (invoker->binderConnector_ != nullptr)) {
1787          check = invoker->binderConnector_->IsActvBinderService();
1788      }
1789  
1790      return check;
1791  }
1792  #endif // CONFIG_ACTV_BINDER
1793  
1794  #ifdef CONFIG_IPC_SINGLE
1795  } // namespace IPC_SINGLE
1796  #endif
1797  } // namespace OHOS
1798