• 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 "sys_binder.h"
20 #include "string_ex.h"
21 #include "dbinder_log.h"
22 #include "dbinder_service.h"
23 #include "dbinder_death_recipient.h"
24 #include "ipc_skeleton.h"
25 
26 namespace OHOS {
27 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_DBINDER_SER_STUB,
28     "DbinderServiceStub" };
29 
DBinderServiceStub(const std::string & service,const std::string & device,binder_uintptr_t object)30 DBinderServiceStub::DBinderServiceStub(const std::string &service, const std::string &device, binder_uintptr_t object)
31     : IPCObjectStub(Str8ToStr16(DBinderService::ConvertToSecureDeviceID(device) + service)),
32     serviceName_(service), deviceID_(device), binderObject_(object)
33 {
34     DBINDER_LOGD(LOG_LABEL, "created, service:%{public}s device:%{public}s",
35         serviceName_.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID_).c_str());
36 }
37 
~DBinderServiceStub()38 DBinderServiceStub::~DBinderServiceStub()
39 {
40     DBINDER_LOGD(LOG_LABEL, "destroyed, service:%{public}s device:%{public}s",
41         serviceName_.c_str(), DBinderService::ConvertToSecureDeviceID(deviceID_).c_str());
42 }
43 
GetServiceName()44 const std::string &DBinderServiceStub::GetServiceName()
45 {
46     return serviceName_;
47 }
48 
GetDeviceID()49 const std::string &DBinderServiceStub::GetDeviceID()
50 {
51     return deviceID_;
52 }
53 
GetBinderObject() const54 binder_uintptr_t DBinderServiceStub::GetBinderObject() const
55 {
56     return binderObject_;
57 }
58 
ProcessProto(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)59 int32_t DBinderServiceStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply,
60     MessageOption &option)
61 {
62     int result = ERR_NONE;
63     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
64     if (dBinderService == nullptr) {
65         DBINDER_LOGE(LOG_LABEL, "DBinderService is nullptr");
66         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
67     }
68     auto session = dBinderService->QuerySessionObject(reinterpret_cast<binder_uintptr_t>(this));
69     if (session == nullptr) {
70         DBINDER_LOGE(LOG_LABEL, "client find session is null");
71         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
72     }
73 
74     DBINDER_LOGI(LOG_LABEL, "serviceName:%{public}s stubIndex:%{public}" PRIu64 " tokenId:%{public}u",
75         session->serviceName.c_str(), session->stubIndex, session->deviceIdInfo.tokenId);
76 
77     int uid = IPCSkeleton::GetCallingUid();
78     int pid = IPCSkeleton::GetCallingPid();
79     if (uid < 0 || pid < 0) {
80         DBINDER_LOGE(LOG_LABEL, "uid or pid err");
81         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
82     }
83 
84     std::string localBusName = dBinderService->CreateDatabusName(uid, pid);
85     if (localBusName.empty()) {
86         DBINDER_LOGE(LOG_LABEL, "local busname nil");
87         return DBINDER_SERVICE_PROCESS_PROTO_ERR;
88     }
89 
90     switch (session->type) {
91         case IRemoteObject::DATABUS_TYPE: {
92             if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(session->stubIndex) ||
93                 !reply.WriteString(session->serviceName) || !reply.WriteString(session->deviceIdInfo.toDeviceId) ||
94                 !reply.WriteString(session->deviceIdInfo.fromDeviceId) || !reply.WriteString(localBusName) ||
95                 !reply.WriteUint32(session->deviceIdInfo.tokenId) || !reply.WriteString16(descriptor_)) {
96                 DBINDER_LOGE(LOG_LABEL, "write to parcel fail");
97                 return DBINDER_SERVICE_PROCESS_PROTO_ERR;
98             }
99             break;
100         }
101         default: {
102             DBINDER_LOGE(LOG_LABEL, "Invalid Type");
103             return DBINDER_SERVICE_PROCESS_PROTO_ERR;
104         }
105     }
106 
107     return result;
108 }
109 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)110 int32_t DBinderServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
111     MessageOption &option)
112 {
113     int32_t result = ERR_NONE;
114     switch (code) {
115         case GET_PROTO_INFO: {
116             result = ProcessProto(code, data, reply, option);
117             break;
118         }
119         case DBINDER_OBITUARY_TRANSACTION: {
120             result = ProcessDeathRecipient(data, reply);
121             break;
122         }
123         default: {
124             DBINDER_LOGI(LOG_LABEL, "unknown code:%{public}u", code);
125             result = DBINDER_SERVICE_UNKNOW_TRANS_ERR;
126             break;
127         }
128     }
129 
130     return result;
131 }
132 
ProcessDeathRecipient(MessageParcel & data,MessageParcel & reply)133 int32_t DBinderServiceStub::ProcessDeathRecipient(MessageParcel &data, MessageParcel &reply)
134 {
135     int32_t processType = data.ReadInt32();
136     DBINDER_LOGD(LOG_LABEL, "recv, DBINDER_OBITUARY_TRANSACTION type:%{public}d", processType);
137     if (processType == IRemoteObject::DeathRecipient::ADD_DEATH_RECIPIENT) {
138         return AddDbinderDeathRecipient(data, reply);
139     }
140 
141     if (processType == IRemoteObject::DeathRecipient::REMOVE_DEATH_RECIPIENT) {
142         return RemoveDbinderDeathRecipient(data, reply);
143     }
144 
145     return DBINDER_SERVICE_UNKNOW_TRANS_ERR;
146 }
147 
AddDbinderDeathRecipient(MessageParcel & data,MessageParcel & reply)148 int32_t DBinderServiceStub::AddDbinderDeathRecipient(MessageParcel &data, MessageParcel &reply)
149 {
150     sptr<IRemoteObject> object = data.ReadRemoteObject();
151     if (object == nullptr) {
152         DBINDER_LOGE(LOG_LABEL, "received proxy is null");
153         return DBINDER_SERVICE_INVALID_DATA_ERR;
154     }
155 
156     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
157     sptr<IRemoteObject::DeathRecipient> death(new DbinderDeathRecipient());
158     DBINDER_LOGI(LOG_LABEL, "stub desc:%{public}s",
159         DBinderService::ConvertToSecureDeviceID(Str16ToStr8(descriptor_)).c_str());
160 
161     // If the client dies, notify DBS to delete information of callbackProxy
162     if (!callbackProxy->AddDeathRecipient(death)) {
163         DBINDER_LOGE(LOG_LABEL, "fail to add death recipient");
164         return DBINDER_SERVICE_ADD_DEATH_ERR;
165     }
166 
167     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
168     if (dBinderService == nullptr) {
169         DBINDER_LOGE(LOG_LABEL, "dBinder service is null");
170         return DBINDER_SERVICE_ADD_DEATH_ERR;
171     }
172 
173     if (!dBinderService->AttachDeathRecipient(object, death)) {
174         DBINDER_LOGE(LOG_LABEL, "fail to attach death recipient");
175         return DBINDER_SERVICE_ADD_DEATH_ERR;
176     }
177 
178     if (!dBinderService->AttachCallbackProxy(object, this)) {
179         DBINDER_LOGE(LOG_LABEL, "fail to attach callback proxy");
180         return DBINDER_SERVICE_ADD_DEATH_ERR;
181     }
182     return ERR_NONE;
183 }
184 
RemoveDbinderDeathRecipient(MessageParcel & data,MessageParcel & reply)185 int32_t DBinderServiceStub::RemoveDbinderDeathRecipient(MessageParcel &data, MessageParcel &reply)
186 {
187     sptr<IRemoteObject> object = data.ReadRemoteObject();
188     if (object == nullptr) {
189         DBINDER_LOGE(LOG_LABEL, "received proxy is null");
190         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
191     }
192 
193     IPCObjectProxy *callbackProxy = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
194     DBINDER_LOGI(LOG_LABEL, "stub desc:%{public}s",
195         DBinderService::ConvertToSecureDeviceID(Str16ToStr8(descriptor_)).c_str());
196     sptr<DBinderService> dBinderService = DBinderService::GetInstance();
197     if (dBinderService == nullptr) {
198         DBINDER_LOGE(LOG_LABEL, "dBinder service is null");
199         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
200     }
201 
202     sptr<IRemoteObject::DeathRecipient> death = dBinderService->QueryDeathRecipient(object);
203     if (death != nullptr) {
204         // Continue to clear subsequent data
205         callbackProxy->RemoveDeathRecipient(death);
206     }
207 
208     if (!dBinderService->DetachDeathRecipient(object)) {
209         DBINDER_LOGE(LOG_LABEL, "fail to detach death recipient");
210         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
211     }
212 
213     if (!dBinderService->DetachCallbackProxy(object)) {
214         DBINDER_LOGE(LOG_LABEL, "fail to detach callback proxy");
215         return DBINDER_SERVICE_REMOVE_DEATH_ERR;
216     }
217     return ERR_NONE;
218 }
219 } // namespace OHOS
220