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_skeleton.h"
17
18 #include <cstdint>
19 #include <sys/types.h>
20
21 #include "access_token_adapter.h"
22 #include "iosfwd"
23 #include "ipc_process_skeleton.h"
24 #include "ipc_thread_skeleton.h"
25 #include "ipc_types.h"
26 #include "iremote_invoker.h"
27 #include "iremote_object.h"
28 #include "refbase.h"
29 #include "selinux/selinux.h"
30 #include "string"
31 #include "unistd.h"
32 #ifdef FFRT_IPC_ENABLE
33 #include "c/ffrt_ipc.h"
34 #endif
35
36 namespace OHOS {
37 #ifdef CONFIG_IPC_SINGLE
38 using namespace IPC_SINGLE;
39 #endif
40
GetSid()41 static std::string GetSid()
42 {
43 char *con = nullptr;
44 int ret = getcon(&con);
45 if (ret < 0) {
46 return "";
47 }
48 std::string context = con;
49 freecon(con);
50 return context;
51 }
52
JoinWorkThread()53 void IPCSkeleton::JoinWorkThread()
54 {
55 IPCThreadSkeleton *current = IPCThreadSkeleton::GetCurrent();
56 if (current != nullptr) {
57 current->JoinWorkThread(IRemoteObject::IF_PROT_DEFAULT);
58 }
59 }
60
StopWorkThread()61 void IPCSkeleton::StopWorkThread()
62 {
63 IPCThreadSkeleton *current = IPCThreadSkeleton::GetCurrent();
64 if (current != nullptr) {
65 current->StopWorkThread(IRemoteObject::IF_PROT_DEFAULT);
66 }
67 }
68
SetContextObject(sptr<IRemoteObject> & object)69 bool IPCSkeleton::SetContextObject(sptr<IRemoteObject> &object)
70 {
71 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
72 if (current != nullptr) {
73 return current->SetRegistryObject(object);
74 }
75 return false;
76 }
77
GetContextObject()78 sptr<IRemoteObject> IPCSkeleton::GetContextObject()
79 {
80 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
81 if (current != nullptr) {
82 return current->GetRegistryObject();
83 }
84 return nullptr;
85 }
86
SetMaxWorkThreadNum(int maxThreadNum)87 bool IPCSkeleton::SetMaxWorkThreadNum(int maxThreadNum)
88 {
89 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
90 if (current != nullptr) {
91 // first thread have started at IPCProcessSkeleton instances
92 return current->SetMaxWorkThread(maxThreadNum);
93 }
94 return false;
95 }
96
GetCallingSid()97 std::string IPCSkeleton::GetCallingSid()
98 {
99 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
100 if (invoker != nullptr) {
101 return invoker->GetCallerSid();
102 }
103 return GetSid();
104 }
105
GetCallingPid()106 pid_t IPCSkeleton::GetCallingPid()
107 {
108 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
109 if (invoker != nullptr) {
110 return invoker->GetCallerPid();
111 }
112 return getpid();
113 }
114
GetCallingRealPid()115 pid_t IPCSkeleton::GetCallingRealPid()
116 {
117 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
118 if (invoker != nullptr) {
119 return invoker->GetCallerRealPid();
120 }
121 return getprocpid();
122 }
123
GetCallingUid()124 pid_t IPCSkeleton::GetCallingUid()
125 {
126 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
127 if (invoker != nullptr) {
128 return invoker->GetCallerUid();
129 }
130 return getuid();
131 }
132
GetCallingTokenID()133 uint32_t IPCSkeleton::GetCallingTokenID()
134 {
135 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
136 if (invoker != nullptr) {
137 return static_cast<uint32_t>(invoker->GetCallerTokenID());
138 }
139 return static_cast<uint32_t>(GetSelfTokenID());
140 }
141
GetCallingFullTokenID()142 uint64_t IPCSkeleton::GetCallingFullTokenID()
143 {
144 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
145 if (invoker != nullptr) {
146 return invoker->GetCallerTokenID();
147 }
148 return GetSelfTokenID();
149 }
150
GetSelfTokenID()151 uint64_t IPCSkeleton::GetSelfTokenID()
152 {
153 IRemoteInvoker *invoker = IPCThreadSkeleton::GetDefaultInvoker();
154 if (invoker != nullptr) {
155 return invoker->GetSelfTokenID();
156 }
157 return 0;
158 }
159
GetFirstTokenID()160 uint32_t IPCSkeleton::GetFirstTokenID()
161 {
162 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
163 if (invoker != nullptr) {
164 return static_cast<uint32_t>(invoker->GetFirstCallerTokenID());
165 }
166 invoker = IPCThreadSkeleton::GetDefaultInvoker();
167 if (invoker != nullptr) {
168 return static_cast<uint32_t>(invoker->GetSelfFirstCallerTokenID());
169 }
170 return 0;
171 }
172
GetFirstFullTokenID()173 uint64_t IPCSkeleton::GetFirstFullTokenID()
174 {
175 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
176 if (invoker != nullptr) {
177 return invoker->GetFirstCallerTokenID();
178 }
179 invoker = IPCThreadSkeleton::GetDefaultInvoker();
180 if (invoker != nullptr) {
181 return invoker->GetSelfFirstCallerTokenID();
182 }
183 return 0;
184 }
185
GetLocalDeviceID()186 std::string IPCSkeleton::GetLocalDeviceID()
187 {
188 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
189 if (invoker != nullptr) {
190 return invoker->GetLocalDeviceID();
191 }
192 return "";
193 }
194
GetCallingDeviceID()195 std::string IPCSkeleton::GetCallingDeviceID()
196 {
197 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
198 if (invoker != nullptr) {
199 return invoker->GetCallerDeviceID();
200 }
201 return "";
202 }
203
GetInstance()204 IPCSkeleton &IPCSkeleton::GetInstance()
205 {
206 static IPCSkeleton skeleton;
207 return skeleton;
208 }
209
IsLocalCalling()210 bool IPCSkeleton::IsLocalCalling()
211 {
212 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
213 if (invoker != nullptr) {
214 return invoker->IsLocalCalling();
215 }
216 return true;
217 }
218
FlushCommands(IRemoteObject * object)219 int IPCSkeleton::FlushCommands(IRemoteObject *object)
220 {
221 IRemoteInvoker *invoker = IPCThreadSkeleton::GetProxyInvoker(object);
222 if (invoker == nullptr) {
223 return IPC_SKELETON_NULL_OBJECT_ERR;
224 }
225
226 #ifdef FFRT_IPC_ENABLE
227 IPCObjectProxy *proxy = reinterpret_cast<IPCObjectProxy *>(object);
228 bool isBinderInvoker = (proxy->GetProto() == IRemoteObject::IF_PROT_BINDER);
229 if (isBinderInvoker) {
230 ffrt_this_task_set_legacy_mode(true);
231 }
232 #endif
233 int ret = invoker->FlushCommands(object);
234 #ifdef FFRT_IPC_ENABLE
235 if (isBinderInvoker) {
236 ffrt_this_task_set_legacy_mode(false);
237 }
238 #endif
239 return ret;
240 }
241
ResetCallingIdentity()242 std::string IPCSkeleton::ResetCallingIdentity()
243 {
244 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
245 if (invoker != nullptr) {
246 return invoker->ResetCallingIdentity();
247 }
248 return "";
249 }
250
SetCallingIdentity(std::string & identity,bool flag)251 bool IPCSkeleton::SetCallingIdentity(std::string &identity, bool flag)
252 {
253 IRemoteInvoker *invoker = IPCThreadSkeleton::GetActiveInvoker();
254 if (invoker != nullptr) {
255 return invoker->SetCallingIdentity(identity, flag);
256 }
257
258 return true;
259 }
260
BlockUntilThreadAvailable()261 void IPCDfx::BlockUntilThreadAvailable()
262 {
263 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
264 if (current != nullptr) {
265 current->BlockUntilThreadAvailable();
266 }
267 }
268
SetIPCProxyLimit(uint64_t num,IPCProxyLimitCallback callback)269 bool IPCDfx::SetIPCProxyLimit(uint64_t num, IPCProxyLimitCallback callback)
270 {
271 IPCProcessSkeleton *current = IPCProcessSkeleton::GetCurrent();
272 if (current != nullptr) {
273 return current->SetIPCProxyLimit(num, callback);
274 }
275 return false;
276 }
277 } // namespace OHOS
278