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