• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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