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_service.h"
17 
18 #include <cinttypes>
19 #include "securec.h"
20 #include "string_ex.h"
21 #include "ipc_skeleton.h"
22 #include "ipc_thread_skeleton.h"
23 
24 #include "dbinder_error_code.h"
25 #include "dbinder_log.h"
26 #include "dbinder_remote_listener.h"
27 #include "dbinder_sa_death_recipient.h"
28 #include "dbinder_service_stub.h"
29 #include "ffrt.h"
30 #include "softbus_bus_center.h"
31 
32 namespace OHOS {
33 
34 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_DBINDER_SER, "DbinderService" };
35 
36 sptr<DBinderService> DBinderService::instance_ = nullptr;
37 bool DBinderService::mainThreadCreated_ = false;
38 std::mutex DBinderService::instanceMutex_;
39 std::shared_ptr<DBinderRemoteListener> DBinderService::remoteListener_ = nullptr;
40 constexpr unsigned int BINDER_MASK = 0xffff;
41 // DBinderServiceStub's reference count in a MakeRemoteBinder call.
42 constexpr int DBINDER_STUB_REF_COUNT = 2;
43 
DBinderService()44 DBinderService::DBinderService()
45 {
46     DBINDER_LOGI(LOG_LABEL, "create dbinder service");
47 }
48 
~DBinderService()49 DBinderService::~DBinderService()
50 {
51     StopRemoteListener();
52 
53     DBinderStubRegisted_.clear();
54     mapDBinderStubRegisters_.clear();
55     mapRemoteBinderObjects_.clear();
56     threadLockInfo_.clear();
57     proxyObject_.clear();
58     sessionObject_.clear();
59     noticeProxy_.clear();
60     deathRecipients_.clear();
61     loadSaReply_.clear();
62     dbinderCallback_ = nullptr;
63     DBINDER_LOGI(LOG_LABEL, "dbinder service died");
64 }
65 
GetLocalDeviceID()66 std::string DBinderService::GetLocalDeviceID()
67 {
68     std::string pkgName = "DBinderService";
69     std::string networkId;
70 
71     if (DBinderSoftbusClient::GetInstance().GetLocalNodeDeviceId(
72         pkgName.c_str(), networkId) != SOFTBUS_CLIENT_SUCCESS) {
73         DBINDER_LOGE(LOG_LABEL, "Get local node device id failed");
74     }
75 
76     return networkId;
77 }
78 
StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> & callbackImpl)79 bool DBinderService::StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl)
80 {
81     if (mainThreadCreated_) {
82         return ReStartRemoteListener();
83     }
84 
85     bool result = StartRemoteListener();
86     if (!result) {
87         return false;
88     }
89     mainThreadCreated_ = true;
90     dbinderCallback_ = callbackImpl;
91 
92     return true;
93 }
94 
StartRemoteListener()95 bool DBinderService::StartRemoteListener()
96 {
97     if (remoteListener_ != nullptr) {
98         DBINDER_LOGI(LOG_LABEL, "remote listener started");
99         return true;
100     }
101 
102     remoteListener_ = std::make_shared<DBinderRemoteListener>();
103     if (remoteListener_ == nullptr) {
104         DBINDER_LOGE(LOG_LABEL, "failed to create remote listener");
105         return false;
106     }
107 
108     if (remoteListener_->StartListener() != true) {
109         StopRemoteListener();
110         return false;
111     }
112 
113     DBINDER_LOGI(LOG_LABEL, "start remote listener ok");
114     return true;
115 }
116 
ReStartRemoteListener()117 bool DBinderService::ReStartRemoteListener()
118 {
119     if (remoteListener_ == nullptr) {
120         DBINDER_LOGE(LOG_LABEL, "restart remote listener got null");
121         return false;
122     }
123     if (remoteListener_->StartListener() != true) {
124         DBINDER_LOGE(LOG_LABEL, "restart dbinder server failed");
125         StopRemoteListener();
126         return false;
127     }
128     return true;
129 }
130 
StopRemoteListener()131 void DBinderService::StopRemoteListener()
132 {
133     if (remoteListener_ != nullptr) {
134         remoteListener_->StopListener();
135         remoteListener_ = nullptr;
136     }
137 }
138 
GetRemoteListener()139 std::shared_ptr<DBinderRemoteListener> DBinderService::GetRemoteListener()
140 {
141     if (remoteListener_ == nullptr && !StartRemoteListener()) {
142         return nullptr;
143     }
144     return remoteListener_;
145 }
146 
GetInstance()147 sptr<DBinderService> DBinderService::GetInstance()
148 {
149     if (instance_ == nullptr) {
150         std::lock_guard<std::mutex> lockGuard(instanceMutex_);
151         if (instance_ == nullptr) {
152             sptr<DBinderService> temp = new DBinderService();
153             instance_ = temp;
154         }
155     }
156     return instance_;
157 }
158 
GetSeqNumber()159 uint32_t DBinderService::GetSeqNumber()
160 {
161     std::lock_guard<std::mutex> lockGuard(instanceMutex_);
162     if (seqNumber_ == std::numeric_limits<uint32_t>::max()) {
163         seqNumber_ = 0;
164     }
165     seqNumber_++;
166     return seqNumber_;
167 }
168 
IsDeviceIdIllegal(const std::string & deviceID)169 bool DBinderService::IsDeviceIdIllegal(const std::string &deviceID)
170 {
171     if (deviceID.empty() || deviceID.length() > DEVICEID_LENGTH) {
172         return true;
173     }
174     return false;
175 }
176 
AddStubByTag(binder_uintptr_t stub)177 binder_uintptr_t DBinderService::AddStubByTag(binder_uintptr_t stub)
178 {
179     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
180 
181     // the same stub needs add stubNum to mapDBinderStubRegisters_, the previous corresponding stubNum will be returned.
182     for (auto iter = mapDBinderStubRegisters_.begin(); iter != mapDBinderStubRegisters_.end(); iter++) {
183         if (iter->second == stub) {
184             return iter->first;
185         }
186     }
187     binder_uintptr_t stubTag = stubTagNum_++;
188     auto result = mapDBinderStubRegisters_.insert(
189         std::pair<binder_uintptr_t, binder_uintptr_t>(stubTag, stub));
190     if (result.second) {
191         return stubTag;
192     } else {
193         return 0;
194     }
195 }
196 
QueryStubPtr(binder_uintptr_t stubTag)197 binder_uintptr_t DBinderService::QueryStubPtr(binder_uintptr_t stubTag)
198 {
199     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
200 
201     auto iter = mapDBinderStubRegisters_.find(stubTag);
202     if (iter != mapDBinderStubRegisters_.end()) {
203         return iter->second;
204     }
205 
206     return 0;
207 }
208 
CheckBinderObject(const sptr<DBinderServiceStub> & stub,binder_uintptr_t stubPtr)209 bool DBinderService::CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t stubPtr)
210 {
211     if (stub == nullptr) {
212         return false;
213     }
214 
215     if (reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()) == stubPtr) {
216         DBINDER_LOGI(LOG_LABEL, "found registered stub");
217         return true;
218     }
219     return false;
220 }
221 
HasDBinderStub(binder_uintptr_t stubPtr)222 bool DBinderService::HasDBinderStub(binder_uintptr_t stubPtr)
223 {
224     auto checkStub = [&stubPtr, this](const sptr<DBinderServiceStub> &stub) {
225         return CheckBinderObject(stub, stubPtr);
226     };
227 
228     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
229     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
230     if (it != DBinderStubRegisted_.end()) {
231         return true;
232     }
233     return false;
234 }
235 
IsSameStubObject(const sptr<DBinderServiceStub> & stub,const std::u16string & service,const std::string & device)236 bool DBinderService::IsSameStubObject(const sptr<DBinderServiceStub> &stub, const std::u16string &service,
237     const std::string &device)
238 {
239     if (stub == nullptr) {
240         return false;
241     }
242     const std::string serviceStr8 = Str16ToStr8(service);
243     if (IsSameTextStr(stub->GetServiceName(), serviceStr8) && IsSameTextStr(stub->GetDeviceID(), device)) {
244         DBINDER_LOGI(LOG_LABEL, "found registered service, name:%{public}s device:%{public}s",
245             serviceStr8.c_str(), DBinderService::ConvertToSecureDeviceID(device).c_str());
246         return true;
247     }
248     return false;
249 }
250 
FindDBinderStub(const std::u16string & service,const std::string & device)251 sptr<DBinderServiceStub> DBinderService::FindDBinderStub(const std::u16string &service, const std::string &device)
252 {
253     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
254         return IsSameStubObject(stub, service, device);
255     };
256 
257     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
258     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
259     if (it == DBinderStubRegisted_.end()) {
260         DBINDER_LOGW(LOG_LABEL, "not found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
261             DBinderService::ConvertToSecureDeviceID(device).c_str());
262         return nullptr;
263     }
264     DBINDER_LOGD(LOG_LABEL, "found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
265         DBinderService::ConvertToSecureDeviceID(device).c_str());
266     return (*it);
267 }
268 
DeleteDBinderStub(const std::u16string & service,const std::string & device)269 bool DBinderService::DeleteDBinderStub(const std::u16string &service, const std::string &device)
270 {
271     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
272         return IsSameStubObject(stub, service, device);
273     };
274 
275     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
276     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
277     if (it == DBinderStubRegisted_.end()) {
278         DBINDER_LOGW(LOG_LABEL, "not found, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
279             DBinderService::ConvertToSecureDeviceID(device).c_str());
280         return false;
281     }
282 
283     for (auto mapIt = mapDBinderStubRegisters_.begin(); mapIt != mapDBinderStubRegisters_.end();) {
284         if (mapIt->second == reinterpret_cast<binder_uintptr_t>((*it).GetRefPtr())) {
285             mapIt = mapDBinderStubRegisters_.erase(mapIt);
286         } else {
287             ++mapIt;
288         }
289     }
290     DBinderStubRegisted_.erase(it);
291     DBINDER_LOGI(LOG_LABEL, "succ, service:%{public}s device:%{public}s", Str16ToStr8(service).c_str(),
292         DBinderService::ConvertToSecureDeviceID(device).c_str());
293     return true;
294 }
295 
FindOrNewDBinderStub(const std::u16string & service,const std::string & device,binder_uintptr_t binderObject)296 sptr<DBinderServiceStub> DBinderService::FindOrNewDBinderStub(const std::u16string &service, const std::string &device,
297     binder_uintptr_t binderObject)
298 {
299     auto checkStub = [&service, &device, this](const sptr<DBinderServiceStub> &stub) {
300         return IsSameStubObject(stub, service, device);
301     };
302 
303     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
304     const std::string serviceStr8 = Str16ToStr8(service);
305     auto it = std::find_if(DBinderStubRegisted_.begin(), DBinderStubRegisted_.end(), checkStub);
306     if (it != DBinderStubRegisted_.end()) {
307         DBINDER_LOGD(LOG_LABEL, "found, service:%{public}s device:%{public}s", serviceStr8.c_str(),
308             DBinderService::ConvertToSecureDeviceID(device).c_str());
309         return (*it);
310     }
311 
312     sptr<DBinderServiceStub> dBinderServiceStub = new DBinderServiceStub(serviceStr8, device, binderObject);
313     DBinderStubRegisted_.push_back(dBinderServiceStub);
314     DBINDER_LOGD(LOG_LABEL, "create, service:%{public}s device:%{public}s", serviceStr8.c_str(),
315         DBinderService::ConvertToSecureDeviceID(device).c_str());
316     return dBinderServiceStub;
317 }
318 
MakeRemoteBinder(const std::u16string & serviceName,const std::string & deviceID,int32_t binderObject,uint32_t pid,uint32_t uid)319 sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &serviceName,
320     const std::string &deviceID, int32_t binderObject, uint32_t pid, uint32_t uid)
321 {
322     if (IsDeviceIdIllegal(deviceID) || serviceName.length() == 0) {
323         DBINDER_LOGE(LOG_LABEL, "para is wrong, device length:%{public}zu, service length:%{public}zu",
324             deviceID.length(), serviceName.length());
325         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
326         return nullptr;
327     }
328     const std::string serviceNameStr8 = Str16ToStr8(serviceName);
329     DBINDER_LOGI(LOG_LABEL, "service:%{public}s device:%{public}s", serviceNameStr8.c_str(),
330         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
331     DfxReportDeviceEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE,
332         DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), __FUNCTION__);
333 
334     sptr<DBinderServiceStub> dBinderServiceStub = FindOrNewDBinderStub(serviceName, deviceID,
335         static_cast<binder_uintptr_t>(binderObject));
336     if (dBinderServiceStub == nullptr) {
337         DBINDER_LOGE(LOG_LABEL, "FindOrNewDBinderStub fail, service:%{public}s", serviceNameStr8.c_str());
338         return nullptr;
339     }
340 
341     /* if not found dBinderServiceStub, should send msg to toDeviceID
342      * to invoker socket thread and add authentication info for create softbus session
343      */
344     int retryTimes = 0;
345     int32_t ret = -1;
346     do {
347         ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber(), pid, uid);
348         retryTimes++;
349     } while (ret == WAIT_REPLY_TIMEOUT && (retryTimes < RETRY_TIMES));
350 
351     if (ret != DBINDER_OK) {
352         DBINDER_LOGE(LOG_LABEL, "fail to invoke service, service:%{public}s device:%{public}s "
353             "DBinderServiceStub refcount:%{public}d",
354             serviceNameStr8.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str(),
355             dBinderServiceStub->GetSptrRefCount());
356         if (dBinderServiceStub->GetSptrRefCount() <= DBINDER_STUB_REF_COUNT) {
357             /* invoke fail, delete dbinder stub info */
358             (void)DeleteDBinderStub(serviceName, deviceID);
359             (void)DetachSessionObject(reinterpret_cast<binder_uintptr_t>(dBinderServiceStub.GetRefPtr()));
360         }
361         return nullptr;
362     }
363 
364     return dBinderServiceStub;
365 }
366 
CheckDeviceIDsInvalid(const std::string & deviceID,const std::string & localDevID)367 bool DBinderService::CheckDeviceIDsInvalid(const std::string &deviceID, const std::string &localDevID)
368 {
369     if (IsDeviceIdIllegal(deviceID) || IsDeviceIdIllegal(localDevID)) {
370         DBINDER_LOGE(LOG_LABEL, "wrong device id length, remote:%{public}zu local:%{public}zu",
371             deviceID.length(), localDevID.length());
372         return true;
373     }
374     return false;
375 }
376 
CopyDeviceIDsToMessage(std::shared_ptr<struct DHandleEntryTxRx> message,const std::string & localDevID,const std::string & deviceID)377 bool DBinderService::CopyDeviceIDsToMessage(std::shared_ptr<struct DHandleEntryTxRx> message,
378     const std::string &localDevID, const std::string &deviceID)
379 {
380     if (memcpy_s(message->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDevID.data(), localDevID.length()) != 0 ||
381         memcpy_s(message->deviceIdInfo.toDeviceId, DEVICEID_LENGTH, deviceID.data(), deviceID.length()) != 0) {
382         DBINDER_LOGE(LOG_LABEL, "fail to copy memory, service:%{public}" PRIu64" seq:%{public}u",
383             message->stubIndex, message->seqNumber);
384         return false;
385     }
386     message->deviceIdInfo.fromDeviceId[localDevID.length()] = '\0';
387     message->deviceIdInfo.toDeviceId[deviceID.length()] = '\0';
388     return true;
389 }
390 
CreateMessage(const sptr<DBinderServiceStub> & stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)391 std::shared_ptr<struct DHandleEntryTxRx> DBinderService::CreateMessage(const sptr<DBinderServiceStub> &stub,
392     uint32_t seqNumber, uint32_t pid, uint32_t uid)
393 {
394     auto message = std::make_shared<struct DHandleEntryTxRx>();
395     if (message == nullptr) {
396         DBINDER_LOGE(LOG_LABEL, "new DHandleEntryTxRx fail");
397         return nullptr;
398     }
399 
400     message->head.len = sizeof(DHandleEntryTxRx);
401     message->head.version = RPC_TOKENID_SUPPORT_VERSION;
402     message->dBinderCode = MESSAGE_AS_INVOKER;
403     message->transType = GetRemoteTransType();
404     message->fromPort = 0;
405     message->toPort = 0;
406     message->stubIndex = static_cast<uint64_t>(std::atoi(stub->GetServiceName().c_str()));
407     message->seqNumber = seqNumber;
408     message->binderObject = stub->GetBinderObject();
409     message->stub = AddStubByTag(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
410     message->deviceIdInfo.tokenId = IPCSkeleton::GetCallingTokenID();
411     message->pid = pid;
412     message->uid = uid;
413 
414     return message;
415 }
416 
SendEntryToRemote(const sptr<DBinderServiceStub> stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)417 bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid,
418     uint32_t uid)
419 {
420     const std::string deviceID = stub->GetDeviceID();
421     const std::string localDevID = GetLocalDeviceID();
422     if (CheckDeviceIDsInvalid(deviceID, localDevID)) {
423         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
424         return false;
425     }
426 
427     auto message = CreateMessage(stub, seqNumber, pid, uid);
428     if (message == nullptr) {
429         return false;
430     }
431 
432     if (!CopyDeviceIDsToMessage(message, localDevID, deviceID)) {
433         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
434         return false;
435     }
436 
437     DBINDER_LOGI(LOG_LABEL, "pid:%{public}u uid:%{public}u seq:%{public}u stub:%{public}llu"
438         " tokenId:%{public}u", message->pid, message->uid, message->seqNumber,
439         (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId);
440     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
441     if (remoteListener == nullptr) {
442         DBINDER_LOGE(LOG_LABEL, "remoteListener is null, service:%{public}" PRIu64 " seq:%{public}u",
443             message->stubIndex, message->seqNumber);
444         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_REMOTE_LISTENER_FAIL, __FUNCTION__);
445         return false;
446     }
447     bool result = remoteListener->SendDataToRemote(deviceID, message.get());
448     if (result != true) {
449         DBINDER_LOGE(LOG_LABEL, "SendDataToRemote failed, service:%{public}" PRIu64" seq:%{public}u",
450             message->stubIndex, message->seqNumber);
451         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_DATA_TO_REMOTE_FAIL, __FUNCTION__);
452         return false;
453     }
454     return true;
455 }
456 
InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub,uint32_t seqNumber,uint32_t pid,uint32_t uid)457 int32_t DBinderService::InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber,
458     uint32_t pid, uint32_t uid)
459 {
460     if (stub == nullptr) {
461         DBINDER_LOGE(LOG_LABEL, "stub is nullptr");
462         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
463         return STUB_INVALID;
464     }
465 
466     bool result = SendEntryToRemote(stub, seqNumber, pid, uid);
467     if (!result) {
468         DBINDER_LOGE(LOG_LABEL, "SendEntryToRemote fail, seq:%{public}u", seqNumber);
469         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_ENTRY_TO_REMOTE_FAIL, __FUNCTION__);
470         return SEND_MESSAGE_FAILED;
471     }
472 
473     /* pend to wait reply */
474     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = std::make_shared<struct ThreadLockInfo>();
475     result = AttachThreadLockInfo(seqNumber, stub->GetDeviceID(), threadLockInfo);
476     if (result != true) {
477         DBINDER_LOGE(LOG_LABEL, "AttachThreadLockInfo fail, seq:%{public}u", seqNumber);
478         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_THREADLOCK_FAIL, __FUNCTION__);
479         return MAKE_THREADLOCK_FAILED;
480     }
481 
482     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
483     if (threadLockInfo->condition.wait_for(lock, std::chrono::seconds(WAIT_FOR_REPLY_MAX_SEC),
484         [&threadLockInfo] { return threadLockInfo->ready; }) == false) {
485         DBINDER_LOGE(LOG_LABEL, "get remote data timeout or ssession is  closed, seq:%{public}u", seqNumber);
486         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_WAIT_REPLY_TIMEOUT, __FUNCTION__);
487         DetachThreadLockInfo(seqNumber);
488         threadLockInfo->ready = false;
489         return WAIT_REPLY_TIMEOUT;
490     }
491     /* if can not find session, means invoke failed or nothing in OnRemoteReplyMessage() */
492     auto session = QuerySessionObject(reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr()));
493     if (session == nullptr) {
494         DBINDER_LOGE(LOG_LABEL, "client find session is null, seq:%{public}u", seqNumber);
495         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_REPLY_SESSION_FAIL, __FUNCTION__);
496         return QUERY_REPLY_SESSION_FAILED;
497     }
498     return DBINDER_OK;
499 }
500 
CheckSystemAbilityId(int32_t systemAbilityId)501 bool DBinderService::CheckSystemAbilityId(int32_t systemAbilityId)
502 {
503     return systemAbilityId >= FIRST_SYS_ABILITY_ID && systemAbilityId <= LAST_SYS_ABILITY_ID;
504 }
505 
AllocFreeSocketPort()506 uint16_t DBinderService::AllocFreeSocketPort()
507 {
508     /* alloc port by system */
509     return 0;
510 }
511 
IsSameLoadSaItem(const std::string & srcNetworkId,int32_t systemAbilityId,std::shared_ptr<DHandleEntryTxRx> loadSaItem)512 bool DBinderService::IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId,
513     std::shared_ptr<DHandleEntryTxRx> loadSaItem)
514 {
515     if (static_cast<int32_t>(loadSaItem->stubIndex) == systemAbilityId &&
516         loadSaItem->deviceIdInfo.fromDeviceId == srcNetworkId) {
517         DBINDER_LOGI(LOG_LABEL, "match succeed");
518         return true;
519     }
520     return false;
521 }
522 
PopLoadSaItem(const std::string & srcNetworkId,int32_t systemAbilityId)523 std::shared_ptr<DHandleEntryTxRx> DBinderService::PopLoadSaItem(const std::string& srcNetworkId,
524     int32_t systemAbilityId)
525 {
526     auto checkSaItem = [srcNetworkId, systemAbilityId, this](std::shared_ptr<DHandleEntryTxRx> loadSaItem) {
527         return IsSameLoadSaItem(srcNetworkId, systemAbilityId, loadSaItem);
528     };
529 
530     std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
531     auto it = std::find_if(loadSaReply_.begin(), loadSaReply_.end(), checkSaItem);
532     if (it == loadSaReply_.end()) {
533         DBINDER_LOGI(LOG_LABEL, "no msg for saId:%{public}d, deviceId:%{public}s",
534             systemAbilityId, DBinderService::ConvertToSecureDeviceID(srcNetworkId).c_str());
535         return nullptr;
536     }
537     std::shared_ptr<DHandleEntryTxRx> replymsg = (*it);
538     it = loadSaReply_.erase(it);
539     return replymsg;
540 }
541 
LoadSystemAbilityComplete(const std::string & srcNetworkId,int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)542 void DBinderService::LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId,
543     const sptr<IRemoteObject>& remoteObject)
544 {
545     while (true) {
546         std::shared_ptr<struct DHandleEntryTxRx> replyMessage = PopLoadSaItem(srcNetworkId, systemAbilityId);
547         if (replyMessage == nullptr) {
548             break;
549         }
550         if (remoteObject == nullptr) {
551             SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage);
552             DBINDER_LOGE(LOG_LABEL, "GetSystemAbility from samgr error, saId:%{public}d", systemAbilityId);
553             continue;
554         }
555         binder_uintptr_t binderObject = replyMessage->binderObject;
556         IPCObjectProxy *saProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject.GetRefPtr());
557         if (QueryProxyObject(binderObject) == nullptr) {
558             /* When the stub object dies, you need to delete the corresponding busName information */
559             sptr<IRemoteObject::DeathRecipient> death(new DbinderSaDeathRecipient(binderObject));
560             if (!saProxy->AddDeathRecipient(death)) {
561                 SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_FOUND, replyMessage);
562                 DBINDER_LOGE(LOG_LABEL, "fail to add death recipient");
563                 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ADD_DEATH_RECIPIENT_FAIL, __FUNCTION__);
564                 continue;
565             }
566             if (!AttachProxyObject(remoteObject, binderObject)) {
567                 DBINDER_LOGW(LOG_LABEL, "attach proxy object is already existed");
568             }
569         }
570         std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId;
571         if (replyMessage->transType != IRemoteObject::DATABUS_TYPE) {
572             SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_INVOKE_FAILED, replyMessage);
573             DBINDER_LOGE(LOG_LABEL, "Invalid Message Type");
574             DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
575         } else {
576             // peer device rpc version == 1, not support thokenId and message->deviceIdInfo.tokenId is random value
577             uint32_t tokenId = (replyMessage->head.version < RPC_TOKENID_SUPPORT_VERSION) ?
578                 0 : replyMessage->deviceIdInfo.tokenId;
579             uint32_t result = OnRemoteInvokerDataBusMessage(saProxy, replyMessage, deviceId,
580                 replyMessage->pid, replyMessage->uid, tokenId);
581             if (result != 0) {
582                 SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, result, replyMessage);
583                 continue;
584             }
585             SendReplyMessageToRemote(MESSAGE_AS_REPLY, 0, replyMessage);
586         }
587     }
588     DBINDER_LOGI(LOG_LABEL, "LoadSystemAbility complete");
589 }
590 
SendReplyMessageToRemote(uint32_t dBinderCode,uint32_t reason,std::shared_ptr<struct DHandleEntryTxRx> replyMessage)591 void DBinderService::SendReplyMessageToRemote(uint32_t dBinderCode, uint32_t reason,
592     std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
593 {
594     std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
595     if (remoteListener == nullptr) {
596         DBINDER_LOGE(LOG_LABEL, "remoteListener is null");
597         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_REMOTE_LISTENER_FAIL, __FUNCTION__);
598         return;
599     }
600     replyMessage->dBinderCode = dBinderCode;
601     if (dBinderCode == MESSAGE_AS_REMOTE_ERROR) {
602         replyMessage->transType = reason; // reuse transType send back error code
603     }
604     if (!remoteListener->SendDataReply(replyMessage->deviceIdInfo.fromDeviceId, replyMessage.get())) {
605         DBINDER_LOGE(LOG_LABEL, "fail to send data from server DBS to client DBS");
606         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_SEND_DATA_REPLAY_FAIL, __FUNCTION__);
607     }
608 }
609 
CheckAndAmendSaId(std::shared_ptr<struct DHandleEntryTxRx> message)610 bool DBinderService::CheckAndAmendSaId(std::shared_ptr<struct DHandleEntryTxRx> message)
611 {
612     bool ret = true;
613     int32_t stubIndex = static_cast<int32_t>(message->stubIndex);
614     int32_t binderObject = static_cast<int32_t>(message->binderObject);
615     bool stubIndexVaild = CheckSystemAbilityId(stubIndex);
616     bool binderObjectVaild = CheckSystemAbilityId(binderObject);
617     if (stubIndexVaild && binderObjectVaild) {
618         if (stubIndex != binderObject) {
619             DBINDER_LOGW(LOG_LABEL, "stubIndex(%{public}d) != binderObject(%{public}d), update said:%{public}d",
620                 stubIndex, binderObject, stubIndex);
621             message->binderObject = message->stubIndex;
622         }
623     } else if (stubIndexVaild && !binderObjectVaild) {
624         DBINDER_LOGI(LOG_LABEL, "update said, replace binderObject:%{public}d with stubIndex:%{public}d",
625             binderObject, stubIndex);
626         message->binderObject = message->stubIndex;
627     } else if (!stubIndexVaild && binderObjectVaild) {
628         DBINDER_LOGI(LOG_LABEL, "update said, replace stubIndex:%{public}d with binderObject:%{public}d",
629             stubIndex, binderObject);
630         message->stubIndex = message->binderObject;
631     } else {
632         DBINDER_LOGE(LOG_LABEL, "invalid said, stubIndex:%{public}d binderObject:%{public}d",
633             stubIndex, binderObject);
634         ret = false;
635     }
636     return ret;
637 }
638 
OnRemoteInvokerMessage(std::shared_ptr<struct DHandleEntryTxRx> message)639 bool DBinderService::OnRemoteInvokerMessage(std::shared_ptr<struct DHandleEntryTxRx> message)
640 {
641     if (!CheckAndAmendSaId(message)) {
642         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_INVALID_SAID, __FUNCTION__);
643         SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SAID_INVALID_ERR, message);
644         return false;
645     }
646 
647     DBINDER_LOGI(LOG_LABEL,
648         "invoke business service:%{public}d seq:%{public}u stub:%{public}llu tokenId:%{public}u",
649         static_cast<int32_t>(message->stubIndex), message->seqNumber,
650         (message->stub & BINDER_MASK), message->deviceIdInfo.tokenId);
651     if (!dbinderCallback_->IsDistributedSystemAbility(message->binderObject)) {
652         DBINDER_LOGE(LOG_LABEL, "SA:%{public}llu not have distributed capability.", message->binderObject);
653         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_NOT_DISTEIBUTED_SA, __FUNCTION__);
654         SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_DISTRUBUTED_ERR, message);
655         return false;
656     }
657 
658     std::shared_ptr<DHandleEntryTxRx> replyMessage = message;
659     {
660         std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
661         loadSaReply_.push_back(replyMessage);
662     }
663     bool isSaAvailable = dbinderCallback_->LoadSystemAbilityFromRemote(replyMessage->deviceIdInfo.fromDeviceId,
664         static_cast<int32_t>(replyMessage->stubIndex));
665     if (!isSaAvailable) {
666         DBINDER_LOGE(LOG_LABEL, "fail to call the system ability:%{public}d",
667             static_cast<int32_t>(replyMessage->stubIndex));
668         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CALL_SYSTEM_ABILITY_FAIL, __FUNCTION__);
669         PopLoadSaItem(replyMessage->deviceIdInfo.fromDeviceId, static_cast<int32_t>(replyMessage->stubIndex));
670         SendReplyMessageToRemote(MESSAGE_AS_REMOTE_ERROR, SA_NOT_AVAILABLE, replyMessage);
671         return false;
672     }
673 
674     return true;
675 }
676 
GetDatabusNameByProxy(IPCObjectProxy * proxy)677 std::string DBinderService::GetDatabusNameByProxy(IPCObjectProxy *proxy)
678 {
679     if (proxy == nullptr) {
680         DBINDER_LOGE(LOG_LABEL, "proxy can not be null");
681         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
682         return "";
683     }
684     std::string sessionName = proxy->GetSessionName();
685     if (sessionName.empty()) {
686         DBINDER_LOGE(LOG_LABEL, "grand session name failed");
687         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GRT_SESSION_NAME_FAIL, __FUNCTION__);
688         return "";
689     }
690     DBINDER_LOGD(LOG_LABEL, "succ, handle:%{public}d sessionName:%{public}s",
691         proxy->GetHandle(), sessionName.c_str());
692     return sessionName;
693 }
694 
CreateDatabusName(int uid,int pid)695 std::string DBinderService::CreateDatabusName(int uid, int pid)
696 {
697     std::string sessionName = "DBinder" + std::to_string(uid) + std::string("_") + std::to_string(pid);
698     if (DBinderSoftbusClient::GetInstance().DBinderGrantPermission(uid, pid, sessionName) != ERR_NONE) {
699         DBINDER_LOGE(LOG_LABEL, "fail to Grant Permission softbus name");
700         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GRANT_PERMISSION_FAIL, __FUNCTION__);
701         return "";
702     }
703 
704     return sessionName;
705 }
706 
CheckDeviceIdIllegal(const std::string & remoteDeviceId)707 bool DBinderService::CheckDeviceIdIllegal(const std::string &remoteDeviceId)
708 {
709     if (IsDeviceIdIllegal(remoteDeviceId)) {
710         DBINDER_LOGE(LOG_LABEL, "remote device id is error");
711         return true;
712     }
713     return false;
714 }
715 
CheckSessionNameIsEmpty(const std::string & sessionName)716 bool DBinderService::CheckSessionNameIsEmpty(const std::string &sessionName)
717 {
718     if (sessionName.empty()) {
719         DBINDER_LOGE(LOG_LABEL, "get bus name fail");
720         return true;
721     }
722     return false;
723 }
724 
CheckInvokeListenThreadIllegal(IPCObjectProxy * proxy,MessageParcel & data,MessageParcel & reply)725 bool DBinderService::CheckInvokeListenThreadIllegal(IPCObjectProxy *proxy, MessageParcel &data, MessageParcel &reply)
726 {
727     int err = proxy->InvokeListenThread(data, reply);
728     if (err != ERR_NONE) {
729         DBINDER_LOGE(LOG_LABEL, "start service listen error:%{public}d handle:%{public}d", err, proxy->GetHandle());
730         return true;
731     }
732     return false;
733 }
734 
CheckStubIndexAndSessionNameIllegal(uint64_t stubIndex,const std::string & serverSessionName,const std::string & deviceId,IPCObjectProxy * proxy)735 bool DBinderService::CheckStubIndexAndSessionNameIllegal(uint64_t stubIndex, const std::string &serverSessionName,
736     const std::string &deviceId, IPCObjectProxy *proxy)
737 {
738     if (stubIndex == 0 || serverSessionName.empty() || serverSessionName.length() > SERVICENAME_LENGTH) {
739         DBINDER_LOGE(LOG_LABEL, "stubindex:%{public}" PRIu64 " or sessionName:%{public}s is invalid"
740             " handle:%{public}d deviceId:%{public}s", stubIndex, serverSessionName.c_str(), proxy->GetHandle(),
741             DBinderService::ConvertToSecureDeviceID(deviceId).c_str());
742         return true;
743     }
744     return false;
745 }
746 
SetReplyMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage,uint64_t stubIndex,const std::string & serverSessionName,uint32_t selfTokenId,IPCObjectProxy * proxy)747 bool DBinderService::SetReplyMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage, uint64_t stubIndex,
748     const std::string &serverSessionName, uint32_t selfTokenId, IPCObjectProxy *proxy)
749 {
750     replyMessage->dBinderCode = MESSAGE_AS_REPLY;
751     if (replyMessage->head.version >= RPC_TOKENID_SUPPORT_VERSION) {
752         replyMessage->dBinderCode = MESSAGE_AS_REPLY_TOKENID;
753     }
754     replyMessage->head.version = RPC_TOKENID_SUPPORT_VERSION;
755     replyMessage->stubIndex = stubIndex;
756     replyMessage->serviceNameLength = serverSessionName.length();
757     replyMessage->deviceIdInfo.tokenId = selfTokenId;
758     if (memcpy_s(replyMessage->serviceName, SERVICENAME_LENGTH, serverSessionName.data(),
759         replyMessage->serviceNameLength) != 0) {
760         DBINDER_LOGE(LOG_LABEL, "memcpy serviceName fail, handle:%{public}d", proxy->GetHandle());
761         return false;
762     }
763     replyMessage->serviceName[replyMessage->serviceNameLength] = '\0';
764     return true;
765 }
766 
OnRemoteInvokerDataBusMessage(IPCObjectProxy * proxy,std::shared_ptr<struct DHandleEntryTxRx> replyMessage,std::string & remoteDeviceId,int pid,int uid,uint32_t tokenId)767 uint32_t DBinderService::OnRemoteInvokerDataBusMessage(IPCObjectProxy *proxy,
768     std::shared_ptr<struct DHandleEntryTxRx> replyMessage,
769     std::string &remoteDeviceId, int pid, int uid, uint32_t tokenId)
770 {
771     if (CheckDeviceIdIllegal(remoteDeviceId)) {
772         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
773         return DEVICEID_INVALID;
774     }
775     std::string sessionName = GetDatabusNameByProxy(proxy);
776     if (CheckSessionNameIsEmpty(sessionName)) {
777         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_BUS_NAME_FAIL, __FUNCTION__);
778         return SESSION_NAME_NOT_FOUND;
779     }
780 
781     MessageParcel data;
782     MessageParcel reply;
783     if (!data.WriteUint16(IRemoteObject::DATABUS_TYPE) || !data.WriteString(GetLocalDeviceID()) ||
784         !data.WriteUint32(pid) || !data.WriteUint32(uid) || !data.WriteString(remoteDeviceId) ||
785         !data.WriteString(sessionName) || !data.WriteUint32(tokenId)) {
786         DBINDER_LOGE(LOG_LABEL, "write to parcel fail, handle:%{public}d", proxy->GetHandle());
787         DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(),
788             RADAR_WRITE_PARCEL_FAIL, __FUNCTION__);
789         return WRITE_PARCEL_FAILED;
790     }
791     if (CheckInvokeListenThreadIllegal(proxy, data, reply)) {
792         DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(),
793             RADAR_INVOKE_STUB_THREAD_FAIL, __FUNCTION__);
794         return INVOKE_STUB_THREAD_FAILED;
795     }
796 
797     uint64_t stubIndex = reply.ReadUint64();
798     std::string serverSessionName = reply.ReadString();
799     std::string deviceId = reply.ReadString();
800     uint32_t selfTokenId = reply.ReadUint32();
801     if (CheckStubIndexAndSessionNameIllegal(stubIndex, serverSessionName, deviceId, proxy)) {
802         DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(),
803             RADAR_SESSION_NAME_INVALID, __FUNCTION__);
804         return SESSION_NAME_INVALID;
805     }
806     if (!SetReplyMessage(replyMessage, stubIndex, serverSessionName, selfTokenId, proxy)) {
807         DfxReportFailHandleEvent(DbinderErrorCode::RPC_DRIVER, proxy->GetHandle(), RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
808         return SESSION_NAME_INVALID;
809     }
810     return 0;
811 }
812 
GetRegisterService(binder_uintptr_t binderObject)813 std::u16string DBinderService::GetRegisterService(binder_uintptr_t binderObject)
814 {
815     std::shared_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
816     for (auto it = mapRemoteBinderObjects_.begin(); it != mapRemoteBinderObjects_.end(); it++) {
817         if (it->second == binderObject) {
818             DBINDER_LOGI(LOG_LABEL, "get service:%{public}s", Str16ToStr8(it->first).c_str());
819             return it->first;
820         }
821     }
822     return std::u16string();
823 }
824 
RegisterRemoteProxy(std::u16string serviceName,sptr<IRemoteObject> binderObject)825 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject)
826 {
827     if (serviceName.length() == 0 || binderObject == nullptr) {
828         DBINDER_LOGE(LOG_LABEL, "serviceName length:%{public}zu", serviceName.length());
829         return false;
830     }
831 
832     DBINDER_LOGI(LOG_LABEL, "service name:%{public}s", Str16ToStr8(serviceName).c_str());
833     binder_uintptr_t binder = (binder_uintptr_t)binderObject.GetRefPtr();
834     return RegisterRemoteProxyInner(serviceName, binder);
835 }
836 
RegisterRemoteProxy(std::u16string serviceName,int32_t systemAbilityId)837 bool DBinderService::RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId)
838 {
839     if (serviceName.length() == 0 || systemAbilityId <= 0) {
840         DBINDER_LOGE(LOG_LABEL, "serviceName length:%{public}zu", serviceName.length());
841         return false;
842     }
843     DBINDER_LOGI(LOG_LABEL, "service name:%{public}s saId:%{public}d",
844         Str16ToStr8(serviceName).c_str(), systemAbilityId);
845     binder_uintptr_t binder = (binder_uintptr_t)systemAbilityId;
846     return RegisterRemoteProxyInner(serviceName, binder);
847 }
848 
RegisterRemoteProxyInner(std::u16string serviceName,binder_uintptr_t binder)849 bool DBinderService::RegisterRemoteProxyInner(std::u16string serviceName, binder_uintptr_t binder)
850 {
851     std::unique_lock<std::shared_mutex> lockGuard(remoteBinderMutex_);
852     // clear historical remnants, Don't care if it succeeds
853     (void)mapRemoteBinderObjects_.erase(serviceName);
854     auto result = mapRemoteBinderObjects_.insert(std::pair<std::u16string, binder_uintptr_t>(serviceName, binder));
855     return result.second;
856 }
857 
AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)858 void DBinderService::AddAsynMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)
859 {
860     auto task = [this, message] { this->OnRemoteMessageTask(message); };
861     ffrt::submit(task);
862 }
863 
OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)864 bool DBinderService::OnRemoteMessageTask(std::shared_ptr<struct DHandleEntryTxRx> message)
865 {
866     if (message == nullptr) {
867         DBINDER_LOGE(LOG_LABEL, "message is null");
868         return false;
869     }
870 
871     bool result = false;
872     switch (message->dBinderCode) {
873         case MESSAGE_AS_INVOKER: {
874             result = OnRemoteInvokerMessage(message);
875             break;
876         }
877         case MESSAGE_AS_REPLY:
878         case MESSAGE_AS_REPLY_TOKENID: {
879             result = OnRemoteReplyMessage(message);
880             break;
881         }
882         case MESSAGE_AS_REMOTE_ERROR: {
883             result = OnRemoteErrorMessage(message);
884             break;
885         }
886         default: {
887             DBINDER_LOGE(LOG_LABEL, "DbinderCode:%{public}u is not support", message->dBinderCode);
888             result = false;
889             break;
890         }
891     }
892     return result;
893 }
894 
ProcessOnSessionClosed(const std::string & networkId)895 bool DBinderService::ProcessOnSessionClosed(const std::string &networkId)
896 {
897     std::lock_guard<std::mutex> lock(threadLockMutex_);
898     for (auto it = threadLockInfo_.begin(); it != threadLockInfo_.end();) {
899         if (it->second->networkId != networkId) {
900             it++;
901             continue;
902         }
903         std::unique_lock<std::mutex> lock(it->second->mutex);
904         it->second->ready = false;
905         it->second->condition.notify_all();
906         it = threadLockInfo_.erase(it);
907     }
908     return true;
909 }
910 
OnRemoteErrorMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)911 bool DBinderService::OnRemoteErrorMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
912 {
913     DfxReportEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE, __FUNCTION__);
914     DBINDER_LOGI(LOG_LABEL, "invoke remote stubIndex:%{public}d fail, error:%{public}u seq:%{public}u",
915         static_cast<int32_t>(replyMessage->stubIndex), replyMessage->transType, replyMessage->seqNumber);
916     WakeupThreadByStub(replyMessage->seqNumber);
917     DetachThreadLockInfo(replyMessage->seqNumber);
918     return true;
919 }
920 
OnRemoteReplyMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)921 bool DBinderService::OnRemoteReplyMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
922 {
923     DBINDER_LOGI(LOG_LABEL, "invoker remote stubIndex:%{public}d succ, seq:%{public}u stub:%{public}llu "
924         "tokenId:%{public}u dBinderCode:%{public}u", static_cast<int32_t>(replyMessage->stubIndex),
925         replyMessage->seqNumber, (replyMessage->stub & BINDER_MASK), replyMessage->deviceIdInfo.tokenId,
926         replyMessage->dBinderCode);
927     MakeSessionByReplyMessage(replyMessage);
928     WakeupThreadByStub(replyMessage->seqNumber);
929     DetachThreadLockInfo(replyMessage->seqNumber);
930     return true;
931 }
932 
IsSameSession(std::shared_ptr<struct SessionInfo> oldSession,std::shared_ptr<struct SessionInfo> newSession)933 bool DBinderService::IsSameSession(std::shared_ptr<struct SessionInfo> oldSession,
934     std::shared_ptr<struct SessionInfo> newSession)
935 {
936     if ((oldSession->stubIndex != newSession->stubIndex) || (oldSession->toPort != newSession->toPort)
937         || (oldSession->fromPort != newSession->fromPort) || (oldSession->type != newSession->type)
938         || (oldSession->serviceName != newSession->serviceName)) {
939         return false;
940     }
941     if (strncmp(oldSession->deviceIdInfo.fromDeviceId, newSession->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH) != 0
942         || strncmp(oldSession->deviceIdInfo.toDeviceId, newSession->deviceIdInfo.toDeviceId, DEVICEID_LENGTH) != 0) {
943         return false;
944     }
945 
946     return true;
947 }
948 
IsInvalidStub(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)949 bool DBinderService::IsInvalidStub(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
950 {
951     if (HasDBinderStub(QueryStubPtr(replyMessage->stub)) == false) {
952         DBINDER_LOGE(LOG_LABEL, "invalid stub object");
953         return true;
954     }
955     return false;
956 }
957 
CopyDeviceIdInfo(std::shared_ptr<struct SessionInfo> & session,std::shared_ptr<struct DHandleEntryTxRx> replyMessage)958 bool DBinderService::CopyDeviceIdInfo(std::shared_ptr<struct SessionInfo> &session,
959     std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
960 {
961     if (memcpy_s(&session->deviceIdInfo, sizeof(struct DeviceIdInfo), &replyMessage->deviceIdInfo,
962         sizeof(struct DeviceIdInfo)) != 0) {
963         DBINDER_LOGE(LOG_LABEL, "fail to copy memory");
964         return false;
965     }
966     return true;
967 }
968 
InitializeSession(std::shared_ptr<struct SessionInfo> & session,std::shared_ptr<struct DHandleEntryTxRx> replyMessage)969 void DBinderService::InitializeSession(std::shared_ptr<struct SessionInfo> &session,
970     std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
971 {
972     session->seqNumber   = replyMessage->seqNumber;
973     session->socketFd    = 0;
974     session->stubIndex   = replyMessage->stubIndex;
975     session->toPort      = replyMessage->toPort;
976     session->fromPort    = replyMessage->fromPort;
977     session->type        = replyMessage->transType;
978     session->serviceName = replyMessage->serviceName;
979 }
980 
MakeSessionByReplyMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)981 void DBinderService::MakeSessionByReplyMessage(std::shared_ptr<struct DHandleEntryTxRx> replyMessage)
982 {
983     if (IsInvalidStub(replyMessage)) {
984         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_STUB_INVALID, __FUNCTION__);
985         return;
986     }
987 
988     std::shared_ptr<struct SessionInfo> session = std::make_shared<struct SessionInfo>();
989     if (session == nullptr) {
990         DBINDER_LOGE(LOG_LABEL, "new SessionInfo fail");
991         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_IPC_NEW_SESSION_FAIL, __FUNCTION__);
992         return;
993     }
994 
995     if (!CopyDeviceIdInfo(session, replyMessage)) {
996         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
997         return;
998     }
999     // remote device NOT support tokenId, clear random value
1000     if (replyMessage->dBinderCode == MESSAGE_AS_REPLY) {
1001         session->deviceIdInfo.tokenId = 0;
1002     }
1003     DBINDER_LOGI(LOG_LABEL, "stubIndex:%{public}d tokenId:%{public}u",
1004         static_cast<int32_t>(replyMessage->stubIndex), session->deviceIdInfo.tokenId);
1005     InitializeSession(session, replyMessage);
1006 
1007     if (session->stubIndex == 0) {
1008         DBINDER_LOGE(LOG_LABEL, "get stubIndex == 0, it is invalid");
1009         return;
1010     }
1011     // check whether need to update session
1012     std::shared_ptr<struct SessionInfo> oldSession = QuerySessionObject(QueryStubPtr(replyMessage->stub));
1013     if (oldSession != nullptr) {
1014         if (IsSameSession(oldSession, session) == true) {
1015             DBINDER_LOGI(LOG_LABEL, "invoker remote session already, do nothing");
1016             return;
1017         }
1018         // ignore seqNumber overflow here, greater seqNumber means later request
1019         if (oldSession->seqNumber < session->seqNumber) {
1020             // remote old session
1021             if (!DetachSessionObject(QueryStubPtr(replyMessage->stub))) {
1022                 DBINDER_LOGE(LOG_LABEL, "failed to detach session object");
1023                 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_DETACH_SESSION_FAIL, __FUNCTION__);
1024             }
1025         } else {
1026             // do nothing, use old session, discard session got this time
1027             // in this case, old session is requested later, but it comes back earlier
1028         }
1029     }
1030 
1031     if (!AttachSessionObject(session, QueryStubPtr(replyMessage->stub))) {
1032         DBINDER_LOGE(LOG_LABEL, "attach SessionInfo fail");
1033         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_SESSION_FAIL, __FUNCTION__);
1034         return;
1035     }
1036 }
1037 
WakeupThreadByStub(uint32_t seqNumber)1038 void DBinderService::WakeupThreadByStub(uint32_t seqNumber)
1039 {
1040     std::shared_ptr<struct ThreadLockInfo> threadLockInfo = QueryThreadLockInfo(seqNumber);
1041     if (threadLockInfo == nullptr) {
1042         DBINDER_LOGE(LOG_LABEL, "threadLockInfo is not exist");
1043         return;
1044     }
1045     /* Wake up the client processing thread */
1046     std::unique_lock<std::mutex> lock(threadLockInfo->mutex);
1047     threadLockInfo->ready = true;
1048     threadLockInfo->condition.notify_all();
1049 }
1050 
DetachThreadLockInfo(uint32_t seqNumber)1051 void DBinderService::DetachThreadLockInfo(uint32_t seqNumber)
1052 {
1053     std::lock_guard<std::mutex> lock(threadLockMutex_);
1054     threadLockInfo_.erase(seqNumber);
1055 }
1056 
AttachThreadLockInfo(uint32_t seqNumber,const std::string & networkId,std::shared_ptr<struct ThreadLockInfo> object)1057 bool DBinderService::AttachThreadLockInfo(uint32_t seqNumber, const std::string &networkId,
1058     std::shared_ptr<struct ThreadLockInfo> object)
1059 {
1060     std::lock_guard<std::mutex> lock(threadLockMutex_);
1061     object->networkId = networkId;
1062     auto result =
1063         threadLockInfo_.insert(std::pair<uint32_t, std::shared_ptr<struct ThreadLockInfo>>(seqNumber, object));
1064     return result.second;
1065 }
1066 
QueryThreadLockInfo(uint32_t seqNumber)1067 std::shared_ptr<struct ThreadLockInfo> DBinderService::QueryThreadLockInfo(uint32_t seqNumber)
1068 {
1069     std::lock_guard<std::mutex> lock(threadLockMutex_);
1070 
1071     auto it = threadLockInfo_.find(seqNumber);
1072     if (it != threadLockInfo_.end()) {
1073         return it->second;
1074     }
1075     return nullptr;
1076 }
1077 
DetachProxyObject(binder_uintptr_t binderObject)1078 bool DBinderService::DetachProxyObject(binder_uintptr_t binderObject)
1079 {
1080     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
1081 
1082     return (proxyObject_.erase(binderObject) > 0);
1083 }
1084 
AttachProxyObject(sptr<IRemoteObject> object,binder_uintptr_t binderObject)1085 bool DBinderService::AttachProxyObject(sptr<IRemoteObject> object, binder_uintptr_t binderObject)
1086 {
1087     std::unique_lock<std::shared_mutex> lock(proxyMutex_);
1088 
1089     auto result = proxyObject_.insert(std::pair<int, sptr<IRemoteObject>>(binderObject, object));
1090     return result.second;
1091 }
1092 
QueryProxyObject(binder_uintptr_t binderObject)1093 sptr<IRemoteObject> DBinderService::QueryProxyObject(binder_uintptr_t binderObject)
1094 {
1095     std::shared_lock<std::shared_mutex> lock(proxyMutex_);
1096 
1097     auto it = proxyObject_.find(binderObject);
1098     if (it != proxyObject_.end()) {
1099         return it->second;
1100     }
1101     return nullptr;
1102 }
1103 
DetachSessionObject(binder_uintptr_t stub)1104 bool DBinderService::DetachSessionObject(binder_uintptr_t stub)
1105 {
1106     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
1107     return (sessionObject_.erase(stub) > 0);
1108 }
1109 
AttachSessionObject(std::shared_ptr<struct SessionInfo> object,binder_uintptr_t stub)1110 bool DBinderService::AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub)
1111 {
1112     std::unique_lock<std::shared_mutex> lock(sessionMutex_);
1113 
1114     auto ret = sessionObject_.insert(std::pair<binder_uintptr_t, std::shared_ptr<struct SessionInfo>>(stub, object));
1115     return ret.second;
1116 }
1117 
QuerySessionObject(binder_uintptr_t stub)1118 std::shared_ptr<struct SessionInfo> DBinderService::QuerySessionObject(binder_uintptr_t stub)
1119 {
1120     std::shared_lock<std::shared_mutex> lock(sessionMutex_);
1121 
1122     auto it = sessionObject_.find(stub);
1123     if (it != sessionObject_.end()) {
1124         return it->second;
1125     }
1126     return nullptr;
1127 }
1128 
DetachDeathRecipient(sptr<IRemoteObject> object)1129 bool DBinderService::DetachDeathRecipient(sptr<IRemoteObject> object)
1130 {
1131     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
1132 
1133     return (deathRecipients_.erase(object) > 0);
1134 }
1135 
AttachDeathRecipient(sptr<IRemoteObject> object,sptr<IRemoteObject::DeathRecipient> deathRecipient)1136 bool DBinderService::AttachDeathRecipient(sptr<IRemoteObject> object,
1137     sptr<IRemoteObject::DeathRecipient> deathRecipient)
1138 {
1139     std::unique_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
1140 
1141     auto ret = deathRecipients_.insert(
1142         std::pair<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>>(object, deathRecipient));
1143 
1144     return ret.second;
1145 }
1146 
QueryDeathRecipient(sptr<IRemoteObject> object)1147 sptr<IRemoteObject::DeathRecipient> DBinderService::QueryDeathRecipient(sptr<IRemoteObject> object)
1148 {
1149     std::shared_lock<std::shared_mutex> lockGuard(deathRecipientMutex_);
1150 
1151     auto it = deathRecipients_.find(object);
1152     if (it != deathRecipients_.end()) {
1153         return it->second;
1154     }
1155 
1156     return nullptr;
1157 }
1158 
1159 
DetachCallbackProxy(sptr<IRemoteObject> object)1160 bool DBinderService::DetachCallbackProxy(sptr<IRemoteObject> object)
1161 {
1162     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1163 
1164     return (noticeProxy_.erase(object) > 0);
1165 }
1166 
AttachCallbackProxy(sptr<IRemoteObject> object,DBinderServiceStub * dbStub)1167 bool DBinderService::AttachCallbackProxy(sptr<IRemoteObject> object, DBinderServiceStub *dbStub)
1168 {
1169     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1170 
1171     auto result = noticeProxy_.insert(std::pair<sptr<IRemoteObject>, DBinderServiceStub *>(object, dbStub));
1172 
1173     return result.second;
1174 }
1175 
NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)1176 bool DBinderService::NoticeCallbackProxy(sptr<DBinderServiceStub> dbStub)
1177 {
1178     DBINDER_LOGI(LOG_LABEL, "service:%{public}s devicId:%{public}s",
1179         dbStub->GetServiceName().c_str(), DBinderService::ConvertToSecureDeviceID(dbStub->GetDeviceID()).c_str());
1180     bool status = true;
1181     const binder_uintptr_t binderObject = reinterpret_cast<binder_uintptr_t>(dbStub.GetRefPtr());
1182     if (!DetachSessionObject(binderObject)) {
1183         DBINDER_LOGE(LOG_LABEL, "fail to detach session object");
1184         status = false;
1185     }
1186 
1187     if (!DeleteDBinderStub(Str8ToStr16(dbStub->GetServiceName()), dbStub->GetDeviceID())) {
1188         DBINDER_LOGE(LOG_LABEL, "fail to delete DBinder stub");
1189         status = false;
1190     }
1191 
1192     ProcessCallbackProxy(dbStub);
1193 
1194     return status;
1195 }
1196 
ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)1197 void DBinderService::ProcessCallbackProxy(sptr<DBinderServiceStub> dbStub)
1198 {
1199     std::lock_guard<std::mutex> lockGuard(callbackProxyMutex_);
1200     for (auto it = noticeProxy_.begin(); it != noticeProxy_.end();) {
1201         if (it->second == dbStub.GetRefPtr()) {
1202             IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>((it->first).GetRefPtr());
1203             int status = callbackProxy->NoticeServiceDie();
1204             if (status != ERR_NONE) {
1205                 DBINDER_LOGE(LOG_LABEL, "fail to notice service:%{public}s die, handle:%{public}d",
1206                     dbStub->GetServiceName().c_str(), callbackProxy->GetHandle());
1207                 // do nothing, Continue to clear subsequent data
1208             }
1209 
1210             sptr<IRemoteObject::DeathRecipient> death = QueryDeathRecipient((it->first));
1211             if (death != nullptr) {
1212                 // Continue to clear subsequent data
1213                 callbackProxy->RemoveDeathRecipient(death);
1214             }
1215 
1216             if (!DetachDeathRecipient((it->first))) {
1217                 DBINDER_LOGE(LOG_LABEL, "detaching death recipient is failed, service:%{public}s handle:%{public}d",
1218                     dbStub->GetServiceName().c_str(), callbackProxy->GetHandle());
1219             }
1220 
1221             it = noticeProxy_.erase(it);
1222         } else {
1223             it++;
1224         }
1225     }
1226 }
1227 
NoticeServiceDieInner(const std::u16string & serviceName,const std::string & deviceID)1228 int32_t DBinderService::NoticeServiceDieInner(const std::u16string &serviceName, const std::string &deviceID)
1229 {
1230     if (serviceName.empty() || IsDeviceIdIllegal(deviceID)) {
1231         DBINDER_LOGE(LOG_LABEL, "service name length:%{public}zu, deviceID length:%{public}zu",
1232             serviceName.length(), deviceID.length());
1233         return DBINDER_SERVICE_INVALID_DATA_ERR;
1234     }
1235 
1236     DBINDER_LOGI(LOG_LABEL, "service:%{public}s deviceId:%{public}s",
1237         Str16ToStr8(serviceName).c_str(), DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
1238     sptr<DBinderServiceStub> dbStub = FindDBinderStub(serviceName, deviceID);
1239     if (dbStub == nullptr) {
1240         DBINDER_LOGE(LOG_LABEL, "find null stub, do not need notice death");
1241         return ERR_NONE;
1242     }
1243 
1244     if (!NoticeCallbackProxy(dbStub)) {
1245         DBINDER_LOGE(LOG_LABEL, "find null proxy");
1246         return DBINDER_SERVICE_NOTICE_DIE_ERR;
1247     }
1248     return ERR_NONE;
1249 }
1250 
NoticeServiceDie(const std::u16string & serviceName,const std::string & deviceID)1251 int32_t DBinderService::NoticeServiceDie(const std::u16string &serviceName, const std::string &deviceID)
1252 {
1253     if (IsDeviceIdIllegal(deviceID)) {
1254         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
1255     } else {
1256         DfxReportDeviceEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE,
1257             DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), __FUNCTION__);
1258     }
1259     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
1260     return NoticeServiceDieInner(serviceName, deviceID);
1261 }
1262 
NoticeDeviceDie(const std::string & deviceID)1263 int32_t DBinderService::NoticeDeviceDie(const std::string &deviceID)
1264 {
1265     if (IsDeviceIdIllegal(deviceID)) {
1266         DBINDER_LOGE(LOG_LABEL, "deviceID length:%{public}zu", deviceID.length());
1267         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
1268         return DBINDER_SERVICE_INVALID_DATA_ERR;
1269     }
1270     DBINDER_LOGI(LOG_LABEL, "remote device:%{public}s is dead",
1271         DBinderService::ConvertToSecureDeviceID(deviceID).c_str());
1272     DfxReportDeviceEvent(DbinderErrorCode::RPC_DRIVER, DbinderErrorCode::IPC_RESULT_IDLE,
1273         DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), __FUNCTION__);
1274 
1275     if (remoteListener_ == nullptr) {
1276         DBINDER_LOGE(LOG_LABEL, "remote listener is null");
1277         return DBINDER_SERVICE_NOTICE_DIE_ERR;
1278     }
1279 
1280     if (!remoteListener_->ShutdownSocket(deviceID)) {
1281         DBINDER_LOGE(LOG_LABEL, "Shutdown fail");
1282         // do nothing
1283     }
1284 
1285     std::list<std::u16string> serviceNames = FindServicesByDeviceID(deviceID);
1286     if (serviceNames.empty()) {
1287         DBINDER_LOGE(LOG_LABEL, "the device does not have any registered service");
1288         return ERR_NONE;
1289     }
1290 
1291     int status = ERR_NONE;
1292     std::lock_guard<std::mutex> lockGuard(deathNotificationMutex_);
1293 
1294     for (auto it = serviceNames.begin(); it != serviceNames.end(); it++) {
1295         status += NoticeServiceDieInner((*it), deviceID);
1296     }
1297 
1298     return status;
1299 }
1300 
FindServicesByDeviceID(const std::string & deviceID)1301 std::list<std::u16string> DBinderService::FindServicesByDeviceID(const std::string &deviceID)
1302 {
1303     std::lock_guard<std::mutex> lockGuard(handleEntryMutex_);
1304     std::list<std::u16string> serviceNames;
1305     for (auto it = DBinderStubRegisted_.begin(); it != DBinderStubRegisted_.end(); it++) {
1306         if ((*it)->GetDeviceID() == deviceID) {
1307             serviceNames.push_back(Str8ToStr16((*it)->GetServiceName()));
1308         }
1309     }
1310 
1311     DBINDER_LOGI(LOG_LABEL, "deviceId:%{public}s, service size:%{public}zu",
1312         DBinderService::ConvertToSecureDeviceID(deviceID).c_str(), serviceNames.size());
1313     return serviceNames;
1314 }
1315 
GetRemoteTransType()1316 uint32_t DBinderService::GetRemoteTransType()
1317 {
1318     return IRemoteObject::DATABUS_TYPE;
1319 }
1320 
ConvertToSecureDeviceID(const std::string & str)1321 std::string DBinderService::ConvertToSecureDeviceID(const std::string &str)
1322 {
1323     size_t len = str.size();
1324     if (len <= ENCRYPT_LENGTH) {
1325         return "****";
1326     }
1327     return str.substr(0, ENCRYPT_LENGTH) + "****" + str.substr(len - ENCRYPT_LENGTH);
1328 }
1329 } // namespace OHOS
1330