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