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 "ipc_object_stub.h"
17
18 #include <cstdint>
19 #include <ctime>
20 #include <string>
21
22 #include "hilog/log_c.h"
23 #include "hilog/log_cpp.h"
24 #include "iosfwd"
25 #include "ipc_debug.h"
26 #include "ipc_payload_statistics_impl.h"
27 #include "ipc_process_skeleton.h"
28 #include "ipc_skeleton.h"
29 #include "ipc_thread_skeleton.h"
30 #include "ipc_types.h"
31 #include "iremote_invoker.h"
32 #include "iremote_object.h"
33 #include "log_tags.h"
34 #include "message_option.h"
35 #include "message_parcel.h"
36 #include "process_skeleton.h"
37 #include "refbase.h"
38 #include "string_ex.h"
39 #include "sys_binder.h"
40 #include "unistd.h"
41 #include "vector"
42
43 #ifndef CONFIG_IPC_SINGLE
44 #include "dbinder_databus_invoker.h"
45 #include "dbinder_error_code.h"
46 #endif
47
48 namespace OHOS {
49 #ifdef CONFIG_IPC_SINGLE
50 using namespace IPC_SINGLE;
51 #endif
52 using namespace OHOS::HiviewDFX;
53 static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC_STUB, "IPCObjectStub" };
54 #ifndef CONFIG_IPC_SINGLE
55 // Authentication information can be added only for processes with system permission.
56 static constexpr pid_t ALLOWED_UID = 10000;
57 #endif
58 static constexpr int SHELL_UID = 2000;
59 static constexpr int HIDUMPER_SERVICE_UID = 1212;
60 static constexpr int COEFF_MILLI_TO_MICRO = 1000;
61 static constexpr int IPC_CMD_PROCESS_WARN_TIME = 500 * COEFF_MILLI_TO_MICRO; // 500 ms
62
IPCObjectStub(std::u16string descriptor,bool serialInvokeFlag)63 IPCObjectStub::IPCObjectStub(std::u16string descriptor, bool serialInvokeFlag)
64 : IRemoteObject(descriptor), serialInvokeFlag_(serialInvokeFlag), lastRequestTime_(0)
65 {
66 ZLOGD(LABEL, "desc:%{public}s, %{public}u",
67 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(),
68 ProcessSkeleton::ConvertAddr(this));
69 auto start = std::chrono::steady_clock::now();
70 lastRequestTime_ = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
71 start.time_since_epoch()).count());
72 ProcessSkeleton *current = ProcessSkeleton::GetInstance();
73 if (current == nullptr) {
74 ZLOGE(LABEL, "ProcessSkeleton is null");
75 return;
76 }
77 if (current->GetSamgrFlag()) {
78 SetRequestSidFlag(true);
79 }
80 std::u16string str(descriptor_);
81 current->AttachValidObject(this, str);
82 }
83
~IPCObjectStub()84 IPCObjectStub::~IPCObjectStub()
85 {
86 ZLOGD(LABEL, "desc:%{public}s, %{public}u",
87 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(),
88 ProcessSkeleton::ConvertAddr(this));
89 ProcessSkeleton *current = ProcessSkeleton::GetInstance();
90 if (current == nullptr) {
91 ZLOGE(LABEL, "ProcessSkeleton is null");
92 return;
93 }
94 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
95 std::chrono::steady_clock::now().time_since_epoch()).count());
96 current->DetachValidObject(this);
97 }
98
IsDeviceIdIllegal(const std::string & deviceID)99 bool IPCObjectStub::IsDeviceIdIllegal(const std::string &deviceID)
100 {
101 if (deviceID.empty() || deviceID.length() > DEVICEID_LENGTH) {
102 return true;
103 }
104 return false;
105 }
106
GetObjectRefCount()107 int32_t IPCObjectStub::GetObjectRefCount()
108 {
109 return GetSptrRefCount();
110 }
111
Dump(int fd,const std::vector<std::u16string> & args)112 int IPCObjectStub::Dump(int fd, const std::vector<std::u16string> &args)
113 {
114 const size_t numArgs = args.size();
115 ZLOGE(LABEL, "Invalid call on Stub, fd:%{public}d args:%{public}zu", fd, numArgs);
116 return ERR_NONE;
117 }
118
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)119 int IPCObjectStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
120 {
121 int result = ERR_NONE;
122 switch (code) {
123 #ifndef CONFIG_IPC_SINGLE
124 case DBINDER_OBITUARY_TRANSACTION: {
125 ZLOGW(LABEL, "recv DBINDER_OBITUARY_TRANSACTION, desc:%{public}s",
126 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
127 if (data.ReadInt32() == IRemoteObject::DeathRecipient::NOTICE_DEATH_RECIPIENT) {
128 result = NoticeServiceDie(data, reply, option);
129 } else {
130 result = IPC_STUB_INVALID_DATA_ERR;
131 }
132 break;
133 }
134 #endif
135 default:
136 result = IPC_STUB_UNKNOW_TRANS_ERR;
137 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
138 std::chrono::steady_clock::now().time_since_epoch()).count());
139 ZLOGW(LABEL, "unknown code:%{public}u desc:%{public}s time:%{public}" PRIu64, code,
140 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), curTime);
141 break;
142 }
143 return result;
144 }
145
OnRemoteDump(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)146 int IPCObjectStub::OnRemoteDump(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
147 {
148 int result = ERR_NONE;
149 int fd = data.ReadFileDescriptor();
150 std::vector<std::u16string> args;
151 if (fd != INVALID_FD) {
152 if (data.ReadString16Vector(&args)) {
153 result = Dump(fd, args);
154 }
155 ::close(fd);
156 } else {
157 result = IPC_STUB_INVALID_DATA_ERR;
158 }
159 return result;
160 }
161
DBinderPingTransaction(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)162 int IPCObjectStub::DBinderPingTransaction(uint32_t code,
163 MessageParcel &data, MessageParcel &reply, MessageOption &option)
164 {
165 if (!reply.WriteInt32(ERR_NONE)) {
166 return IPC_STUB_WRITE_PARCEL_ERR;
167 }
168 return ERR_NONE;
169 }
170
DBinderSearchDescriptor(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)171 int IPCObjectStub::DBinderSearchDescriptor(uint32_t code,
172 MessageParcel &data, MessageParcel &reply, MessageOption &option)
173 {
174 std::u16string descriptor = GetObjectDescriptor();
175 if (!reply.WriteString16(descriptor)) {
176 ZLOGE(LABEL, "write to parcel fail");
177 return IPC_STUB_WRITE_PARCEL_ERR;
178 }
179 return ERR_NONE;
180 }
181
DBinderSearchRefCount(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)182 int IPCObjectStub::DBinderSearchRefCount(uint32_t code,
183 MessageParcel &data, MessageParcel &reply, MessageOption &option)
184 {
185 int refCount = GetObjectRefCount();
186 // when handle transaction the invoker would try to acquire
187 // the object's reference to defense the object being released
188 // so the actual we should decrement the temporary reference.
189 if (IPCSkeleton::IsLocalCalling()) {
190 --refCount;
191 }
192 reply.WriteInt32(refCount);
193 return ERR_NONE;
194 }
195
DBinderDumpTransaction(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)196 int IPCObjectStub::DBinderDumpTransaction(uint32_t code,
197 MessageParcel &data, MessageParcel &reply, MessageOption &option)
198 {
199 pid_t uid = IPCSkeleton::GetCallingUid();
200 if (!IPCSkeleton::IsLocalCalling() || (uid != 0 && uid != SHELL_UID && uid != HIDUMPER_SERVICE_UID)) {
201 ZLOGE(LABEL, "do not allow dump, uid:%{public}u", uid);
202 return ERR_NONE;
203 }
204 return OnRemoteDump(code, data, reply, option);
205 }
206
207 #ifndef CONFIG_IPC_SINGLE
DBinderInvokeListenThread(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)208 int IPCObjectStub::DBinderInvokeListenThread(uint32_t code,
209 MessageParcel &data, MessageParcel &reply, MessageOption &option)
210 {
211 pid_t uid = IPCSkeleton::GetCallingUid();
212 if (!IPCSkeleton::IsLocalCalling() || uid >= ALLOWED_UID) {
213 ZLOGE(LABEL, "INVOKE_LISTEN_THREAD unauthenticated user, desc:%{public}s, uid:%{public}u",
214 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), uid);
215 return IPC_STUB_INVALID_DATA_ERR;
216 }
217 return InvokerThread(code, data, reply, option);
218 }
219
DBinderIncRefsTransaction(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)220 int IPCObjectStub::DBinderIncRefsTransaction(uint32_t code,
221 MessageParcel &data, MessageParcel &reply, MessageOption &option)
222 {
223 if (IPCSkeleton::IsLocalCalling()) {
224 ZLOGE(LABEL, "dbinder incref in the same device is invalid");
225 return IPC_STUB_INVALID_DATA_ERR;
226 }
227 pid_t callerPid = IPCSkeleton::GetCallingPid();
228 pid_t callerUid = IPCSkeleton::GetCallingUid();
229 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
230 std::string callerDevId = IPCSkeleton::GetCallingDeviceID();
231 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
232 uint64_t stubIndex = current->QueryStubIndex(this);
233 DBinderDatabusInvoker *invoker = reinterpret_cast<DBinderDatabusInvoker *>(
234 IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
235 if (invoker == nullptr) {
236 return IPC_STUB_INVALID_DATA_ERR;
237 }
238 int32_t listenFd = invoker->GetClientFd();
239 // update listenFd
240 ZLOGW(LABEL, "update app info, listenFd:%{public}d stubIndex:%{public}" PRIu64 " tokenId:%{public}u",
241 listenFd, stubIndex, tokenId);
242 AppAuthInfo appAuthInfo = { callerPid, callerUid, tokenId, listenFd, stubIndex, nullptr, callerDevId };
243 current->AttachOrUpdateAppAuthInfo(appAuthInfo);
244 return ERR_NONE;
245 }
246
DBinderDecRefsTransaction(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)247 int IPCObjectStub::DBinderDecRefsTransaction(uint32_t code,
248 MessageParcel &data, MessageParcel &reply, MessageOption &option)
249 {
250 if (IPCSkeleton::IsLocalCalling()) {
251 ZLOGE(LABEL, "dbinder decref in the same device is invalid");
252 return IPC_STUB_INVALID_DATA_ERR;
253 }
254 // stub's refcount will be decreased either in this case or OnSessionClosed callback
255 // we may race with OnSessionClosed callback, thus dec refcount only when removing appInfo sucessfully
256 pid_t callerPid = IPCSkeleton::GetCallingPid();
257 pid_t callerUid = IPCSkeleton::GetCallingUid();
258 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
259 std::string callerDevId = IPCSkeleton::GetCallingDeviceID();
260 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
261 uint64_t stubIndex = current->QueryStubIndex(this);
262 DBinderDatabusInvoker *invoker = reinterpret_cast<DBinderDatabusInvoker *>(
263 IPCThreadSkeleton::GetRemoteInvoker(IRemoteObject::IF_PROT_DATABUS));
264 if (invoker == nullptr) {
265 return IPC_STUB_INVALID_DATA_ERR;
266 }
267 int32_t listenFd = invoker->GetClientFd();
268 // detach info whose listen fd equals the given one
269 AppAuthInfo appAuthInfo = { callerPid, callerUid, tokenId, listenFd, stubIndex, this, callerDevId };
270 if (current->DetachAppAuthInfo(appAuthInfo)) {
271 DecStrongRef(this);
272 }
273 return ERR_NONE;
274 }
275
DBinderAddCommAuth(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)276 int IPCObjectStub::DBinderAddCommAuth(uint32_t code,
277 MessageParcel &data, MessageParcel &reply, MessageOption &option)
278 {
279 pid_t uid = IPCSkeleton::GetCallingUid();
280 if (IPCSkeleton::IsLocalCalling() || uid >= ALLOWED_UID) {
281 ZLOGE(LABEL, "DBINDER_ADD_COMMAUTH unauthenticated user, desc:%{public}s, uid:%{public}u",
282 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), uid);
283 return IPC_STUB_INVALID_DATA_ERR;
284 }
285 return AddAuthInfo(data, reply, code);
286 }
287
DBinderGetSessionName(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)288 int IPCObjectStub::DBinderGetSessionName(uint32_t code,
289 MessageParcel &data, MessageParcel &reply, MessageOption &option)
290 {
291 if (!IPCSkeleton::IsLocalCalling()) {
292 ZLOGE(LABEL, "GET_UIDPID_INFO message is not from sa manager");
293 return IPC_STUB_INVALID_DATA_ERR;
294 }
295 std::string sessionName = GetSessionName();
296 if (sessionName.empty()) {
297 ZLOGE(LABEL, "sessionName is empty");
298 return IPC_STUB_CREATE_BUS_SERVER_ERR;
299 }
300 if (!reply.WriteString(sessionName)) {
301 ZLOGE(LABEL, "write to parcel fail");
302 return IPC_STUB_INVALID_DATA_ERR;
303 }
304 return ERR_NONE;
305 }
306
DBinderGetGrantedSessionName(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)307 int IPCObjectStub::DBinderGetGrantedSessionName(uint32_t code,
308 MessageParcel &data, MessageParcel &reply, MessageOption &option)
309 {
310 if (!IPCSkeleton::IsLocalCalling() || !IsSamgrCall()) {
311 ZLOGE(LABEL, "GRANT_DATABUS_NAME message is excluded in sa manager");
312 return IPC_STUB_INVALID_DATA_ERR;
313 }
314 return GetGrantedSessionName(code, data, reply, option);
315 }
316
DBinderGetSessionNameForPidUid(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)317 int IPCObjectStub::DBinderGetSessionNameForPidUid(uint32_t code,
318 MessageParcel &data, MessageParcel &reply, MessageOption &option)
319 {
320 if (!IPCSkeleton::IsLocalCalling() || !IsSamgrCall()) {
321 ZLOGE(LABEL, "TRANS_DATABUS_NAME message is excluded in sa manager");
322 return IPC_STUB_INVALID_DATA_ERR;
323 }
324 return GetSessionNameForPidUid(code, data, reply, option);
325 }
326
DBinderGetPidUid(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)327 int IPCObjectStub::DBinderGetPidUid(uint32_t code,
328 MessageParcel &data, MessageParcel &reply, MessageOption &option)
329 {
330 if (!IPCSkeleton::IsLocalCalling()) {
331 return IPC_STUB_INVALID_DATA_ERR;
332 }
333 return GetPidUid(data, reply);
334 }
335
DBinderRemoveSessionName(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)336 int IPCObjectStub::DBinderRemoveSessionName(uint32_t code,
337 MessageParcel &data, MessageParcel &reply, MessageOption &option)
338 {
339 if (!IPCSkeleton::IsLocalCalling() || !IsSamgrCall()) {
340 ZLOGE(LABEL, "REMOVE_SESSION_NAME message is excluded in sa manager");
341 return IPC_STUB_INVALID_DATA_ERR;
342 }
343 return RemoveSessionName(data);
344 }
345 #endif
346
SendRequestInner(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)347 int IPCObjectStub::SendRequestInner(uint32_t code,
348 MessageParcel &data, MessageParcel &reply, MessageOption &option)
349 {
350 int result = ERR_NONE;
351 std::unique_lock<std::recursive_mutex> lockGuard(serialRecursiveMutex_, std::defer_lock);
352 if (serialInvokeFlag_) {
353 lockGuard.lock();
354 }
355 auto start = std::chrono::steady_clock::now();
356 lastRequestTime_ = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
357 start.time_since_epoch()).count());
358 result = OnRemoteRequest(code, data, reply, option);
359 auto finish = std::chrono::steady_clock::now();
360 uint32_t duration = static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::microseconds>(
361 finish - start).count());
362 if (duration >= IPC_CMD_PROCESS_WARN_TIME) {
363 ZLOGW(LABEL, "stub:%{public}s deal request code:%{public}u cost time:%{public}ums",
364 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(GetObjectDescriptor())).c_str(),
365 code, duration / COEFF_MILLI_TO_MICRO);
366 }
367
368 IPCPayloadStatisticsImpl& instance = IPCPayloadStatisticsImpl::GetInstance();
369 if (instance.GetStatisticsStatus()) {
370 int32_t currentPid = IPCSkeleton::GetCallingPid();
371 std::u16string currentDesc = GetObjectDescriptor();
372 int32_t currentCode = static_cast<int32_t>(code);
373 if (!instance.UpdatePayloadInfo(currentPid, currentDesc, currentCode, duration)) {
374 ZLOGE(LABEL, "Process load information update failed");
375 }
376 }
377 return result;
378 }
379
SendRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)380 int IPCObjectStub::SendRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
381 {
382 switch (code) {
383 case PING_TRANSACTION:
384 return DBinderPingTransaction(code, data, reply, option);
385 case INTERFACE_TRANSACTION:
386 return DBinderSearchDescriptor(code, data, reply, option);
387 case SYNCHRONIZE_REFERENCE:
388 return DBinderSearchRefCount(code, data, reply, option);
389 case DUMP_TRANSACTION:
390 return DBinderDumpTransaction(code, data, reply, option);
391 case GET_PROTO_INFO:
392 return ProcessProto(code, data, reply, option);
393 #ifndef CONFIG_IPC_SINGLE
394 case INVOKE_LISTEN_THREAD:
395 return DBinderInvokeListenThread(code, data, reply, option);
396 case DBINDER_INCREFS_TRANSACTION:
397 return DBinderIncRefsTransaction(code, data, reply, option);
398 case DBINDER_DECREFS_TRANSACTION:
399 return DBinderDecRefsTransaction(code, data, reply, option);
400 case DBINDER_ADD_COMMAUTH:
401 return DBinderAddCommAuth(code, data, reply, option);
402 case GET_SESSION_NAME:
403 return DBinderGetSessionName(code, data, reply, option);
404 case GET_GRANTED_SESSION_NAME:
405 return DBinderGetGrantedSessionName(code, data, reply, option);
406 case GET_SESSION_NAME_PID_UID:
407 return DBinderGetSessionNameForPidUid(code, data, reply, option);
408 case GET_PID_UID:
409 return DBinderGetPidUid(code, data, reply, option);
410 case REMOVE_SESSION_NAME:
411 return DBinderRemoveSessionName(code, data, reply, option);
412 #endif
413 default:
414 return SendRequestInner(code, data, reply, option);
415 }
416 return ERR_NONE;
417 }
418
OnFirstStrongRef(const void * objectId)419 void IPCObjectStub::OnFirstStrongRef(const void *objectId)
420 {
421 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
422
423 if (current != nullptr) {
424 current->AttachObject(this);
425 }
426 }
427
OnLastStrongRef(const void * objectId)428 void IPCObjectStub::OnLastStrongRef(const void *objectId)
429 {
430 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
431
432 if (current != nullptr) {
433 current->DetachObject(this);
434 #ifndef CONFIG_IPC_SINGLE
435 // we only need to erase stub index here, commAuth and appInfo
436 // has already been removed either in dbinder dec refcount case
437 // or OnSessionClosed, we also remove commAuth and appInfo in case of leak
438 uint64_t stubIndex = current->EraseStubIndex(this);
439 current->DetachAppAuthInfoByStub(this, stubIndex);
440 #endif
441 }
442 }
443
AddDeathRecipient(const sptr<DeathRecipient> & recipient)444 bool IPCObjectStub::AddDeathRecipient(const sptr<DeathRecipient> &recipient)
445 {
446 (void)recipient;
447 return false;
448 }
449
RemoveDeathRecipient(const sptr<DeathRecipient> & recipient)450 bool IPCObjectStub::RemoveDeathRecipient(const sptr<DeathRecipient> &recipient)
451 {
452 (void)recipient;
453 return false;
454 }
455
GetCallingPid()456 pid_t IPCObjectStub::GetCallingPid()
457 {
458 return IPCSkeleton::GetCallingPid();
459 }
460
GetCallingUid()461 pid_t IPCObjectStub::GetCallingUid()
462 {
463 return IPCSkeleton::GetCallingUid();
464 }
465
GetCallingTokenID()466 uint32_t IPCObjectStub::GetCallingTokenID()
467 {
468 return IPCSkeleton::GetCallingTokenID();
469 }
470
GetCallingFullTokenID()471 uint64_t IPCObjectStub::GetCallingFullTokenID()
472 {
473 return IPCSkeleton::GetCallingFullTokenID();
474 }
475
GetFirstTokenID()476 uint32_t IPCObjectStub::GetFirstTokenID()
477 {
478 return IPCSkeleton::GetFirstTokenID();
479 }
480
GetFirstFullTokenID()481 uint64_t IPCObjectStub::GetFirstFullTokenID()
482 {
483 return IPCSkeleton::GetFirstFullTokenID();
484 }
485
GetObjectType() const486 int IPCObjectStub::GetObjectType() const
487 {
488 return OBJECT_TYPE_NATIVE;
489 }
490
ProcessProto(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)491 int32_t IPCObjectStub::ProcessProto(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
492 {
493 int result = ERR_NONE;
494 ZLOGD(LABEL, "normal stub object, des:%{public}s",
495 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
496 if (!reply.WriteUint32(IRemoteObject::IF_PROT_BINDER) || !reply.WriteString16(descriptor_)) {
497 ZLOGE(LABEL, "write to parcel fail");
498 result = IPC_STUB_WRITE_PARCEL_ERR;
499 }
500 return result;
501 }
502
GetLastRequestTime()503 uint64_t IPCObjectStub::GetLastRequestTime()
504 {
505 return lastRequestTime_;
506 }
507
508 #ifndef CONFIG_IPC_SINGLE
InvokerThread(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)509 int32_t IPCObjectStub::InvokerThread(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
510 {
511 switch (data.ReadUint32()) {
512 case IRemoteObject::DATABUS_TYPE: {
513 if (InvokerDataBusThread(data, reply) != ERR_NONE) {
514 ZLOGE(LABEL, "Invoker databus thread fail");
515 return IPC_STUB_INVOKE_THREAD_ERR;
516 }
517 break;
518 }
519 default: {
520 ZLOGE(LABEL, "InvokerThread Invalid Type");
521 return IPC_STUB_INVALID_DATA_ERR;
522 }
523 }
524
525 return ERR_NONE;
526 }
527
InvokerDataBusThread(MessageParcel & data,MessageParcel & reply)528 int32_t IPCObjectStub::InvokerDataBusThread(MessageParcel &data, MessageParcel &reply)
529 {
530 ZLOGI(LABEL, "enter");
531 std::string deviceId = data.ReadString();
532 uint32_t remotePid = data.ReadUint32();
533 uint32_t remoteUid = data.ReadUint32();
534 std::string remoteDeviceId = data.ReadString();
535 std::string sessionName = data.ReadString();
536 uint32_t remoteTokenId = data.ReadUint32();
537 if (IsDeviceIdIllegal(deviceId) || IsDeviceIdIllegal(remoteDeviceId) || sessionName.empty()) {
538 ZLOGE(LABEL, "device ID is invalid or session name nil, desc:%{public}s",
539 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
540 return IPC_STUB_INVALID_DATA_ERR;
541 }
542
543 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
544 if (current == nullptr) {
545 ZLOGE(LABEL, "IPCProcessSkeleton is nullptr");
546 return IPC_STUB_CURRENT_NULL_ERR;
547 }
548 if (!current->CreateSoftbusServer(sessionName)) {
549 ZLOGE(LABEL, "fail to create databus server, desc:%{public}s sessionName:%{public}s",
550 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str(), sessionName.c_str());
551 return IPC_STUB_CREATE_BUS_SERVER_ERR;
552 }
553
554 uint64_t stubIndex = current->AddStubByIndex(this);
555 if (stubIndex == 0) {
556 ZLOGE(LABEL, "add stub fail, desc:%{public}s",
557 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
558 return IPC_STUB_INVALID_DATA_ERR;
559 }
560
561 uint32_t selfTokenId = static_cast<uint32_t>(IPCSkeleton::GetSelfTokenID());
562 ZLOGI(LABEL, "invoke databus thread, local deviceId:%{public}s remote deviceId:%{public}s "
563 "stubIndex:%{public}" PRIu64 " sessionName:%{public}s",
564 IPCProcessSkeleton::ConvertToSecureString(deviceId).c_str(),
565 IPCProcessSkeleton::ConvertToSecureString(remoteDeviceId).c_str(), stubIndex, sessionName.c_str());
566 if (!reply.WriteUint64(stubIndex) || !reply.WriteString(sessionName) || !reply.WriteString(deviceId) ||
567 !reply.WriteUint32(selfTokenId)) {
568 ZLOGE(LABEL, "write to parcel fail");
569 return IPC_STUB_INVALID_DATA_ERR;
570 }
571
572 // mark socketId as 0
573 AppAuthInfo appAuthInfo = { remotePid, remoteUid, remoteTokenId, 0, stubIndex, this, remoteDeviceId };
574 if (current->AttachOrUpdateAppAuthInfo(appAuthInfo)) {
575 IncStrongRef(this);
576 }
577 return ERR_NONE;
578 }
579
NoticeServiceDie(MessageParcel & data,MessageParcel & reply,MessageOption & option)580 int32_t IPCObjectStub::NoticeServiceDie(MessageParcel &data, MessageParcel &reply, MessageOption &option)
581 {
582 ZLOGW(LABEL, "enter, desc:%{public}s", ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
583 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
584 if (current == nullptr) {
585 ZLOGE(LABEL, "current is null");
586 return IPC_STUB_CURRENT_NULL_ERR;
587 }
588
589 sptr<IPCObjectProxy> ipcProxy = current->QueryCallbackProxy(this);
590 if (ipcProxy == nullptr) {
591 ZLOGE(LABEL, "ipc proxy is null, desc:%{public}s",
592 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
593 return IPC_STUB_INVALID_DATA_ERR;
594 }
595
596 ipcProxy->SendObituary();
597 return ERR_NONE;
598 }
599
AddAuthInfo(MessageParcel & data,MessageParcel & reply,uint32_t code)600 int32_t IPCObjectStub::AddAuthInfo(MessageParcel &data, MessageParcel &reply, uint32_t code)
601 {
602 uint32_t remotePid = data.ReadUint32();
603 uint32_t remoteUid = data.ReadUint32();
604 std::string remoteDeviceId = data.ReadString();
605 uint64_t stubIndex = data.ReadUint64();
606 uint32_t tokenId = data.ReadUint32();
607 if (IsDeviceIdIllegal(remoteDeviceId)) {
608 ZLOGE(LABEL, "remote deviceId is null, desc:%{public}s",
609 ProcessSkeleton::ConvertToSecureDesc(Str16ToStr8(descriptor_)).c_str());
610 return IPC_STUB_INVALID_DATA_ERR;
611 }
612
613 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
614 if (current == nullptr) {
615 ZLOGE(LABEL, "current is null");
616 return IPC_STUB_CURRENT_NULL_ERR;
617 }
618
619 if (stubIndex == 0) {
620 // keep compatible with proxy that doesn't write stubIndex when adding auth info to stub
621 stubIndex = current->QueryStubIndex(this);
622 if (stubIndex == 0) {
623 ZLOGE(LABEL, "stub index is null");
624 return BINDER_CALLBACK_STUBINDEX_ERR;
625 }
626 }
627 ZLOGW(LABEL, "add auth info, pid:%{public}u uid:%{public}u deviceId:%{public}s "
628 "stubIndex:%{public}" PRIu64 " tokenId:%{public}u", remotePid, remoteUid,
629 IPCProcessSkeleton::ConvertToSecureString(remoteDeviceId).c_str(), stubIndex, tokenId);
630 // mark listen fd as 0
631 AppAuthInfo appAuthInfo = { remotePid, remoteUid, tokenId, 0, stubIndex, this, remoteDeviceId };
632 if (current->AttachOrUpdateAppAuthInfo(appAuthInfo)) {
633 IncStrongRef(this);
634 }
635 return ERR_NONE;
636 }
637
GetSessionName()638 std::string IPCObjectStub::GetSessionName()
639 {
640 ZLOGI(LABEL, "enter");
641 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
642 if (current == nullptr) {
643 ZLOGE(LABEL, "get current is null");
644 return std::string("");
645 }
646 sptr<IRemoteObject> object = current->GetSAMgrObject();
647 if (object == nullptr) {
648 ZLOGE(LABEL, "get object is null");
649 return std::string("");
650 }
651 if (!object->IsProxyObject()) {
652 ZLOGE(LABEL, "object is not a proxy pbject");
653 return std::string("");
654 }
655
656 IPCObjectProxy *samgr = reinterpret_cast<IPCObjectProxy *>(object.GetRefPtr());
657 return samgr->GetGrantedSessionName();
658 }
659
GetGrantedSessionName(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)660 int32_t IPCObjectStub::GetGrantedSessionName(uint32_t code, MessageParcel &data, MessageParcel &reply,
661 MessageOption &option)
662 {
663 ZLOGI(LABEL, "enter");
664 int pid = IPCSkeleton::GetCallingPid();
665 int uid = IPCSkeleton::GetCallingUid();
666 std::string sessionName = CreateSessionName(uid, pid);
667 if (sessionName.empty()) {
668 ZLOGE(LABEL, "pid(%{public}d)/uid(%{public}d) is invalid", pid, uid);
669 return IPC_STUB_INVALID_DATA_ERR;
670 }
671 if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteString(sessionName)) {
672 ZLOGE(LABEL, "write to parcel fail");
673 return IPC_STUB_INVALID_DATA_ERR;
674 }
675
676 return ERR_NONE;
677 }
678
GetSessionNameForPidUid(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)679 int32_t IPCObjectStub::GetSessionNameForPidUid(uint32_t code, MessageParcel &data, MessageParcel &reply,
680 MessageOption &option)
681 {
682 uint32_t remotePid = data.ReadUint32();
683 uint32_t remoteUid = data.ReadUint32();
684 if (remotePid == static_cast<uint32_t>(IPCSkeleton::GetCallingPid())) {
685 ZLOGE(LABEL, "pid(%{public}d)/uid(%{public}d) is invalid", remotePid, remoteUid);
686 return IPC_STUB_INVALID_DATA_ERR;
687 }
688 std::string sessionName = CreateSessionName(remoteUid, remotePid);
689 if (sessionName.empty()) {
690 ZLOGE(LABEL, "pid(%{public}d)/uid(%{public}d) is invalid", remotePid, remoteUid);
691 return IPC_STUB_INVALID_DATA_ERR;
692 }
693 if (!reply.WriteUint32(IRemoteObject::IF_PROT_DATABUS) || !reply.WriteString(sessionName)) {
694 ZLOGE(LABEL, "write to parcel fail");
695 return IPC_STUB_INVALID_DATA_ERR;
696 }
697
698 return ERR_NONE;
699 }
700
GetPidUid(MessageParcel & data,MessageParcel & reply)701 int IPCObjectStub::GetPidUid(MessageParcel &data, MessageParcel &reply)
702 {
703 if (!reply.WriteUint32(getpid()) || !reply.WriteUint32(getuid())) {
704 ZLOGE(LABEL, "write to parcel fail");
705 return IPC_STUB_INVALID_DATA_ERR;
706 }
707 return ERR_NONE;
708 }
709
CreateSessionName(int uid,int pid)710 std::string IPCObjectStub::CreateSessionName(int uid, int pid)
711 {
712 std::string sessionName = DBINDER_SOCKET_NAME_PREFIX +
713 std::to_string(uid) + std::string("_") + std::to_string(pid);
714 if (DBinderSoftbusClient::GetInstance().DBinderGrantPermission(uid, pid, sessionName) != ERR_NONE) {
715 ZLOGE(LABEL, "DBinderGrantPermission fail, %{public}s", sessionName.c_str());
716 return "";
717 }
718
719 return sessionName;
720 }
721
RemoveSessionName(MessageParcel & data)722 int IPCObjectStub::RemoveSessionName(MessageParcel &data)
723 {
724 std::string sessionName = data.ReadString();
725 if (sessionName.empty()) {
726 ZLOGE(LABEL, "read parcel fail");
727 return IPC_STUB_INVALID_DATA_ERR;
728 }
729 if (DBinderSoftbusClient::GetInstance().DBinderRemovePermission(sessionName) != ERR_NONE) {
730 ZLOGE(LABEL, "DBinderRemovePermission fail, %{public}s", sessionName.c_str());
731 return IPC_STUB_REMOVE_SESSION_NAME_ERR;
732 }
733
734 ZLOGI(LABEL, "%{public}s", sessionName.c_str());
735 return ERR_NONE;
736 }
737
IsSamgrCall()738 bool IPCObjectStub::IsSamgrCall()
739 {
740 return ProcessSkeleton::GetInstance()->GetSamgrFlag();
741 }
742 #endif
743
GetRequestSidFlag() const744 bool IPCObjectStub::GetRequestSidFlag() const
745 {
746 return requestSidFlag_;
747 }
748
SetRequestSidFlag(bool flag)749 void IPCObjectStub::SetRequestSidFlag(bool flag)
750 {
751 #ifdef WITH_SELINUX
752 requestSidFlag_ = flag;
753 #endif
754 }
755
GetAndSaveDBinderData(pid_t pid,uid_t uid)756 int IPCObjectStub::GetAndSaveDBinderData(pid_t pid, uid_t uid)
757 {
758 (void)pid;
759 (void)uid;
760 ZLOGW(LABEL, "unexpected call");
761 return ERR_INVALID_STATE;
762 }
763 } // namespace OHOS
764