• 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_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