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::string & service,const std::string & device,binder_uintptr_t object)35 DBinderServiceStub::DBinderServiceStub(const std::string &service, const std::string &device, binder_uintptr_t object)
36     : IPCObjectStub(Str8ToStr16(DBinderService::ConvertToSecureDeviceID(device) + service)),
37     serviceName_(service), deviceID_(device), binderObject_(object)
38 {
39     DBINDER_LOGD(LOG_LABEL, "created, service:%{public}s device:%{public}s",
40         serviceName_.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID_).c_str());
41     dbinderData_ = std::make_unique<uint8_t[]>(sizeof(dbinder_negotiation_data));
42     if (dbinderData_ == nullptr) {
43         DBINDER_LOGW(LOG_LABEL, "malloc dbinderData_ fail");
44         return;
45     }
46     memset_s(dbinderData_.get(), sizeof(dbinder_negotiation_data), 0, sizeof(dbinder_negotiation_data));
47 }
48 
~DBinderServiceStub()49 DBinderServiceStub::~DBinderServiceStub()
50 {
51     DBINDER_LOGD(LOG_LABEL, "destroyed, service:%{public}s device:%{public}s",
52         serviceName_.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID_).c_str());
53     dbinderData_ = nullptr;
54 }
55 
GetServiceName()56 const std::string &DBinderServiceStub::GetServiceName()
57 {
58     return serviceName_;
59 }
60 
GetDeviceID()61 const std::string &DBinderServiceStub::GetDeviceID()
62 {
63     return deviceID_;
64 }
65 
GetBinderObject() const66 binder_uintptr_t DBinderServiceStub::GetBinderObject() const
67 {
68     return binderObject_;
69 }
70 
ProcessProto(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)71 int32_t DBinderServiceStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply,
72     MessageOption &option)
73 {
74     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
75     if (dBinderService == nullptr) {
76         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
77         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
78         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
79     }
80     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
81     if (session == nullptr) {
82         DBINDER_LOGE(LOG_LABEL, "client find session is null");
83         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_SESSION_FAIL, __FUNCTION__);
84         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
85     }
86 
87     DBINDER_LOGI(LOG_LABEL, "serviceName:%{public}s stubIndex:%{public}" PRIu64 " tokenId:%{public}u",
88         session->serviceName.c_str(), session->stubIndex, session->deviceIdInfo.tokenId);
89 
90     int uid = IPCSkeleton::GetCallingUid();
91     int pid = IPCSkeleton::GetCallingPid();
92     if (uid < 0 || pid < 0) {
93         DBINDER_LOGE(LOG_LABEL, "uid or pid err");
94         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_UID_OR_PID_FAIL, __FUNCTION__);
95         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
96     }
97 
98     std::string localBusName = dBinderService->CreateDatabusName(uid, pid);
99     if (localBusName.empty()) {
100         DBINDER_LOGE(LOG_LABEL, "local busname nil");
101         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CREATE_BUS_NAME_FAIL, __FUNCTION__);
102         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
103     }
104 
105     switch (session->type) {
106         case IRemoteObject::DATABUS_TYPE: {
107             if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(session->stubIndex) ||
108                 !reply.WriteString(session->serviceName) || !reply.WriteString(session->deviceIdInfo.toDeviceId) ||
109                 !reply.WriteString(session->deviceIdInfo.fromDeviceId) || !reply.WriteString(localBusName) ||
110                 !reply.WriteUint32(session->deviceIdInfo.tokenId) || !reply.WriteString16(descriptor_)) {
111                 DBINDER_LOGE(LOG_LABEL, "write to parcel fail");
112                 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_WRITE_TO_PARCEL_FAIL, __FUNCTION__);
113                 return DBINDER_SERVICE_PROCESS_PROTO_ERR;
114             }
115             break;
116         }
117         default: {
118             DBINDER_LOGE(LOG_LABEL, "Invalid Type");
119             DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_TYPE_INVALID, __FUNCTION__);
120             return DBINDER_SERVICE_PROCESS_PROTO_ERR;
121         }
122     }
123     return ERR_NONE;
124 }
125 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)126 int32_t DBinderServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
127     MessageOption &option)
128 {
129     int32_t result = ERR_NONE;
130     switch (code) {
131         case GET_PROTO_INFO: {
132             result = ProcessProto(code, data, reply, option);
133             break;
134         }
135         case DBINDER_OBITUARY_TRANSACTION: {
136             result = ProcessDeathRecipient(data);
137             break;
138         }
139         default: {
140             DBINDER_LOGI(LOG_LABEL, "unknown code:%{public}u", code);
141             result = DBINDER_SERVICE_UNKNOW_TRANS_ERR;
142             break;
143         }
144     }
145 
146     return result;
147 }
148 
ProcessDeathRecipient(MessageParcel & data)149 int32_t DBinderServiceStub::ProcessDeathRecipient(MessageParcel &data)
150 {
151     int32_t processType = data.ReadInt32();
152     DBINDER_LOGD(LOG_LABEL, "recv, DBINDER_OBITUARY_TRANSACTION type:%{public}d", processType);
153     if (processType == IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT) {
154         return AddDbinderDeathRecipient(data);
155     }
156 
157     if (processType == IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT) {
158         return RemoveDbinderDeathRecipient(data);
159     }
160 
161     return DBINDER_SERVICE_UNKNOW_TRANS_ERR;
162 }
163 
AddDbinderDeathRecipient(MessageParcel & data)164 int32_t DBinderServiceStub::AddDbinderDeathRecipient(MessageParcel &data)
165 {
166     sptr<IRemoteObject> object = data.ReadRemoteObject();
167     if (object == nullptr) {
168         DBINDER_LOGE(LOG_LABEL, "received proxy is null");
169         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RECEIVED_PROXY_NULL, __FUNCTION__);
170         return DBINDER_SERVICE_INVALID_DATA_ERR;
171     }
172 
173     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
174     sptr<IRemoteObject::DeathRecipient> death(new DbinderDeathRecipient());
175     DBINDER_LOGI(LOG_LABEL, "stub desc:%{public}s",
176         DBinderService::ConvertToSecureDeviceID(Str16ToStr8(descriptor_)).c_str());
177 
178     // If the client dies, notify DBS to delete information of callbackProxy
179     if (!callbackProxy->AddDeathRecipient(death)) {
180         DBINDER_LOGE(LOG_LABEL, "fail to add death recipient");
181         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ADD_DEATH_RECIPIENT_FAIL, __FUNCTION__);
182         return DBINDER_SERVICE_ADD_DEATH_ERR;
183     }
184 
185     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
186     if (dBinderService == nullptr) {
187         DBINDER_LOGE(LOG_LABEL, "dBinder service is null");
188         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
189         return DBINDER_SERVICE_ADD_DEATH_ERR;
190     }
191 
192     if (!dBinderService->AttachDeathRecipient(object, death)) {
193         DBINDER_LOGE(LOG_LABEL, "fail to attach death recipient");
194         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_DEATH_RECIPIENT_FAIL, __FUNCTION__);
195         return DBINDER_SERVICE_ADD_DEATH_ERR;
196     }
197 
198     if (!dBinderService->AttachCallbackProxy(object, this)) {
199         DBINDER_LOGE(LOG_LABEL, "fail to attach callback proxy");
200         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ATTACH_CALLBACK_PROXY_FAIL, __FUNCTION__);
201         return DBINDER_SERVICE_ADD_DEATH_ERR;
202     }
203     return ERR_NONE;
204 }
205 
RemoveDbinderDeathRecipient(MessageParcel & data)206 int32_t DBinderServiceStub::RemoveDbinderDeathRecipient(MessageParcel &data)
207 {
208     sptr<IRemoteObject> object = data.ReadRemoteObject();
209     if (object == nullptr) {
210         DBINDER_LOGE(LOG_LABEL, "received proxy is null");
211         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RECEIVED_PROXY_NULL, __FUNCTION__);
212         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
213     }
214 
215     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
216     DBINDER_LOGI(LOG_LABEL, "stub desc:%{public}s",
217         DBinderService::ConvertToSecureDeviceID(Str16ToStr8(descriptor_)).c_str());
218     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
219     if (dBinderService == nullptr) {
220         DBINDER_LOGE(LOG_LABEL, "dBinder service is null");
221         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
222         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
223     }
224 
225     sptr<IRemoteObject::DeathRecipient> death = dBinderService->QueryDeathRecipient(object);
226     if (death != nullptr) {
227         // Continue to clear subsequent data
228         callbackProxy->RemoveDeathRecipient(death);
229     }
230 
231     if (!dBinderService->DetachDeathRecipient(object)) {
232         DBINDER_LOGE(LOG_LABEL, "fail to detach death recipient");
233         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_DETACH_DEATH_RECIPIENT_FAIL, __FUNCTION__);
234         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
235     }
236 
237     if (!dBinderService->DetachCallbackProxy(object)) {
238         DBINDER_LOGE(LOG_LABEL, "fail to detach callback proxy");
239         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_DETACH_CALLBACK_PROXY_FAIL, __FUNCTION__);
240         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
241     }
242     return ERR_NONE;
243 }
244 
Marshalling(Parcel & parcel) const245 bool DBinderServiceStub::Marshalling(Parcel &parcel) const
246 {
247     DBINDER_LOGD(LOG_LABEL, "enter");
248     if (dbinderData_ == nullptr) {
249         DBINDER_LOGE(LOG_LABEL, "dbinderData_ is nullptr");
250         return false;
251     }
252     auto *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
253     if (invoker == nullptr) {
254         DBINDER_LOGE(LOG_LABEL, "GetRemoteInvoker fail");
255         return false;
256     }
257 
258     size_t offset = parcel.GetWritePosition();
259     auto dbinderData = reinterpret_cast<const dbinder_negotiation_data *>(dbinderData_.get());
260     if (!ProcessSkeleton::FlattenDBinderData(parcel, dbinderData)) {
261         return false;
262     }
263 
264     if (!invoker->FlattenObject(parcel, this)) {
265         DBINDER_LOGE(LOG_LABEL, "FlattenObject fail");
266         parcel.RewindWrite(offset);
267         return false;
268     }
269     return true;
270 }
271 
Marshalling(Parcel & parcel,const sptr<IRemoteObject> & object)272 bool DBinderServiceStub::Marshalling(Parcel &parcel, const sptr<IRemoteObject> &object)
273 {
274     DBINDER_LOGD(LOG_LABEL, "enter");
275     auto serviceStub = reinterpret_cast<DBinderServiceStub *>(object.GetRefPtr());
276     if (serviceStub == nullptr) {
277         return false;
278     }
279     return serviceStub->Marshalling(parcel);
280 }
281 
SaveDBinderData(const std::string & localBusName)282 int DBinderServiceStub::SaveDBinderData(const std::string &localBusName)
283 {
284     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
285     if (dBinderService == nullptr) {
286         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
287         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
288         return DBINDER_SERVICE_FILL_DATA_ERR;
289     }
290 
291     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
292     if (session == nullptr) {
293         DBINDER_LOGE(LOG_LABEL, "client find session is null");
294         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_SESSION_FAIL, __FUNCTION__);
295         return DBINDER_SERVICE_FILL_DATA_ERR;
296     }
297 
298     if (dbinderData_ == nullptr) {
299         DBINDER_LOGE(LOG_LABEL, "dbinderData_ is nullptr");
300         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
301         return DBINDER_SERVICE_MALLOC_ERR;
302     }
303 
304     dbinder_negotiation_data *dbinderData = reinterpret_cast<dbinder_negotiation_data *>(dbinderData_.get());
305     (void)memset_s(dbinderData, sizeof(dbinder_negotiation_data), 0, sizeof(dbinder_negotiation_data));
306     dbinderData->proto = IRemoteObject::IF_PROT_DATABUS;
307     dbinderData->stub_index = session->stubIndex;
308     dbinderData->tokenid = session->deviceIdInfo.tokenId;
309     auto ret = memcpy_s(dbinderData->target_name, SESSION_NAME_LENGTH, session->serviceName.c_str(),
310         session->serviceName.length());
311     ret += memcpy_s(dbinderData->target_device, DEVICEID_LENGTH, session->deviceIdInfo.toDeviceId,
312         DEVICEID_LENGTH);
313     ret += memcpy_s(dbinderData->local_device, DEVICEID_LENGTH, session->deviceIdInfo.fromDeviceId,
314         DEVICEID_LENGTH);
315     ret += memcpy_s(dbinderData->local_name, SESSION_NAME_LENGTH, localBusName.c_str(), localBusName.length());
316     ret += memcpy_s(dbinderData->desc, DBINDER_DESC_LENGTH, descriptor_.c_str(), descriptor_.length());
317     if (ret != EOK) {
318         DBINDER_LOGE(LOG_LABEL, "memcpy_s fail, ret:%{public}d", ret);
319         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
320         return DBINDER_SERVICE_FILL_DATA_ERR;
321     }
322     DBINDER_LOGI(LOG_LABEL, "proto:%{public}d stubIndex:%{public}llu tokenid:%{public}u "
323         "targetName:%{public}s localName:%{public}s",
324         dbinderData->proto, dbinderData->stub_index, dbinderData->tokenid, dbinderData->target_name,
325         dbinderData->local_name);
326     return ERR_NONE;
327 }
328 
CheckSessionObjectValidity()329 bool DBinderServiceStub::CheckSessionObjectValidity()
330 {
331     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
332     if (dBinderService == nullptr) {
333         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
334         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
335         return false;
336     }
337 
338     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
339     if (session == nullptr) {
340         DBINDER_LOGE(LOG_LABEL, "client find session is null");
341         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_QUERY_SESSION_FAIL, __FUNCTION__);
342         return false;
343     }
344     if (session->type != IRemoteObject::DATABUS_TYPE) {
345         DBINDER_LOGE(LOG_LABEL, "Invalid Type:%{public}d", session->type);
346         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_TYPE_INVALID, __FUNCTION__);
347         return false;
348     }
349     return true;
350 }
351 
GetAndSaveDBinderData(pid_t pid,uid_t uid)352 int DBinderServiceStub::GetAndSaveDBinderData(pid_t pid, uid_t uid)
353 {
354     if (uid < 0 || pid < 0) {
355         DBINDER_LOGE(LOG_LABEL, "uid(%{public}d) or pid(%{public}d) is invalid", uid, pid);
356         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_UID_OR_PID_FAIL, __FUNCTION__);
357         return DBINDER_SERVICE_FILL_DATA_ERR;
358     }
359     if (!CheckSessionObjectValidity()) {
360         return DBINDER_SERVICE_FILL_DATA_ERR;
361     }
362 
363     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
364     if (dBinderService == nullptr) {
365         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
366         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SERVICE_NULL, __FUNCTION__);
367         return DBINDER_SERVICE_FILL_DATA_ERR;
368     }
369     std::string localBusName = dBinderService->CreateDatabusName(uid, pid);
370     if (localBusName.empty()) {
371         DBINDER_LOGE(LOG_LABEL, "local busname nil");
372         DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_CREATE_BUS_NAME_FAIL, __FUNCTION__);
373         return DBINDER_SERVICE_FILL_DATA_ERR;
374     }
375     return SaveDBinderData(localBusName);
376 }
377 } // namespace OHOS
378