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