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