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