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