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