• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2025 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 #ifndef OHOS_IPC_BINDER_INVOKER_H
17 #define OHOS_IPC_BINDER_INVOKER_H
18 
19 #include <atomic>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <unordered_set>
23 #include "ipc_types.h"
24 #include "binder_connector.h"
25 #include "iremote_invoker.h"
26 #include "invoker_factory.h"
27 #include "process_skeleton.h"
28 #include <securec.h>
29 
30 namespace OHOS {
31 
32 /* dfx interface,type is 0 for string */
33 extern "C" uintptr_t DFX_SetCrashObj(uint8_t type, uintptr_t addr);
34 extern "C" void DFX_ResetCrashObj(uintptr_t crashObj);
35 
36 struct CrashObjDumper {
37 public:
CrashObjDumperCrashObjDumper38     explicit CrashObjDumper(const char *str)
39     {
40         if (str == nullptr) {
41             return;
42         }
43         ptr_ = DFX_SetCrashObj(0, reinterpret_cast<uintptr_t>(str));
44     }
~CrashObjDumperCrashObjDumper45     ~CrashObjDumper()
46     {
47         DFX_ResetCrashObj(ptr_);
48     }
49 private:
50     uintptr_t ptr_ = 0;
51 };
52 #ifdef CONFIG_IPC_SINGLE
53 namespace IPC_SINGLE {
54 #endif
55 
56 class BinderInvoker : public IRemoteInvoker {
57 public:
58     class BinderAllocator : public DefaultAllocator {
59         void Dealloc(void *data) override;
60 
61         friend BinderInvoker;
62     };
63 
64     BinderInvoker();
65 
66     ~BinderInvoker();
67 
68     bool AcquireHandle(int32_t handle) override;
69 
70     bool ReleaseHandle(int32_t handle) override;
71 
72     bool PingService(int32_t handle) override;
73 
74     bool AddDeathRecipient(int32_t handle, void *cookie) override;
75 
76     bool RemoveDeathRecipient(int32_t handle, void *cookie) override;
77 
78     bool SetMaxWorkThread(int maxThreadNum) override;
79 
80     void JoinThread(bool initiative) override;
81 
82     void JoinProcessThread(bool initiative) override;
83 
84     void FreeBuffer(void *data) override;
85 
86     void StopWorkThread() override;
87 
88     bool SetRegistryObject(sptr<IRemoteObject> &object) override;
89 
90     int SendRequest(int handle, uint32_t code, MessageParcel &data, MessageParcel &reply,
91         MessageOption &option) override;
92 
93     int SendReply(MessageParcel &reply, uint32_t flags, int32_t result) override;
94 
95     bool FlattenObject(Parcel &parcel, const IRemoteObject *object) const override;
96 
97     sptr<IRemoteObject> UnflattenObject(Parcel &parcel) override;
98 
99     int ReadFileDescriptor(Parcel &parcel) override;
100 
101     bool WriteFileDescriptor(Parcel &parcel, int fd, bool takeOwnership) override;
102 
103     std::string GetCallerSid() const override;
104 
105     pid_t GetCallerPid() const override;
106 
107     pid_t GetCallerRealPid() const override;
108 
109     uid_t GetCallerUid() const override;
110 
111     uint64_t GetCallerTokenID() const override;
112 
113     uint64_t GetFirstCallerTokenID() const override;
114 
115     uint64_t GetSelfTokenID() const override;
116 
117     uint64_t GetSelfFirstCallerTokenID() const override;
118 
119     uint32_t GetStatus() override;
120 
121     bool IsLocalCalling() override;
122 
123     void SetStatus(uint32_t status);
124 
125     std::string GetLocalDeviceID() override;
126 
127     std::string GetCallerDeviceID() const override;
128 
129     int FlushCommands(IRemoteObject *object) override;
130 
131     std::string ResetCallingIdentity() override;
132 
133     bool SetCallingIdentity(std::string &identity, bool flag) override;
134 
135     bool TriggerSystemIPCThreadReclaim() override;
136 
137     bool EnableIPCThreadReclaim(bool enable) override;
138 
139     int32_t GetInvocationState();
140 
141     void ExitCurrentThread();
142 
143     uint32_t GetStrongRefCountForStub(uint32_t handle);
144 
145     bool IsSendRequesting();
146 #ifndef __linux__
147     bool GetDetailedErrorInfo(uint32_t &errorCode, std::string &errorDesc);
148 #endif
149 #ifndef CONFIG_IPC_SINGLE
150     sptr<IRemoteObject> GetSAMgrObject() override;
151 #endif
152 
153 protected:
154     std::atomic<bool> isMainWorkThread;
155     bool stopWorkThread;
156     pid_t callerPid_;
157     pid_t callerRealPid_;
158     pid_t callerUid_;
159     uint64_t callerTokenID_;
160     uint64_t firstTokenID_;
161     std::string callerSid_;
162 
163 private:
164     int TransactWithDriver(bool doRead = true);
165 
166     bool WriteTransaction(int cmd, uint32_t flags, int32_t handle, uint32_t code, const MessageParcel &data,
167         const int *status, size_t totalDBinderBufSize);
168 
169     int WaitForCompletion(MessageParcel *reply = nullptr);
170 
171     void OnAttemptAcquire();
172 
173     void OnRemoveRecipientDone();
174 
175     void StartWorkLoop();
176 
177     void OnBinderDied();
178 
179     void OnAcquireObject(uint32_t cmd);
180 
181     void OnReleaseObject(uint32_t cmd);
182 
183     void Transaction(binder_transaction_data_secctx& trSecctx);
184 
185     void OnTransaction(uint32_t cmd, int32_t &error);
186 
187     void OnSpawnThread();
188 
189     int HandleCommands(uint32_t cmd);
190 
191     int HandleCommandsInner(uint32_t cmd);
192 
193     int HandleReply(MessageParcel *reply, bool &isStubRet);
194 
195     bool TranslateDBinderProxy(int handle, MessageParcel &data);
196 
197     void GetAccessToken(uint64_t &callerTokenID, uint64_t &firstTokenID);
198 
199     void GetSenderInfo(uint64_t &callerTokenID, uint64_t &firstTokenID, pid_t &realPid);
200 
201     void OnTransactionComplete(MessageParcel *reply, bool &continueLoop, int32_t &error, uint32_t cmd);
202 
203     void OnDeadOrFailedReply(MessageParcel *reply, bool &continueLoop, int32_t &error, uint32_t cmd);
204 
205     void OnReply(MessageParcel *reply, bool &continueLoop, int32_t &error, uint32_t cmd);
206 
207     void DealWithCmd(MessageParcel *reply, bool &continueLoop, int32_t &error, uint32_t cmd);
208 
209     int32_t TargetStubSendRequest(const binder_transaction_data &tr,
210         MessageParcel &data, MessageParcel &reply, MessageOption &option, uint32_t &flagValue);
211 
212     int32_t GeneralServiceSendRequest(
213         const binder_transaction_data &tr, MessageParcel &data, MessageParcel &reply, MessageOption &option);
214 
215     int32_t SamgrServiceSendRequest(const binder_transaction_data &tr,
216         MessageParcel &data, MessageParcel &reply, MessageOption &option);
217 
218     void AttachInvokerProcInfoWrapper();
219 
220     void RestoreInvokerProcInfo(const InvokerProcInfo &info);
221 
222     void PrintParcelData(Parcel &parcel, const std::string &parcelName);
223 
224     void UpdateConsumedData(const binder_write_read &bwr, const size_t outAvail);
225 
226     void PrintIdentity(bool isPrint, bool isBefore);
227 
228     void ProcDeferredDecRefs();
229 
230 #ifndef CONFIG_IPC_SINGLE
231     bool AddCommAuth(int32_t handle, flat_binder_object *flat);
232 
233     bool TranslateDBinderStub(int handle, MessageParcel &parcel, bool isReply, size_t &totalDBinderBufSize);
234 
235     bool GetDBinderCallingPidUid(int handle, bool isReply, pid_t &pid, uid_t &uid);
236 
237     bool UnFlattenDBinderObject(Parcel &parcel, dbinder_negotiation_data &dbinderData);
238 #endif
239 
240     bool GetUint64ValueByStrSlice(const std::string &str, size_t offset, size_t length, uint64_t &value);
241     bool GetCallerRealPidByStr(const std::string &str, size_t offset, size_t length, pid_t &callerRealPid);
242     bool GetCallerPidAndUidByStr(const std::string &str, size_t offset, pid_t &pid, pid_t &uid);
243 
244 private:
245     DISALLOW_COPY_AND_MOVE(BinderInvoker);
246     static constexpr int IPC_DEFAULT_PARCEL_SIZE = 256;
247     static constexpr int IPC_CMD_PROCESS_WARN_TIME = 500;
248     static constexpr int ACCESS_TOKEN_MAX_LEN = 20;
249     Parcel input_;
250     Parcel output_;
251     BinderConnector *binderConnector_;
252     uint32_t status_;
253     static inline InvokerDelegator<BinderInvoker> delegator_ = { IRemoteObject::IF_PROT_BINDER };
254     InvokerProcInfo invokerInfo_;
255     std::atomic<int> lastErr_ = 0;
256     std::atomic<int> lastErrCnt_ = 0;
257     std::atomic<int32_t> sendNestCount_ = 0;
258     std::atomic<int32_t> sendRequestCount_ = 0;
259     std::mutex strongRefMutex_;
260     std::vector<IRemoteObject *> decStrongRefs_;
261     std::mutex weakRefMutex_;
262     std::vector<RefCounter *> decWeakRefs_;
263     int32_t isFirstInvoke_ = STATUS_INIT;
264 };
265 #ifdef CONFIG_IPC_SINGLE
266 } // namespace IPC_SINGLE
267 #endif
268 } // namespace OHOS
269 #endif // OHOS_IPC_BINDER_INVOKER_H
270