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