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