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 "dbinder_databus_invoker.h"
17 #include <cinttypes>
18 #include "string_ex.h"
19 #include "securec.h"
20 #include "sys_binder.h"
21
22 #include "access_token_adapter.h"
23 #include "ipc_object_stub.h"
24 #include "ipc_object_proxy.h"
25 #include "ipc_process_skeleton.h"
26 #include "ipc_thread_skeleton.h"
27 #include "ipc_debug.h"
28 #include "log_tags.h"
29 #include "databus_session_callback.h"
30 #include "rpc_feature_set.h"
31
32 namespace OHOS {
33 using namespace OHOS::HiviewDFX;
DBinderDatabusInvoker()34 DBinderDatabusInvoker::DBinderDatabusInvoker()
35 : stopWorkThread_(false), callerPid_(getpid()), callerUid_(getuid()), callerDeviceID_(""),
36 callerTokenID_(0), firstTokenID_(0), status_(0)
37 {
38 ZLOGI(LOG_LABEL, "Create DBinderDatabusInvoker");
39 }
40
~DBinderDatabusInvoker()41 DBinderDatabusInvoker::~DBinderDatabusInvoker()
42 {
43 ZLOGI(LOG_LABEL, "Clean DBinderDatabusInvoker");
44 }
45
AcquireHandle(int32_t handle)46 bool DBinderDatabusInvoker::AcquireHandle(int32_t handle)
47 {
48 ZLOGI(LOG_LABEL, "Acquire Handle %{public}d", handle);
49 return true;
50 }
51
ReleaseHandle(int32_t handle)52 bool DBinderDatabusInvoker::ReleaseHandle(int32_t handle)
53 {
54 ZLOGI(LOG_LABEL, "Release Handle %{public}d", handle);
55 return true;
56 }
57
NewSessionOfBinderProxy(uint32_t handle,std::shared_ptr<DBinderSessionObject> remoteSession)58 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::NewSessionOfBinderProxy(uint32_t handle,
59 std::shared_ptr<DBinderSessionObject> remoteSession)
60 {
61 if (remoteSession == nullptr) {
62 ZLOGE(LOG_LABEL, "remote session is nullptr");
63 return nullptr;
64 }
65
66 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
67 if (current == nullptr) {
68 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
69 return nullptr;
70 }
71 sptr<IPCObjectProxy> ipcProxy = reinterpret_cast<IPCObjectProxy *>(current->FindOrNewObject(handle).GetRefPtr());
72 if (ipcProxy == nullptr) {
73 ZLOGE(LOG_LABEL, "attempt to send a invalid handle = %u", handle);
74 return nullptr;
75 }
76
77 if (ipcProxy->GetProto() != IRemoteObject::IF_PROT_BINDER) {
78 ZLOGE(LOG_LABEL, "attempt to send a distributed proxy, handle = %u", handle);
79 return nullptr;
80 }
81
82 std::string sessionName = ipcProxy->GetPidAndUidInfo(0);
83 if (sessionName.empty()) {
84 ZLOGE(LOG_LABEL, "get bus name error");
85 return nullptr;
86 }
87
88 std::shared_ptr<Session> session = remoteSession->GetBusSession();
89 if (session == nullptr) {
90 ZLOGE(LOG_LABEL, "get databus session fail");
91 return nullptr;
92 }
93
94 MessageParcel data, reply;
95 if (!data.WriteUint32(IRemoteObject::DATABUS_TYPE) || !data.WriteString(current->GetLocalDeviceID()) ||
96 !data.WriteUint32((uint32_t)(session->GetPeerPid())) || !data.WriteUint32(session->GetPeerUid()) ||
97 !data.WriteString(session->GetPeerDeviceId()) || !data.WriteString(sessionName)) {
98 ZLOGE(LOG_LABEL, "write to parcel fail");
99 return nullptr;
100 }
101 int err = ipcProxy->InvokeListenThread(data, reply);
102 if (err != ERR_NONE) {
103 ZLOGE(LOG_LABEL, "start service listen error = %d", err);
104 return nullptr;
105 }
106
107 uint64_t stubIndex = reply.ReadUint64();
108 if (stubIndex == 0) {
109 ZLOGE(LOG_LABEL, "stubindex error = %" PRIu64 "", stubIndex);
110 return nullptr;
111 }
112
113 if (!current->AttachHandleToIndex(handle, stubIndex)) {
114 ZLOGE(LOG_LABEL, "add stub index err stubIndex = %" PRIu64 ", handle = %u", stubIndex, handle);
115 // do nothing, Sending an object repeatedly
116 }
117
118 std::string serverName = reply.ReadString();
119 std::string deviceId = reply.ReadString();
120 ZLOGI(LOG_LABEL, "NewSessionOfBinderProxy serverName= %s", serverName.c_str());
121
122 std::shared_ptr<DBinderSessionObject> connectSession =
123 std::make_shared<DBinderSessionObject>(nullptr, serverName, deviceId);
124 if (connectSession == nullptr) {
125 ZLOGE(LOG_LABEL, "new server session fail!");
126 return nullptr;
127 }
128
129 return connectSession;
130 }
131
AuthSession2Proxy(uint32_t handle,const std::shared_ptr<DBinderSessionObject> databusSession)132 bool DBinderDatabusInvoker::AuthSession2Proxy(uint32_t handle,
133 const std::shared_ptr<DBinderSessionObject> databusSession)
134 {
135 if (databusSession == nullptr) {
136 ZLOGE(LOG_LABEL, "remote session is nullptr");
137 return false;
138 }
139
140 std::shared_ptr<Session> session = databusSession->GetBusSession();
141 if (session == nullptr) {
142 ZLOGE(LOG_LABEL, "get databus session fail");
143 return false;
144 }
145
146 std::shared_ptr<FeatureSetData> feature = databusSession->GetFeatureSet();
147 if (feature == nullptr) {
148 ZLOGE(LOG_LABEL, "get feature fail");
149 return false;
150 }
151
152 MessageParcel data, reply;
153 MessageOption option;
154
155 if (!data.WriteUint32((uint32_t)(session->GetPeerPid())) || !data.WriteUint32(session->GetPeerUid()) ||
156 !data.WriteString(session->GetPeerDeviceId()) || !data.WriteUint32(feature->featureSet)) {
157 ZLOGE(LOG_LABEL, "write to MessageParcel fail");
158 return false;
159 }
160
161 int32_t err = SendRequest(handle, DBINDER_ADD_COMMAUTH, data, reply, option);
162 if (err != ERR_NONE) {
163 ZLOGE(LOG_LABEL, "send auth info to remote fail");
164 return false;
165 }
166 return true;
167 }
168
QuerySessionOfBinderProxy(uint32_t handle,std::shared_ptr<DBinderSessionObject> session)169 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::QuerySessionOfBinderProxy(uint32_t handle,
170 std::shared_ptr<DBinderSessionObject> session)
171 {
172 if (AuthSession2Proxy(handle, session) != true) {
173 ZLOGE(LOG_LABEL, "auth handle =%{public}u to session failed", handle);
174 return nullptr;
175 }
176 return QueryServerSessionObject(handle);
177 }
178
QueryClientSessionObject(uint32_t databusHandle)179 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::QueryClientSessionObject(uint32_t databusHandle)
180 {
181 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
182 if (current == nullptr) {
183 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
184 return nullptr;
185 }
186 std::shared_ptr<DBinderSessionObject> sessionOfPeer = current->StubQueryDBinderSession(databusHandle);
187 if (sessionOfPeer == nullptr) {
188 ZLOGE(LOG_LABEL, "no session attach to this proxy = %{public}u", databusHandle);
189 return nullptr;
190 }
191 return sessionOfPeer;
192 }
193
QueryServerSessionObject(uint32_t handle)194 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::QueryServerSessionObject(uint32_t handle)
195 {
196 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
197 if (current == nullptr) {
198 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
199 return nullptr;
200 }
201
202 std::shared_ptr<DBinderSessionObject> sessionOfPeer = current->ProxyQueryDBinderSession(handle);
203 if (sessionOfPeer == nullptr) {
204 ZLOGI(LOG_LABEL, "no session attach to this handle = %{public}u", handle);
205 return nullptr;
206 }
207
208 return sessionOfPeer;
209 }
210
OnReceiveNewConnection(std::shared_ptr<Session> session)211 bool DBinderDatabusInvoker::OnReceiveNewConnection(std::shared_ptr<Session> session)
212 {
213 uint32_t handle = IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId());
214 if (handle == 0) {
215 return false;
216 }
217
218 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
219 if (current == nullptr) {
220 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
221 return false;
222 }
223
224 auto featureSet = current->QueryIsAuth(session->GetPeerPid(), (int32_t)(session->GetPeerUid()),
225 session->GetPeerDeviceId());
226 if (featureSet == nullptr) {
227 ZLOGE(LOG_LABEL, "query auth failed, remote device featureSet is null");
228 return false;
229 }
230
231 std::shared_ptr<DBinderSessionObject> sessionObject =
232 std::make_shared<DBinderSessionObject>(session, session->GetPeerSessionName(), session->GetPeerDeviceId());
233 sessionObject->SetFeatureSet(featureSet);
234
235 if (!current->StubAttachDBinderSession(handle, sessionObject)) {
236 ZLOGE(LOG_LABEL, "attach session to process skeleton failed, handle =%u", handle);
237 }
238 return true;
239 }
240
CreateProcessThread()241 bool DBinderDatabusInvoker::CreateProcessThread()
242 {
243 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
244 if (current == nullptr) {
245 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
246 return false;
247 }
248 /* epoll thread obtained one thread, so idle thread must more than 1 */
249 if (current->GetSocketIdleThreadNum() > 0) {
250 current->SpawnThread(IPCWorkThread::PROCESS_PASSIVE, IRemoteObject::IF_PROT_DATABUS);
251 ZLOGI(LOG_LABEL, "create Process thread success");
252 return true;
253 }
254
255 ZLOGE(LOG_LABEL, "no idle socket thread left, fail to CreateProcessThread");
256 return false;
257 }
258
OnRawDataAvailable(std::shared_ptr<Session> session,const char * data,uint32_t dataSize)259 void DBinderDatabusInvoker::OnRawDataAvailable(std::shared_ptr<Session> session, const char *data, uint32_t dataSize)
260 {
261 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
262 if (current == nullptr) {
263 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
264 return;
265 }
266
267 uint32_t rawDataSize = dataSize - sizeof(dbinder_transaction_data);
268 if (rawDataSize > 0 && rawDataSize <= MAX_RAWDATA_SIZE - sizeof(dbinder_transaction_data)) {
269 std::shared_ptr<InvokerRawData> invokerRawData = std::make_shared<InvokerRawData>(rawDataSize);
270 if (memcpy_s(invokerRawData->GetData().get(), rawDataSize, data + sizeof(dbinder_transaction_data),
271 rawDataSize) != EOK) {
272 ZLOGE(LOG_LABEL, "memcpy_s failed , size = %u", rawDataSize);
273 return;
274 }
275 if (!current->AttachRawData(IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId()),
276 invokerRawData)) {
277 return;
278 }
279 }
280 return;
281 }
282
283 /*
284 * Write 64K=SOCKET_BUFF_SIZE
285 * +------------------+-------------------------+----------------|
286 * |0<---processed--->|Read <----need process-->|<--idle buffer-->
287 * -cursor
288 *
289 * when idle buffer less 1k, move need process to buffer head, then update R/W cursor
290 * when idle buffer can not put a full package, also move need process package to buffer head
291 */
OnMessageAvailable(std::shared_ptr<Session> session,const char * data,ssize_t len)292 void DBinderDatabusInvoker::OnMessageAvailable(std::shared_ptr<Session> session, const char *data, ssize_t len)
293 {
294 if (session == nullptr || data == nullptr || len > static_cast<ssize_t>(MAX_RAWDATA_SIZE) ||
295 len < static_cast<ssize_t>(sizeof(dbinder_transaction_data))) {
296 ZLOGE(LOG_LABEL, "session has wrong inputs");
297 return;
298 }
299
300 uint32_t packageSize = HasRawDataPackage(data, len);
301 if (packageSize > 0) {
302 // Only one set of big data can be transferred at a time.
303 return OnRawDataAvailable(session, data, packageSize);
304 }
305
306 uint32_t handle = IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId());
307 uint32_t readSize = 0;
308 do {
309 packageSize = HasCompletePackage(data, readSize, len);
310 if (packageSize > 0) {
311 StartProcessLoop(handle, data + readSize, packageSize);
312 readSize += packageSize;
313 } else {
314 // If the current is abnormal, the subsequent is no longer processed.
315 ZLOGE(LOG_LABEL, "not complete message");
316 break;
317 }
318 } while (readSize + sizeof(dbinder_transaction_data) < static_cast<uint32_t>(len));
319 }
320
OnSendMessage(std::shared_ptr<DBinderSessionObject> sessionOfPeer)321 int DBinderDatabusInvoker::OnSendMessage(std::shared_ptr<DBinderSessionObject> sessionOfPeer)
322 {
323 if (sessionOfPeer == nullptr) {
324 ZLOGE(LOG_LABEL, "sessionOfPeer is null");
325 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
326 }
327
328 std::shared_ptr<Session> session = sessionOfPeer->GetBusSession();
329 if (session == nullptr) {
330 ZLOGE(LOG_LABEL, "databus session is null");
331 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
332 }
333
334 std::shared_ptr<BufferObject> sessionBuff = sessionOfPeer->GetSessionBuff();
335 if (sessionBuff == nullptr) {
336 ZLOGE(LOG_LABEL, "databus session buff is null");
337 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
338 }
339
340 char *sendBuffer = sessionBuff->GetSendBufferAndLock(SOCKET_DEFAULT_BUFF_SIZE);
341 /* session buffer contain mutex, need release mutex */
342 if (sendBuffer == nullptr) {
343 ZLOGE(LOG_LABEL, "buffer alloc failed in session");
344 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
345 }
346 sessionBuff->UpdateSendBuffer();
347 ssize_t writeCursor = sessionBuff->GetSendBufferWriteCursor();
348 ssize_t readCursor = sessionBuff->GetSendBufferReadCursor();
349 if (writeCursor <= readCursor) {
350 sessionBuff->ReleaseSendBufferLock();
351 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
352 }
353
354 ssize_t size = writeCursor - readCursor;
355 int ret = session->SendBytes(static_cast<const void *>(sendBuffer + readCursor), size);
356 if (ret == 0) {
357 readCursor += size;
358 sessionBuff->SetSendBufferReadCursor(readCursor);
359 sessionBuff->SetSendBufferWriteCursor(writeCursor);
360 }
361 ZLOGI(LOG_LABEL, "sendNormalData len: %{public}u, ret: %{public}d", static_cast<uint32_t>(size), ret);
362 sessionBuff->ReleaseSendBufferLock();
363 return ret;
364 }
365
OnSendRawData(std::shared_ptr<DBinderSessionObject> session,const void * data,size_t size)366 int DBinderDatabusInvoker::OnSendRawData(std::shared_ptr<DBinderSessionObject> session, const void *data, size_t size)
367 {
368 if (session == nullptr) {
369 ZLOGE(LOG_LABEL, "sessionOfPeer is null");
370 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
371 }
372
373 std::shared_ptr<Session> dataBusSession = session->GetBusSession();
374 if (dataBusSession == nullptr) {
375 ZLOGE(LOG_LABEL, "databus session is null");
376 return -RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
377 }
378
379 int ret = dataBusSession->SendBytes(data, size);
380 ZLOGI(LOG_LABEL, "sendRawData len: %{public}u, ret: %{public}d", static_cast<uint32_t>(size), ret);
381 return ret;
382 }
383
JoinThread(bool initiative)384 void DBinderDatabusInvoker::JoinThread(bool initiative) {}
385
JoinProcessThread(bool initiative)386 void DBinderDatabusInvoker::JoinProcessThread(bool initiative)
387 {
388 std::thread::id threadId = std::this_thread::get_id();
389 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
390 if (current == nullptr) {
391 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
392 return;
393 }
394
395 std::shared_ptr<ThreadProcessInfo> processInfo = nullptr;
396 do {
397 current->AddDataThreadInWait(threadId);
398 while ((processInfo = current->PopDataInfoFromThread(threadId)) != nullptr) {
399 OnTransaction(processInfo);
400 }
401 } while (!stopWorkThread_);
402 }
403
StopWorkThread()404 void DBinderDatabusInvoker::StopWorkThread()
405 {
406 stopWorkThread_ = true;
407 }
408
FlattenSession(char * sessionOffset,const std::shared_ptr<DBinderSessionObject> connectSession,uint64_t stubIndex)409 uint32_t DBinderDatabusInvoker::FlattenSession(char *sessionOffset,
410 const std::shared_ptr<DBinderSessionObject> connectSession, uint64_t stubIndex)
411 {
412 FlatDBinderSession *flatSession = reinterpret_cast<FlatDBinderSession *>(sessionOffset);
413 flatSession->stubIndex = stubIndex;
414
415 flatSession->deviceIdLength = connectSession->GetDeviceId().length();
416 if (flatSession->deviceIdLength == 0 || flatSession->deviceIdLength > DEVICEID_LENGTH) {
417 ZLOGE(LOG_LABEL, "wrong devices id");
418 return 0;
419 }
420 int memcpyResult = memcpy_s(flatSession->deviceId, DEVICEID_LENGTH, connectSession->GetDeviceId().data(),
421 flatSession->deviceIdLength);
422 if (memcpyResult != 0) {
423 ZLOGE(LOG_LABEL, "memcpy_s failed , ID Size = %hu", flatSession->deviceIdLength);
424 return 0;
425 }
426 flatSession->deviceId[flatSession->deviceIdLength] = '\0';
427
428 flatSession->serviceNameLength = connectSession->GetServiceName().length();
429 if (flatSession->serviceNameLength == 0 || flatSession->serviceNameLength > SERVICENAME_LENGTH) {
430 ZLOGE(LOG_LABEL, "wrong service name");
431 return 0;
432 }
433 memcpyResult = memcpy_s(flatSession->serviceName, SERVICENAME_LENGTH, connectSession->GetServiceName().data(),
434 flatSession->serviceNameLength);
435 if (memcpyResult != 0) {
436 ZLOGE(LOG_LABEL, "memcpy_s failed , name Size = %hu", flatSession->serviceNameLength);
437 return 0;
438 }
439 flatSession->serviceName[flatSession->serviceNameLength] = '\0';
440
441 ZLOGI(LOG_LABEL, "serviceName = %s, stubIndex = %" PRIu64 "", flatSession->serviceName, flatSession->stubIndex);
442
443 return sizeof(struct FlatDBinderSession);
444 }
445
UnFlattenSession(char * sessionOffset,uint64_t & stubIndex)446 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::UnFlattenSession(char *sessionOffset, uint64_t &stubIndex)
447 {
448 FlatDBinderSession *flatSession = reinterpret_cast<FlatDBinderSession *>(sessionOffset);
449 /* force end true string length */
450 flatSession->deviceId[DEVICEID_LENGTH] = '\0';
451 flatSession->serviceName[SERVICENAME_LENGTH] = '\0';
452
453 ZLOGI(LOG_LABEL, "serviceName = %s, stubIndex = %" PRIu64 "", flatSession->serviceName, flatSession->stubIndex);
454 stubIndex = flatSession->stubIndex;
455 if (stubIndex == 0) {
456 ZLOGE(LOG_LABEL, "stubIndex err");
457 return nullptr;
458 }
459
460 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
461 if (current == nullptr) {
462 ZLOGE(LOG_LABEL, "current process skeleton is nullptr");
463 return nullptr;
464 }
465
466 std::shared_ptr<DBinderSessionObject> sessionObject =
467 current->QuerySessionByInfo(flatSession->serviceName, flatSession->deviceId);
468 if (sessionObject != nullptr) {
469 return sessionObject;
470 }
471 return std::make_shared<DBinderSessionObject>(nullptr, flatSession->serviceName, flatSession->deviceId);
472 }
473
FlattenObject(Parcel & parcel,const IRemoteObject * object) const474 bool DBinderDatabusInvoker::FlattenObject(Parcel &parcel, const IRemoteObject *object) const
475 {
476 return true;
477 }
478
UnflattenObject(Parcel & parcel)479 sptr<IRemoteObject> DBinderDatabusInvoker::UnflattenObject(Parcel &parcel)
480 {
481 return nullptr;
482 }
483
ReadFileDescriptor(Parcel & parcel)484 int DBinderDatabusInvoker::ReadFileDescriptor(Parcel &parcel)
485 {
486 return -1;
487 }
488
WriteFileDescriptor(Parcel & parcel,int fd,bool takeOwnership)489 bool DBinderDatabusInvoker::WriteFileDescriptor(Parcel &parcel, int fd, bool takeOwnership)
490 {
491 return true;
492 }
493
UpdateClientSession(uint32_t handle,std::shared_ptr<DBinderSessionObject> sessionObject)494 bool DBinderDatabusInvoker::UpdateClientSession(uint32_t handle, std::shared_ptr<DBinderSessionObject> sessionObject)
495 {
496 ZLOGI(LOG_LABEL, "update client session enter");
497
498 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
499 if (current == nullptr) {
500 ZLOGE(LOG_LABEL, "current process skeleton is nullptr");
501 return false;
502 }
503
504 std::shared_ptr<ISessionService> manager = ISessionService::GetInstance();
505 if (manager == nullptr) {
506 ZLOGE(LOG_LABEL, "fail to get softbus manager");
507 return false;
508 }
509
510 std::string sessionName = current->GetDatabusName();
511 if (sessionName.empty()) {
512 ZLOGE(LOG_LABEL, "fail to get session name");
513 return false;
514 }
515
516 std::shared_ptr<Session> session = manager->OpenSession(sessionName, sessionObject->GetServiceName(),
517 sessionObject->GetDeviceId(), std::string(""), Session::TYPE_BYTES);
518 if (session == nullptr) {
519 ZLOGE(LOG_LABEL, "get databus session fail");
520 return false;
521 }
522
523 sessionObject->SetBusSession(session);
524
525 if (!current->ProxyAttachDBinderSession(handle, sessionObject)) {
526 ZLOGE(LOG_LABEL, "fail to attach session");
527 if (current->QuerySessionByInfo(sessionObject->GetServiceName(),
528 sessionObject->GetDeviceId()) == nullptr) {
529 sessionObject->CloseDatabusSession();
530 }
531 return false;
532 }
533
534 return true;
535 }
536
OnDatabusSessionClosed(std::shared_ptr<Session> session)537 bool DBinderDatabusInvoker::OnDatabusSessionClosed(std::shared_ptr<Session> session)
538 {
539 if (session == nullptr) {
540 ZLOGE(LOG_LABEL, "databus session to be closed is nullptr");
541 return false;
542 }
543 /* means close socket */
544 ZLOGI(LOG_LABEL, "close databus session, own session name = %{public}s, peer session name = %{public}s",
545 session->GetMySessionName().c_str(), session->GetPeerSessionName().c_str());
546 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
547 if (current == nullptr) {
548 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
549 return false;
550 }
551
552 if (current->StubDetachDBinderSession(IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId()))) {
553 current->DetachStubRefInfo(session->GetPeerPid(), session->GetPeerDeviceId());
554 // No need to clear proxy objects
555 return true;
556 }
557
558 std::vector<uint32_t> proxy;
559 if (!current->QueryProxyBySessionHandle(IPCProcessSkeleton::ConvertChannelID2Int(session->GetChannelId()), proxy)) {
560 return false;
561 }
562
563 if (proxy.empty()) {
564 ZLOGE(LOG_LABEL, "proxy handle is empty");
565 return false;
566 }
567
568 for (auto it = proxy.begin(); it != proxy.end(); ++it) {
569 std::u16string descriptor = current->MakeHandleDescriptor(*it);
570 IRemoteObject *remoteObject = current->QueryObject(descriptor);
571 if (remoteObject != nullptr) {
572 (void)current->ProxyDetachDBinderSession(*it);
573 (void)current->DetachHandleToIndex(*it);
574 IPCObjectProxy *remoteProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject);
575 if (remoteProxy->IsSubscribeDeathNotice()) {
576 remoteProxy->SendObituary();
577 }
578 }
579 }
580
581 ZLOGI(LOG_LABEL, "closet socket sussess");
582 return true;
583 }
584
QueryHandleBySession(std::shared_ptr<DBinderSessionObject> session,uint64_t stubIndex)585 uint32_t DBinderDatabusInvoker::QueryHandleBySession(std::shared_ptr<DBinderSessionObject> session, uint64_t stubIndex)
586 {
587 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
588 if (current == nullptr) {
589 ZLOGE(LOG_LABEL, "current ipc process skeleton is nullptr");
590 return 0;
591 }
592
593 return current->QueryHandleByDatabusSession(session->GetServiceName(), session->GetDeviceId(), stubIndex);
594 }
595
GetSeqNum() const596 uint64_t DBinderDatabusInvoker::GetSeqNum() const
597 {
598 return seqNumber_;
599 }
600
SetSeqNum(uint64_t seq)601 void DBinderDatabusInvoker::SetSeqNum(uint64_t seq)
602 {
603 seqNumber_ = seq;
604 }
605
GetClientFd() const606 uint32_t DBinderDatabusInvoker::GetClientFd() const
607 {
608 return clientFd_;
609 }
610
SetClientFd(uint32_t fd)611 void DBinderDatabusInvoker::SetClientFd(uint32_t fd)
612 {
613 clientFd_ = fd;
614 }
615
GetCallerPid() const616 pid_t DBinderDatabusInvoker::GetCallerPid() const
617 {
618 return callerPid_;
619 }
620
SetStatus(uint32_t status)621 void DBinderDatabusInvoker::SetStatus(uint32_t status)
622 {
623 status_ = status;
624 }
625
GetStatus() const626 uint32_t DBinderDatabusInvoker::GetStatus() const
627 {
628 return status_;
629 }
630
SetCallerPid(pid_t pid)631 void DBinderDatabusInvoker::SetCallerPid(pid_t pid)
632 {
633 callerPid_ = pid;
634 }
635
GetCallerUid() const636 uid_t DBinderDatabusInvoker::GetCallerUid() const
637 {
638 return callerUid_;
639 }
640
SetCallerUid(pid_t uid)641 void DBinderDatabusInvoker::SetCallerUid(pid_t uid)
642 {
643 callerUid_ = uid;
644 }
645
GetCallerTokenID() const646 uint32_t DBinderDatabusInvoker::GetCallerTokenID() const
647 {
648 return callerTokenID_;
649 }
650
GetFirstTokenID() const651 uint32_t DBinderDatabusInvoker::GetFirstTokenID() const
652 {
653 return firstTokenID_;
654 }
655
SetCallerDeviceID(const std::string & deviceId)656 void DBinderDatabusInvoker::SetCallerDeviceID(const std::string &deviceId)
657 {
658 callerDeviceID_ = deviceId;
659 }
660
SetCallerTokenID(const uint32_t tokenId)661 void DBinderDatabusInvoker::SetCallerTokenID(const uint32_t tokenId)
662 {
663 callerTokenID_ = tokenId;
664 }
665
IsLocalCalling()666 bool DBinderDatabusInvoker::IsLocalCalling()
667 {
668 return false;
669 }
670
SetTokenId(const dbinder_transaction_data * tr,std::shared_ptr<DBinderSessionObject> sessionObject)671 bool DBinderDatabusInvoker::SetTokenId(const dbinder_transaction_data *tr,
672 std::shared_ptr<DBinderSessionObject> sessionObject)
673 {
674 if (sessionObject == nullptr) {
675 ZLOGE(LOG_LABEL, "sessionObject is null");
676 return false;
677 }
678 std::shared_ptr<FeatureSetData> feature = sessionObject->GetFeatureSet();
679 if (feature == nullptr) {
680 ZLOGE(LOG_LABEL, "feature is null");
681 return false;
682 }
683 if (IsATEnable(feature->featureSet) == true) {
684 uint32_t bufferUseSize = tr->sizeOfSelf - sizeof(struct dbinder_transaction_data) - GetFeatureSize();
685 uint32_t tokenId = GetTokenFromData((FeatureTransData *)(tr->buffer + bufferUseSize), GetFeatureSize());
686 SetCallerTokenID(tokenId);
687 }
688 return true;
689 }
690
CheckAndSetCallerInfo(uint32_t listenFd,uint64_t stubIndex)691 int DBinderDatabusInvoker::CheckAndSetCallerInfo(uint32_t listenFd, uint64_t stubIndex)
692 {
693 std::shared_ptr<DBinderSessionObject> sessionObject = QueryClientSessionObject(listenFd);
694 if (sessionObject == nullptr) {
695 ZLOGE(LOG_LABEL, "session is not exist for listenFd = %{public}u", listenFd);
696 return RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
697 }
698
699 std::shared_ptr<Session> session = sessionObject->GetBusSession();
700 if (session == nullptr) {
701 ZLOGE(LOG_LABEL, "get databus session fail");
702 return RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
703 }
704
705 int pid = session->GetPeerPid();
706 int uid = (int)(session->GetPeerUid());
707 std::string deviceId = session->GetPeerDeviceId();
708 if (uid < 0 || deviceId.length() > DEVICEID_LENGTH) {
709 ZLOGE(LOG_LABEL, "user id and device id error");
710 return RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
711 }
712
713 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
714 if (current == nullptr) {
715 ZLOGE(LOG_LABEL, "current process skeleton is nullptr");
716 return IPC_SKELETON_ERR;
717 }
718 if (current->QueryAppInfoToStubIndex((uint32_t)pid, (uint32_t)uid, deviceId, stubIndex) == false) {
719 ZLOGE(LOG_LABEL, "stub index is NOT belong to caller,serviceName = %{public}s, listenFd = %{public}u",
720 deviceId.c_str(), listenFd);
721 return RPC_DATABUS_INVOKER_INVALID_STUB_INDEX;
722 }
723 callerPid_ = pid;
724 callerUid_ = uid;
725 callerDeviceID_ = deviceId;
726 return ERR_NONE;
727 }
728
GetLocalDeviceID()729 std::string DBinderDatabusInvoker::GetLocalDeviceID()
730 {
731 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
732 if (current == nullptr) {
733 ZLOGE(LOG_LABEL, "current process skeleton is nullptr");
734 return "";
735 }
736
737 return current->GetLocalDeviceID();
738 }
739
GetCallerDeviceID() const740 std::string DBinderDatabusInvoker::GetCallerDeviceID() const
741 {
742 return callerDeviceID_;
743 }
744
MakeStubIndexByRemoteObject(IRemoteObject * stubObject)745 uint64_t DBinderDatabusInvoker::MakeStubIndexByRemoteObject(IRemoteObject *stubObject)
746 {
747 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
748 if (current == nullptr) {
749 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
750 return 0;
751 }
752
753 if (!current->IsContainsObject(stubObject)) {
754 ZLOGE(LOG_LABEL, "fail to find stub");
755 return 0;
756 }
757
758 uint64_t stubIndex = current->AddStubByIndex(stubObject);
759 if (!stubIndex) {
760 ZLOGE(LOG_LABEL, "fail to add stub");
761 return 0;
762 }
763 return stubIndex;
764 }
765
MakeDefaultServerSessionObject()766 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::MakeDefaultServerSessionObject()
767 {
768 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
769 if (current == nullptr) {
770 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
771 return nullptr;
772 }
773 std::string serviceName = current->GetDatabusName();
774 if (serviceName.empty()) {
775 ZLOGE(LOG_LABEL, "fail to get databus name");
776 return nullptr;
777 }
778 std::shared_ptr<DBinderSessionObject> connectSession =
779 std::make_shared<DBinderSessionObject>(nullptr, serviceName, current->GetLocalDeviceID());
780 if (connectSession == nullptr) {
781 ZLOGE(LOG_LABEL, "new server session fail!");
782 return nullptr;
783 }
784 return connectSession;
785 }
786
ConnectRemoteObject2Session(IRemoteObject * stubObject,uint64_t stubIndex,const std::shared_ptr<DBinderSessionObject> sessionObject)787 bool DBinderDatabusInvoker::ConnectRemoteObject2Session(IRemoteObject *stubObject, uint64_t stubIndex,
788 const std::shared_ptr<DBinderSessionObject> sessionObject)
789 {
790 if (sessionObject == nullptr) {
791 ZLOGE(LOG_LABEL, "session object is nullptr");
792 return false;
793 }
794 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
795 if (current == nullptr) {
796 ZLOGE(LOG_LABEL, "IPCProcessSkeleton is nullptr");
797 return false;
798 }
799 std::shared_ptr<Session> session = sessionObject->GetBusSession();
800 if (session == nullptr) {
801 ZLOGE(LOG_LABEL, "get databus session fail");
802 return false;
803 }
804
805 int peerPid = session->GetPeerPid();
806 int peerUid = (int)(session->GetPeerUid());
807 std::string deviceId = session->GetPeerDeviceId();
808 if (!current->AttachAppInfoToStubIndex((uint32_t)peerPid, (uint32_t)peerUid, deviceId, stubIndex)) {
809 ZLOGI(LOG_LABEL, "fail to attach appinfo to stub index, when proxy call we check appinfo");
810 // attempt attach again, if failed, do nothing
811 }
812
813 if (!current->AttachCommAuthInfo(stubObject, peerPid, peerUid, deviceId, sessionObject->GetFeatureSet())) {
814 ZLOGI(LOG_LABEL, "fail to attach comm auth info, maybe attached already");
815 // attempt attach again, if failed, do nothing
816 }
817
818 if (current->AttachStubSendRefInfo(stubObject, peerPid, deviceId)) {
819 if (!current->IncStubRefTimes(stubObject)) {
820 ZLOGE(LOG_LABEL, "Inc Stub RefTimes fail");
821 current->DetachCommAuthInfo(stubObject, peerPid, peerUid, deviceId);
822 current->DetachAppInfoToStubIndex((uint32_t)peerPid, (uint32_t)peerUid, deviceId, stubIndex);
823 return false;
824 }
825 stubObject->IncStrongRef(this);
826 }
827 return true;
828 }
829
CreateServerSessionObject(binder_uintptr_t binder,uint64_t & stubIndex,std::shared_ptr<DBinderSessionObject> sessionObject)830 std::shared_ptr<DBinderSessionObject> DBinderDatabusInvoker::CreateServerSessionObject(binder_uintptr_t binder,
831 uint64_t &stubIndex, std::shared_ptr<DBinderSessionObject> sessionObject)
832 {
833 IRemoteObject *stubObject = reinterpret_cast<IPCObjectStub *>(binder);
834 if (stubObject == nullptr) {
835 ZLOGE(LOG_LABEL, "binder is nullptr");
836 return nullptr;
837 }
838
839 stubIndex = MakeStubIndexByRemoteObject(stubObject);
840 if (stubIndex == 0) {
841 ZLOGE(LOG_LABEL, "fail to add stub");
842 return nullptr;
843 }
844 if (ConnectRemoteObject2Session(stubObject, stubIndex, sessionObject) != true) {
845 ZLOGE(LOG_LABEL, "fail to connect stub to session");
846 return nullptr;
847 }
848 return MakeDefaultServerSessionObject();
849 }
850
FlushCommands(IRemoteObject * object)851 int DBinderDatabusInvoker::FlushCommands(IRemoteObject *object)
852 {
853 if (object == nullptr || !object->IsProxyObject()) {
854 ZLOGE(LOG_LABEL, "proxy is invalid");
855 return RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
856 }
857
858 IPCObjectProxy *proxy = reinterpret_cast<IPCObjectProxy *>(object);
859
860 std::shared_ptr<DBinderSessionObject> session = QueryServerSessionObject(proxy->GetHandle());
861 if (session == nullptr) {
862 ZLOGE(LOG_LABEL, "session is nullptr");
863 return RPC_DATABUS_INVOKER_INVALID_DATA_ERR;
864 }
865
866 (void)OnSendMessage(session);
867 return ERR_NONE;
868 }
869
ResetCallingIdentity()870 std::string DBinderDatabusInvoker::ResetCallingIdentity()
871 {
872 std::string token = std::to_string(((static_cast<uint64_t>(callerUid_) << PID_LEN)
873 | static_cast<uint64_t>(callerPid_)));
874 std::string identity = callerDeviceID_ + token;
875 char buf[ACCESS_TOKEN_MAX_LEN + 1] = {0};
876 int ret = sprintf_s(buf, ACCESS_TOKEN_MAX_LEN + 1, "%010u", callerTokenID_);
877 if (ret < 0) {
878 ZLOGE(LOG_LABEL, "sprintf callerTokenID_ %u failed", callerTokenID_);
879 return "";
880 }
881 std::string accessToken(buf);
882 callerUid_ = (pid_t)getuid();
883 callerPid_ = getpid();
884 callerDeviceID_ = GetLocalDeviceID();
885 callerTokenID_ = RpcGetSelfTokenID();
886 return accessToken + identity;
887 }
888
SetCallingIdentity(std::string & identity)889 bool DBinderDatabusInvoker::SetCallingIdentity(std::string &identity)
890 {
891 if (identity.empty() || identity.length() <= DEVICEID_LENGTH) {
892 return false;
893 }
894
895 uint32_t tokenId = std::stoul(identity.substr(0, ACCESS_TOKEN_MAX_LEN));
896 std::string deviceId = identity.substr(ACCESS_TOKEN_MAX_LEN, DEVICEID_LENGTH);
897 uint64_t token = std::stoull(identity.substr(ACCESS_TOKEN_MAX_LEN + DEVICEID_LENGTH,
898 identity.length() - ACCESS_TOKEN_MAX_LEN - DEVICEID_LENGTH).c_str());
899
900 callerUid_ = static_cast<int>(token >> PID_LEN);
901 callerPid_ = static_cast<int>(token);
902 callerDeviceID_ = deviceId;
903 callerTokenID_ = tokenId;
904
905 return true;
906 }
907
TranslateProxy(uint32_t handle,uint32_t flag)908 int DBinderDatabusInvoker::TranslateProxy(uint32_t handle, uint32_t flag)
909 {
910 return -IPC_INVOKER_TRANSLATE_ERR;
911 }
912
TranslateStub(binder_uintptr_t cookie,binder_uintptr_t ptr,uint32_t flag,int cmd)913 int DBinderDatabusInvoker::TranslateStub(binder_uintptr_t cookie, binder_uintptr_t ptr, uint32_t flag, int cmd)
914 {
915 return -IPC_INVOKER_TRANSLATE_ERR;
916 }
917
HasRawDataPackage(const char * data,ssize_t len)918 uint32_t DBinderDatabusInvoker::HasRawDataPackage(const char *data, ssize_t len)
919 {
920 const dbinder_transaction_data *tr = reinterpret_cast<const dbinder_transaction_data *>(data);
921 if ((tr->magic == DBINDER_MAGICWORD) && (tr->cmd == BC_SEND_RAWDATA) &&
922 (tr->sizeOfSelf == static_cast<uint32_t>(len))) {
923 if (tr->sizeOfSelf > MAX_RAWDATA_SIZE) {
924 return MAX_RAWDATA_SIZE;
925 }
926 return tr->sizeOfSelf;
927 }
928 return 0;
929 }
930
HasCompletePackage(const char * data,uint32_t readCursor,ssize_t len)931 uint32_t DBinderDatabusInvoker::HasCompletePackage(const char *data, uint32_t readCursor, ssize_t len)
932 {
933 const dbinder_transaction_data *tr = reinterpret_cast<const dbinder_transaction_data *>(data + readCursor);
934 if ((tr->magic == DBINDER_MAGICWORD) &&
935 (tr->sizeOfSelf <= SOCKET_MAX_BUFF_SIZE + sizeof(dbinder_transaction_data)) &&
936 (readCursor + tr->sizeOfSelf <= static_cast<uint32_t>(len)) && CheckTransactionData(tr)) {
937 return tr->sizeOfSelf;
938 }
939 return 0;
940 }
941 } // namespace OHOS
942