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_callback_stub.h"
17
18 #include <cinttypes>
19
20 #include "dbinder_error_code.h"
21 #include "ipc_debug.h"
22 #include "ipc_process_skeleton.h"
23 #include "ipc_skeleton.h"
24 #include "ipc_thread_skeleton.h"
25 #include "ipc_types.h"
26 #include "log_tags.h"
27 #include "securec.h"
28 #include "string_ex.h"
29 #include "sys_binder.h"
30
31 namespace OHOS {
32 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC_DBINDER_CB_STUB,
33 "DBinderCallbackStub" };
34
DBinderCallbackStub(const std::string & service,const std::string & device,const std::string & localDevice,uint64_t stubIndex,uint32_t handle,uint32_t tokenId)35 DBinderCallbackStub::DBinderCallbackStub(const std::string &service, const std::string &device,
36 const std::string &localDevice, uint64_t stubIndex, uint32_t handle, uint32_t tokenId)
37 : IPCObjectStub(Str8ToStr16("DBinderCallback" + IPCProcessSkeleton::ConvertToSecureString(device) + service)),
38 serviceName_(service), deviceID_(device), localDeviceID_(localDevice), stubIndex_(stubIndex), handle_(handle),
39 tokenId_(tokenId)
40 {
41 ZLOGD(LOG_LABEL, "created, service:%{public}s deviceId:%{public}s handle:%{public}u stubIndex:%{public}" PRIu64,
42 serviceName_.c_str(), IPCProcessSkeleton::ConvertToSecureString(deviceID_).c_str(), handle_, stubIndex_);
43 dbinderData_ = std::make_unique<uint8_t[]>(sizeof(dbinder_negotiation_data));
44 if (dbinderData_ == nullptr) {
45 ZLOGE(LOG_LABEL, "malloc dbinderData_ fail");
46 return;
47 }
48 memset_s(dbinderData_.get(), sizeof(dbinder_negotiation_data), 0, sizeof(dbinder_negotiation_data));
49 }
50
~DBinderCallbackStub()51 DBinderCallbackStub::~DBinderCallbackStub()
52 {
53 ZLOGD(LOG_LABEL, "destroyed, service:%{public}s deviceId:%{public}s handle:%{public}u stubIndex:%{public}" PRIu64,
54 serviceName_.c_str(), IPCProcessSkeleton::ConvertToSecureString(deviceID_).c_str(), handle_, stubIndex_);
55 IPCProcessSkeleton::GetCurrent()->DetachDBinderCallbackStub(this);
56 dbinderData_ = nullptr;
57 }
58
59 // LCOV_EXCL_START
GetServiceName()60 const std::string &DBinderCallbackStub::GetServiceName()
61 {
62 return serviceName_;
63 }
64 // LCOV_EXCL_STOP
65
66 // LCOV_EXCL_START
GetDeviceID()67 const std::string &DBinderCallbackStub::GetDeviceID()
68 {
69 return deviceID_;
70 }
71 // LCOV_EXCL_STOP
72
73 // LCOV_EXCL_START
GetStubIndex() const74 uint64_t DBinderCallbackStub::GetStubIndex() const
75 {
76 return stubIndex_;
77 }
78 // LCOV_EXCL_STOP
79
80 // LCOV_EXCL_START
GetTokenId() const81 uint32_t DBinderCallbackStub::GetTokenId() const
82 {
83 return tokenId_;
84 }
85 // LCOV_EXCL_STOP
86
ProcessProto(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)87 int32_t DBinderCallbackStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply,
88 MessageOption &option)
89 {
90 int uid = IPCSkeleton::GetCallingUid();
91 int pid = IPCSkeleton::GetCallingPid();
92 if (uid < 0 || pid < 0) {
93 ZLOGE(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 sptr<IRemoteObject> object = IPCProcessSkeleton::GetCurrent()->GetSAMgrObject();
98 if (object == nullptr) {
99 ZLOGE(LOG_LABEL, "get sa object is null");
100 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SA_OBJECT_NULL, __FUNCTION__);
101 return DBINDER_CALLBACK_READ_OBJECT_ERR;
102 }
103 IPCObjectProxy *samgr = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
104 std::string sessionName = samgr->GetSessionNameForPidUid(uid, pid);
105 if (sessionName.empty()) {
106 ZLOGE(LOG_LABEL, "grans session name failed");
107 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SESSION_NAME_FAIL, __FUNCTION__);
108 return DBINDER_SERVICE_WRONG_SESSION;
109 }
110 return ProcessData(uid, pid, sessionName, data, reply);
111 }
112
ProcessData(int uid,int pid,const std::string & sessionName,MessageParcel & data,MessageParcel & reply)113 int32_t DBinderCallbackStub::ProcessData(int uid, int pid, const std::string &sessionName, MessageParcel &data,
114 MessageParcel &reply)
115 {
116 MessageParcel authData;
117 MessageParcel authReply;
118 MessageOption authOption;
119 if (!authData.WriteUint32(pid) || !authData.WriteUint32(uid) || !authData.WriteString(localDeviceID_) ||
120 !authData.WriteUint64(stubIndex_) || !authData.WriteUint32(tokenId_)) {
121 ZLOGE(LOG_LABEL, "write to MessageParcel fail");
122 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
123 return ERR_INVALID_DATA;
124 }
125 IRemoteInvoker *dbinderInvoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS);
126 if (dbinderInvoker == nullptr) {
127 ZLOGE(LOG_LABEL, "no databus thread and invoker");
128 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RPC_DATABUS_INVOKER_ERR, __FUNCTION__);
129 return RPC_DATABUS_INVOKER_ERR;
130 }
131 int err = dbinderInvoker->SendRequest(handle_, DBINDER_ADD_COMMAUTH, authData, authReply, authOption);
132 if (err != ERR_NONE) {
133 ZLOGE(LOG_LABEL, "send auth info to remote fail");
134 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_BINDER_CALLBACK_AUTHCOMM_ERR, __FUNCTION__);
135 return BINDER_CALLBACK_AUTHCOMM_ERR;
136 }
137 ZLOGI(LOG_LABEL, "send to stub ok! stubIndex:%{public}" PRIu64 " peerDevice:%{public}s localDeviceID:%{public}s "
138 "serviceName:%{public}s uid:%{public}d pid:%{public}d tokenId:%{public}u sessionName:%{public}s",
139 stubIndex_, IPCProcessSkeleton::ConvertToSecureString(deviceID_).c_str(),
140 IPCProcessSkeleton::ConvertToSecureString(localDeviceID_).c_str(), serviceName_.c_str(), uid, pid, tokenId_,
141 sessionName.c_str());
142 if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteUint64(stubIndex_) ||
143 !reply.WriteString(serviceName_) || !reply.WriteString(deviceID_) || !reply.WriteString(localDeviceID_) ||
144 !reply.WriteString(sessionName) || !reply.WriteUint32(tokenId_)) {
145 ZLOGE(LOG_LABEL, "write to parcel fail");
146 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_INVALID_DATA, __FUNCTION__);
147 return ERR_INVALID_DATA;
148 }
149 return 0;
150 }
151
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)152 int32_t DBinderCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
153 MessageOption &option)
154 {
155 int32_t result = ERR_NONE;
156 ZLOGI(LOG_LABEL, "code:%{public}u", code);
157 switch (code) {
158 case GET_PROTO_INFO: {
159 result = ProcessProto(code, data, reply, option);
160 break;
161 }
162 default: {
163 ZLOGI(LOG_LABEL, "unknown code:%{public}u", code);
164 result = DBINDER_CALLBACK_ERR;
165 break;
166 }
167 }
168
169 return result;
170 }
171
Marshalling(Parcel & parcel) const172 bool DBinderCallbackStub::Marshalling(Parcel &parcel) const
173 {
174 ZLOGD(LOG_LABEL, "enter");
175 if (dbinderData_ == nullptr) {
176 ZLOGE(LOG_LABEL, "dbinderData_ is nullptr");
177 return false;
178 }
179
180 auto *invoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DEFAULT);
181 if (invoker == nullptr) {
182 ZLOGE(LOG_LABEL, "GetRemoteInvoker fail");
183 return false;
184 }
185
186 size_t offset = parcel.GetWritePosition();
187 auto dbinderData = reinterpret_cast<const dbinder_negotiation_data *>(dbinderData_.get());
188 if (!ProcessSkeleton::FlattenDBinderData(parcel, dbinderData)) {
189 return false;
190 }
191
192 if (!invoker->FlattenObject(parcel, this)) {
193 ZLOGE(LOG_LABEL, "FlattenObject fail");
194 parcel.RewindWrite(offset);
195 return false;
196 }
197 return true;
198 }
199
Marshalling(Parcel & parcel,const sptr<IRemoteObject> & object)200 bool DBinderCallbackStub::Marshalling(Parcel &parcel, const sptr<IRemoteObject> &object)
201 {
202 ZLOGD(LOG_LABEL, "enter");
203 auto callback = reinterpret_cast<DBinderCallbackStub *>(object.GetRefPtr());
204 if (callback == nullptr) {
205 return false;
206 }
207 return callback->Marshalling(parcel);
208 }
209
AddDBinderCommAuth(pid_t pid,uid_t uid,const std::string & sessionName)210 int DBinderCallbackStub::AddDBinderCommAuth(pid_t pid, uid_t uid, const std::string &sessionName)
211 {
212 MessageParcel authData, authReply;
213 MessageOption authOption;
214 if (!authData.WriteUint32(pid) || !authData.WriteUint32(uid) || !authData.WriteString(localDeviceID_) ||
215 !authData.WriteUint64(stubIndex_) || !authData.WriteUint32(tokenId_)) {
216 ZLOGE(LOG_LABEL, "write to MessageParcel fail");
217 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_WRITE_TO_PARCEL_FAIL, __FUNCTION__);
218 return IPC_STUB_WRITE_PARCEL_ERR;
219 }
220 IRemoteInvoker *dbinderInvoker = IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS);
221 if (dbinderInvoker == nullptr) {
222 ZLOGE(LOG_LABEL, "no databus thread and invoker");
223 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_RPC_DATABUS_INVOKER_ERR, __FUNCTION__);
224 return RPC_DATABUS_INVOKER_ERR;
225 }
226 int err = dbinderInvoker->SendRequest(handle_, DBINDER_ADD_COMMAUTH, authData, authReply, authOption);
227 if (err != ERR_NONE) {
228 ZLOGE(LOG_LABEL, "send auth info to remote fail");
229 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_BINDER_CALLBACK_AUTHCOMM_ERR, __FUNCTION__);
230 return BINDER_CALLBACK_AUTHCOMM_ERR;
231 }
232
233 ZLOGI(LOG_LABEL, "send to stub ok! stubIndex:%{public}" PRIu64 " peerDevice:%{public}s localDeviceID:%{public}s "
234 "serviceName:%{public}s uid:%{public}d pid:%{public}d tokenId:%{public}u sessionName:%{public}s",
235 stubIndex_, IPCProcessSkeleton::ConvertToSecureString(deviceID_).c_str(),
236 IPCProcessSkeleton::ConvertToSecureString(localDeviceID_).c_str(), serviceName_.c_str(), uid, pid, tokenId_,
237 sessionName.c_str());
238 return ERR_NONE;
239 }
240
SaveDBinderData(const std::string & sessionName)241 int DBinderCallbackStub::SaveDBinderData(const std::string &sessionName)
242 {
243 if (dbinderData_ == nullptr) {
244 ZLOGE(LOG_LABEL, "dbinderData_ is nullptr");
245 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
246 return DBINDER_CALLBACK_MALLOC_ERR;
247 }
248
249 dbinder_negotiation_data *dbinderData = reinterpret_cast<dbinder_negotiation_data *>(dbinderData_.get());
250 (void)memset_s(dbinderData, sizeof(dbinder_negotiation_data), 0, sizeof(dbinder_negotiation_data));
251 dbinderData->proto = IRemoteObject::IF_PROT_DATABUS;
252 dbinderData->stub_index = stubIndex_;
253 dbinderData->tokenid = tokenId_;
254 auto ret = memcpy_s(dbinderData->target_name, SESSION_NAME_LENGTH, serviceName_.c_str(), serviceName_.length());
255 ret += memcpy_s(dbinderData->target_device, DEVICEID_LENGTH, deviceID_.c_str(), deviceID_.length());
256 ret += memcpy_s(dbinderData->local_device, DEVICEID_LENGTH, localDeviceID_.c_str(), localDeviceID_.length());
257 ret += memcpy_s(dbinderData->local_name, SESSION_NAME_LENGTH, sessionName.c_str(), sessionName.length());
258 ret += memcpy_s(dbinderData->desc, DBINDER_DESC_LENGTH, descriptor_.c_str(), descriptor_.length());
259 if (ret != EOK) {
260 ZLOGE(LOG_LABEL, "memcpy_s fail, ret:%{public}d", ret);
261 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_ERR_MEMCPY_DATA, __FUNCTION__);
262 return DBINDER_CALLBACK_MEMCPY_ERR;
263 }
264 ZLOGI(LOG_LABEL, "proto:%{public}u stubIndex:%{public}llu tokenId:%{public}u "
265 "targetName:%{public}s localName:%{public}s",
266 dbinderData->proto, dbinderData->stub_index, dbinderData->tokenid, dbinderData->target_name,
267 dbinderData->local_name);
268 return ERR_NONE;
269 }
270
GetAndSaveDBinderData(pid_t pid,uid_t uid)271 int DBinderCallbackStub::GetAndSaveDBinderData(pid_t pid, uid_t uid)
272 {
273 if (uid < 0 || pid < 0) {
274 ZLOGE(LOG_LABEL, "uid(%{public}d) or pid(%{public}d) is invalid", uid, pid);
275 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_UID_OR_PID_FAIL, __FUNCTION__);
276 return DBINDER_CALLBACK_FILL_DATA_ERR;
277 }
278
279 sptr<IRemoteObject> object = IPCProcessSkeleton::GetCurrent()->GetSAMgrObject();
280 if (object == nullptr) {
281 ZLOGE(LOG_LABEL, "GetSAMgrObject failed");
282 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SA_OBJECT_NULL, __FUNCTION__);
283 return DBINDER_CALLBACK_FILL_DATA_ERR;
284 }
285 IPCObjectProxy *samgr = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
286 std::string sessionName = samgr->GetSessionNameForPidUid(uid, pid);
287 if (sessionName.empty()) {
288 ZLOGE(LOG_LABEL, "GetSessionNameForPidUid failed");
289 DfxReportFailEvent(DbinderErrorCode::RPC_DRIVER, RADAR_GET_SESSION_NAME_FAIL, __FUNCTION__);
290 return DBINDER_CALLBACK_FILL_DATA_ERR;
291 }
292
293 int ret = AddDBinderCommAuth(pid, uid, sessionName);
294 if (ret != ERR_NONE) {
295 ZLOGE(LOG_LABEL, "AddDBinderCommAuth failed");
296 return ret;
297 }
298
299 ret = SaveDBinderData(sessionName);
300 if (ret != ERR_NONE) {
301 ZLOGE(LOG_LABEL, "SaveDBinderData failed");
302 return ret;
303 }
304 return ERR_NONE;
305 }
306 } // namespace OHOS
307