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