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