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