• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dbinder_service_stub.h"
17 
18 #include <cinttypes>
19 #include "securec.h"
20 #include "sys_binder.h"
21 #include "string_ex.h"
22 
23 #include "dbinder_death_recipient.h"
24 #include "dbinder_error_code.h"
25 #include "dbinder_log.h"
26 #include "dbinder_service.h"
27 #include "ipc_skeleton.h"
28 #include "ipc_thread_skeleton.h"
29 #include "process_skeleton.h"
30 
31 namespace OHOS {
32 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_DBINDER_SER_STUB,
33     "DBinderServiceStub" };
34 
DBinderServiceStub(const std::u16string & service,const std::string & device,binder_uintptr_t object,uint32_t pid,uint32_t uid)35 DBinderServiceStub::DBinderServiceStub(const std::u16string &service, const std::string &device,
36     binder_uintptr_t object, uint32_t pid, uint32_t uid)
37     : IPCObjectStub(Str8ToStr16(std::to_string(object) + "_" + DBinderService::ConvertToSecureDeviceID(device) +
38         "_" + std::to_string(pid))),
39     serviceName_(service), deviceID_(device), binderObject_(object), peerPid_(pid), peerUid_(uid)
40 {
41     DBINDER_LOGD(LOG_LABEL, "created, service:%{public}llu device:%{public}s pid:%{public}u",
42         binderObject_, DBinderService::ConvertToSecureDeviceID(deviceID_).c_str(), peerPid_);
43     dbinderData_ = std::make_unique<uint8_t[]>(sizeof(dbinder_negotiation_data));
44     if (dbinderData_ == nullptr) {
45         DBINDER_LOGW(LOG_LABEL, "malloc dbinderData_ fail");
46         return;
47     }
48     memset_s(dbinderData_.get(), sizeof(dbinder_negotiation_data), 0, sizeof(dbinder_negotiation_data));
49 }
50 
~DBinderServiceStub()51 DBinderServiceStub::~DBinderServiceStub()
52 {
53     DBINDER_LOGD(LOG_LABEL, "destroyed, service:%{public}llu device:%{public}s pid:%{public}u",
54         binderObject_, DBinderService::ConvertToSecureDeviceID(deviceID_).c_str(), peerPid_);
55     dbinderData_ = nullptr;
56 }
57 
GetServiceName()58 const std::u16string &DBinderServiceStub::GetServiceName()
59 {
60     return serviceName_;
61 }
62 
GetDeviceID()63 const std::string &DBinderServiceStub::GetDeviceID()
64 {
65     return deviceID_;
66 }
67 
GetBinderObject() const68 binder_uintptr_t DBinderServiceStub::GetBinderObject() const
69 {
70     return binderObject_;
71 }
72 
GetPeerPid()73 uint32_t DBinderServiceStub::GetPeerPid()
74 {
75     return peerPid_;
76 }
77 
GetPeerUid()78 uint32_t DBinderServiceStub::GetPeerUid()
79 {
80     return peerUid_;
81 }
82 
SetSeqNumber(uint32_t seqNum)83 void DBinderServiceStub::SetSeqNumber(uint32_t seqNum)
84 {
85     seqNum_ = seqNum;
86 }
87 
GetSeqNumber()88 uint32_t DBinderServiceStub::GetSeqNumber()
89 {
90     return seqNum_;
91 }
92 
SetNegoStatusAndTime(NegotiationStatus status,uint64_t time)93 void DBinderServiceStub::SetNegoStatusAndTime(NegotiationStatus status, uint64_t time)
94 {
95     negoStatus_ = status;
96     negoTime_ = time;
97 }
98 
GetNegoStatusAndTime(NegotiationStatus & status,uint64_t & time)99 void DBinderServiceStub::GetNegoStatusAndTime(NegotiationStatus &status, uint64_t &time)
100 {
101     status = negoStatus_;
102     time = negoTime_;
103 }
104 
ProcessProto(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)105 int32_t DBinderServiceStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply,
106     MessageOption &option)
107 {
108     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
109     if (dBinderService == nullptr) {
110         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
111         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
112         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
113     }
114     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
115     if (session == nullptr) {
116         DBINDER_LOGE(LOG_LABEL, "client find session is null");
117         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_SESSION_FAIL, __FUNCTION__);
118         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
119     }
120 
121     DBINDER_LOGI(LOG_LABEL, "serviceName:%{public}s stubIndex:%{public}" PRIu64 " tokenId:%{public}u",
122         session->serviceName.c_str(), session->stubIndex, session->deviceIdInfo.tokenId);
123 
124     int uid = IPCSkeleton::GetCallingUid();
125     int pid = IPCSkeleton::GetCallingPid();
126     if (uid < 0 || pid < 0) {
127         DBINDER_LOGE(LOG_LABEL, "uid or pid err");
128         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_UID_OR_PID_FAIL, __FUNCTION__);
129         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
130     }
131 
132     std::string localBusName = dBinderService->CreateDatabusName(uid, pid);
133     if (localBusName.empty()) {
134         DBINDER_LOGE(LOG_LABEL, "local busname nil");
135         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CREATE_BUS_NAME_FAIL, __FUNCTION__);
136         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
137     }
138 
139     switch (session->type) {
140         case IRemoteObject::DATABUS_TYPE: {
141             if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(session->stubIndex) ||
142                 !reply.WriteString(session->serviceName) || !reply.WriteString(session->deviceIdInfo.toDeviceId) ||
143                 !reply.WriteString(session->deviceIdInfo.fromDeviceId) || !reply.WriteString(localBusName) ||
144                 !reply.WriteUint32(session->deviceIdInfo.tokenId) || !reply.WriteString16(descriptor_)) {
145                 DBINDER_LOGE(LOG_LABEL, "write to parcel fail");
146                 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_WRITE_TO_PARCEL_FAIL, __FUNCTION__);
147                 return DBINDER_SERVICE_PROCESS_PROTO_ERR;
148             }
149             break;
150         }
151         default: {
152             DBINDER_LOGE(LOG_LABEL, "Invalid Type");
153             DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_TYPE_INVALID, __FUNCTION__);
154             return DBINDER_SERVICE_PROCESS_PROTO_ERR;
155         }
156     }
157     return ERR_NONE;
158 }
159 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)160 int32_t DBinderServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
161     MessageOption &option)
162 {
163     int32_t result = ERR_NONE;
164     switch (code) {
165         case GET_PROTO_INFO: {
166             result = ProcessProto(code, data, reply, option);
167             break;
168         }
169         case DBINDER_OBITUARY_TRANSACTION: {
170             result = ProcessDeathRecipient(data);
171             break;
172         }
173         default: {
174             DBINDER_LOGI(LOG_LABEL, "unknown code:%{public}u", code);
175             result = DBINDER_SERVICE_UNKNOW_TRANS_ERR;
176             break;
177         }
178     }
179 
180     return result;
181 }
182 
ProcessDeathRecipient(MessageParcel & data)183 int32_t DBinderServiceStub::ProcessDeathRecipient(MessageParcel &data)
184 {
185     int32_t processType = data.ReadInt32();
186     DBINDER_LOGD(LOG_LABEL, "recv, DBINDER_OBITUARY_TRANSACTION type:%{public}d", processType);
187     if (processType == IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT) {
188         return AddDbinderDeathRecipient(data);
189     }
190 
191     if (processType == IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT) {
192         return RemoveDbinderDeathRecipient(data);
193     }
194 
195     return DBINDER_SERVICE_UNKNOW_TRANS_ERR;
196 }
197 
AddDbinderDeathRecipient(MessageParcel & data)198 int32_t DBinderServiceStub::AddDbinderDeathRecipient(MessageParcel &data)
199 {
200     sptr<IRemoteObject> object = data.ReadRemoteObject();
201     if (object == nullptr) {
202         DBINDER_LOGE(LOG_LABEL, "received proxy is null");
203         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RECEIVED_PROXY_NULL, __FUNCTION__);
204         return DBINDER_SERVICE_INVALID_DATA_ERR;
205     }
206 
207     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
208     sptr<IRemoteObject::DeathRecipient> death(new DbinderDeathRecipient());
209     DBINDER_LOGI(LOG_LABEL, "stub desc:%{public}s",
210         DBinderService::ConvertToSecureDeviceID(Str16ToStr8(descriptor_)).c_str());
211 
212     // If the client dies, notify DBS to delete information of callbackProxy
213     if (!callbackProxy->AddDeathRecipient(death)) {
214         DBINDER_LOGE(LOG_LABEL, "fail to add death recipient");
215         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ADD_DEATH_RECIPIENT_FAIL, __FUNCTION__);
216         return DBINDER_SERVICE_ADD_DEATH_ERR;
217     }
218 
219     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
220     if (dBinderService == nullptr) {
221         DBINDER_LOGE(LOG_LABEL, "dBinder service is null");
222         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
223         return DBINDER_SERVICE_ADD_DEATH_ERR;
224     }
225 
226     if (!dBinderService->AttachDeathRecipient(object, death)) {
227         DBINDER_LOGE(LOG_LABEL, "fail to attach death recipient");
228         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_DEATH_RECIPIENT_FAIL, __FUNCTION__);
229         return DBINDER_SERVICE_ADD_DEATH_ERR;
230     }
231 
232     if (!dBinderService->AttachCallbackProxy(object, this)) {
233         DBINDER_LOGE(LOG_LABEL, "fail to attach callback proxy");
234         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_CALLBACK_PROXY_FAIL, __FUNCTION__);
235         return DBINDER_SERVICE_ADD_DEATH_ERR;
236     }
237     return ERR_NONE;
238 }
239 
RemoveDbinderDeathRecipient(MessageParcel & data)240 int32_t DBinderServiceStub::RemoveDbinderDeathRecipient(MessageParcel &data)
241 {
242     sptr<IRemoteObject> object = data.ReadRemoteObject();
243     if (object == nullptr) {
244         DBINDER_LOGE(LOG_LABEL, "received proxy is null");
245         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RECEIVED_PROXY_NULL, __FUNCTION__);
246         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
247     }
248 
249     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
250     DBINDER_LOGI(LOG_LABEL, "stub desc:%{public}s",
251         DBinderService::ConvertToSecureDeviceID(Str16ToStr8(descriptor_)).c_str());
252     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
253     if (dBinderService == nullptr) {
254         DBINDER_LOGE(LOG_LABEL, "dBinder service is null");
255         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
256         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
257     }
258 
259     sptr<IRemoteObject::DeathRecipient> death = dBinderService->QueryDeathRecipient(object);
260     if (death != nullptr) {
261         // Continue to clear subsequent data
262         callbackProxy->RemoveDeathRecipient(death);
263     }
264 
265     if (!dBinderService->DetachDeathRecipient(object)) {
266         DBINDER_LOGE(LOG_LABEL, "fail to detach death recipient");
267         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_DETACH_DEATH_RECIPIENT_FAIL, __FUNCTION__);
268         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
269     }
270 
271     if (!dBinderService->DetachCallbackProxy(object)) {
272         DBINDER_LOGE(LOG_LABEL, "fail to detach callback proxy");
273         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_DETACH_CALLBACK_PROXY_FAIL, __FUNCTION__);
274         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
275     }
276     return ERR_NONE;
277 }
278 
Marshalling(Parcel & parcel) const279 bool DBinderServiceStub::Marshalling(Parcel &parcel) const
280 {
281     DBINDER_LOGD(LOG_LABEL, "enter");
282     if (dbinderData_ == nullptr) {
283         DBINDER_LOGE(LOG_LABEL, "dbinderData_ is nullptr");
284         return false;
285     }
286     auto *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
287     if (invoker == nullptr) {
288         DBINDER_LOGE(LOG_LABEL, "GetRemoteInvoker fail");
289         return false;
290     }
291 
292     size_t offset = parcel.GetWritePosition();
293     auto dbinderData = reinterpret_cast<const dbinder_negotiation_data *>(dbinderData_.get());
294     if (!ProcessSkeleton::FlattenDBinderData(parcel, dbinderData)) {
295         return false;
296     }
297 
298     if (!invoker->FlattenObject(parcel, this)) {
299         DBINDER_LOGE(LOG_LABEL, "FlattenObject fail");
300         parcel.RewindWrite(offset);
301         return false;
302     }
303     return true;
304 }
305 
Marshalling(Parcel & parcel,const sptr<IRemoteObject> & object)306 bool DBinderServiceStub::Marshalling(Parcel &parcel, const sptr<IRemoteObject> &object)
307 {
308     DBINDER_LOGD(LOG_LABEL, "enter");
309     auto serviceStub = reinterpret_cast<DBinderServiceStub *>(object.GetRefPtr());
310     if (serviceStub == nullptr) {
311         return false;
312     }
313     return serviceStub->Marshalling(parcel);
314 }
315 
SaveDBinderData(const std::string & localBusName)316 int DBinderServiceStub::SaveDBinderData(const std::string &localBusName)
317 {
318     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
319     if (dBinderService == nullptr) {
320         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
321         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
322         return DBINDER_SERVICE_FILL_DATA_ERR;
323     }
324 
325     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
326     if (session == nullptr) {
327         DBINDER_LOGE(LOG_LABEL, "client find session is null");
328         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_SESSION_FAIL, __FUNCTION__);
329         return DBINDER_SERVICE_FILL_DATA_ERR;
330     }
331 
332     if (dbinderData_ == nullptr) {
333         DBINDER_LOGE(LOG_LABEL, "dbinderData_ is nullptr");
334         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
335         return DBINDER_SERVICE_MALLOC_ERR;
336     }
337 
338     dbinder_negotiation_data *dbinderData = reinterpret_cast<dbinder_negotiation_data *>(dbinderData_.get());
339     (void)memset_s(dbinderData, sizeof(dbinder_negotiation_data), 0, sizeof(dbinder_negotiation_data));
340     dbinderData->proto = IRemoteObject::IF_PROT_DATABUS;
341     dbinderData->stub_index = session->stubIndex;
342     dbinderData->tokenid = session->deviceIdInfo.tokenId;
343     auto ret = memcpy_s(dbinderData->target_name, SESSION_NAME_LENGTH, session->serviceName.c_str(),
344         session->serviceName.length());
345     ret += memcpy_s(dbinderData->target_device, DEVICEID_LENGTH, session->deviceIdInfo.toDeviceId,
346         DEVICEID_LENGTH);
347     ret += memcpy_s(dbinderData->local_device, DEVICEID_LENGTH, session->deviceIdInfo.fromDeviceId,
348         DEVICEID_LENGTH);
349     ret += memcpy_s(dbinderData->local_name, SESSION_NAME_LENGTH, localBusName.c_str(), localBusName.length());
350     ret += memcpy_s(dbinderData->desc, DBINDER_DESC_LENGTH, descriptor_.c_str(), descriptor_.length());
351     if (ret != EOK) {
352         DBINDER_LOGE(LOG_LABEL, "memcpy_s fail, ret:%{public}d", ret);
353         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
354         return DBINDER_SERVICE_FILL_DATA_ERR;
355     }
356     DBINDER_LOGI(LOG_LABEL, "proto:%{public}d stubIndex:%{public}llu tokenid:%{public}u "
357         "targetName:%{public}s localName:%{public}s",
358         dbinderData->proto, dbinderData->stub_index, dbinderData->tokenid, dbinderData->target_name,
359         dbinderData->local_name);
360     isInited_ = true;
361     return ERR_NONE;
362 }
363 
CheckSessionObjectValidity()364 bool DBinderServiceStub::CheckSessionObjectValidity()
365 {
366     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
367     if (dBinderService == nullptr) {
368         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
369         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
370         return false;
371     }
372 
373     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
374     if (session == nullptr) {
375         DBINDER_LOGE(LOG_LABEL, "client find session is null");
376         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_SESSION_FAIL, __FUNCTION__);
377         return false;
378     }
379     if (session->type != IRemoteObject::DATABUS_TYPE) {
380         DBINDER_LOGE(LOG_LABEL, "Invalid Type:%{public}d", session->type);
381         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_TYPE_INVALID, __FUNCTION__);
382         return false;
383     }
384     return true;
385 }
386 
GetAndSaveDBinderData(pid_t pid,uid_t uid)387 int DBinderServiceStub::GetAndSaveDBinderData(pid_t pid, uid_t uid)
388 {
389     if (isInited_) {
390         DBINDER_LOGI(LOG_LABEL, "has been inited, uid:%{public}d pid:%{public}d", uid, pid);
391         return ERR_NONE;
392     }
393     if (uid < 0 || pid < 0) {
394         DBINDER_LOGE(LOG_LABEL, "uid(%{public}d) or pid(%{public}d) is invalid", uid, pid);
395         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_UID_OR_PID_FAIL, __FUNCTION__);
396         return DBINDER_SERVICE_FILL_DATA_ERR;
397     }
398     if (!CheckSessionObjectValidity()) {
399         return DBINDER_SERVICE_FILL_DATA_ERR;
400     }
401 
402     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
403     if (dBinderService == nullptr) {
404         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
405         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
406         return DBINDER_SERVICE_FILL_DATA_ERR;
407     }
408     std::string localBusName = dBinderService->CreateDatabusName(uid, pid);
409     if (localBusName.empty()) {
410         DBINDER_LOGE(LOG_LABEL, "local busname nil");
411         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CREATE_BUS_NAME_FAIL, __FUNCTION__);
412         return DBINDER_SERVICE_FILL_DATA_ERR;
413     }
414     return SaveDBinderData(localBusName);
415 }
416 
DBinderClearServiceState(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)417 int DBinderServiceStub::DBinderClearServiceState(uint32_t code, MessageParcel &data, MessageParcel &reply,
418     MessageOption &option)
419 {
420     if (!IPCSkeleton::IsLocalCalling()) {
421         DBINDER_LOGE(LOG_LABEL, "invalid request in dbinder mode");
422         return IPC_STUB_INVALID_DATA_ERR;
423     }
424     SetNegoStatusAndTime(NegotiationStatus::NEGO_INIT, 0);
425     isInited_ = false;
426     DBINDER_LOGI(LOG_LABEL, "succ");
427     return ERR_NONE;
428 }
429 } // namespace OHOS
430