1 /*
2 * Copyright (c) 2024 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 APPSPAWN_MANAGER_H
17 #define APPSPAWN_MANAGER_H
18
19 #include <limits.h>
20 #include <stdbool.h>
21 #include <unistd.h>
22
23 #include "appspawn.h"
24 #include "appspawn_hook.h"
25 #include "appspawn_msg.h"
26 #include "appspawn_server.h"
27 #include "appspawn_utils.h"
28 #include "list.h"
29 #include "loop_event.h"
30 #ifdef APPSPAWN_HISYSEVENT
31 #include "hisysevent_adapter.h"
32 #endif
33
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37
38 #define MODE_ID_INDEX 1
39 #define MODE_VALUE_INDEX 2
40 #define FD_ID_INDEX 3
41 #define FD_VALUE_INDEX 4
42 #define FLAGS_VALUE_INDEX 5
43 #define SHM_SIZE_INDEX 6
44 #define PARAM_ID_INDEX 7
45 #define PARAM_VALUE_INDEX 8
46 #define CLIENT_ID_INDEX 9
47 #define ARG_NULL 10
48
49 #define MAX_DIED_PROCESS_COUNT 5
50
51 #define INVALID_OFFSET 0xffffffff
52
53 #define APP_STATE_IDLE 1
54 #define APP_STATE_SPAWNING 2
55 #define APPSPAWN_MAX_TIME 3000000
56 #define UUID_MAX_LEN 37
57 #define PATH_MAX_LEN 256
58
59 #define APPSPAWN_INLINE __attribute__((always_inline)) inline
60
61 typedef struct AppSpawnContent AppSpawnContent;
62 typedef struct AppSpawnClient AppSpawnClient;
63 typedef struct TagAppSpawnConnection AppSpawnConnection;
64
65 typedef struct TagAppSpawnMsgNode {
66 AppSpawnConnection *connection;
67 AppSpawnMsg msgHeader;
68 uint32_t tlvCount;
69 uint32_t *tlvOffset; // 记录属性的在msg中的偏移,不完全拷贝试消息完整
70 uint8_t *buffer;
71 } AppSpawnMsgNode;
72
73 typedef struct {
74 int32_t fd[2]; // 2 fd count
75 WatcherHandle watcherHandle;
76 WatcherHandle pidFdWatcherHandle;
77 TimerHandle timer;
78 char *childMsg;
79 uint32_t msgSize;
80 char *coldRunPath;
81 } AppSpawnForkCtx;
82
83 typedef struct TagAppSpawningCtx {
84 AppSpawnClient client;
85 struct ListNode node;
86 AppSpawnForkCtx forkCtx;
87 AppSpawnMsgNode *message;
88 bool isPrefork;
89 pid_t pid;
90 int state;
91 struct timespec spawnStart;
92 } AppSpawningCtx;
93
94 typedef struct TagAppSpawnedProcess {
95 struct ListNode node;
96 uid_t uid;
97 pid_t pid;
98 uint32_t max;
99 int exitStatus;
100 struct timespec spawnStart;
101 struct timespec spawnEnd;
102 #ifdef DEBUG_BEGETCTL_BOOT
103 AppSpawnMsgNode *message;
104 #endif
105 bool isDebuggable;
106 char name[0];
107 } AppSpawnedProcess;
108
109 typedef struct SpawnTime {
110 int minAppspawnTime;
111 int maxAppspawnTime;
112 } SpawnTime;
113
114 #ifndef APPSPAWN_SANDBOX_NEW
115 typedef struct TagPathBuffer {
116 uint32_t pathLen;
117 char path[PATH_MAX_LEN];
118 } PathBuffer;
119
120 typedef struct TagDataGroupCtx {
121 struct ListNode node;
122 int gid;
123 char dataGroupUuid[UUID_MAX_LEN];
124 PathBuffer srcPath;
125 PathBuffer destPath;
126 } DataGroupCtx;
127 #endif
128
129 typedef struct TagAppSpawnMgr {
130 AppSpawnContent content;
131 TaskHandle server;
132 SignalHandle sigHandler;
133 pid_t servicePid;
134 struct ListNode appQueue; // save app pid and name
135 uint32_t diedAppCount;
136 uint32_t flags;
137 struct ListNode diedQueue; // save app pid and name
138 struct ListNode appSpawnQueue; // save app pid and name
139 struct timespec perLoadStart;
140 struct timespec perLoadEnd;
141 struct ListNode extData;
142 struct SpawnTime spawnTime;
143 #ifndef APPSPAWN_SANDBOX_NEW
144 struct ListNode dataGroupCtxQueue;
145 #endif
146 #ifdef APPSPAWN_HISYSEVENT
147 AppSpawnHisyseventInfo *hisyseventInfo;
148 #endif
149 } AppSpawnMgr;
150
151 /**
152 * @brief App Spawn Mgr object op
153 *
154 */
155 AppSpawnMgr *CreateAppSpawnMgr(int mode);
156 AppSpawnMgr *GetAppSpawnMgr(void);
157 void DeleteAppSpawnMgr(AppSpawnMgr *mgr);
158 AppSpawnContent *GetAppSpawnContent(void);
159
160 /**
161 * @brief 孵化成功后进程或者app实例的操作
162 *
163 */
164 typedef void (*AppTraversal)(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data);
165 void TraversalSpawnedProcess(AppTraversal traversal, void *data);
166 AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName, bool isDebuggable);
167 AppSpawnedProcess *GetSpawnedProcess(pid_t pid);
168 AppSpawnedProcess *GetSpawnedProcessByName(const char *name);
169 void TerminateSpawnedProcess(AppSpawnedProcess *node);
170
171 /**
172 * @brief 孵化过程中的ctx对象的操作
173 *
174 */
175 typedef void (*ProcessTraversal)(const AppSpawnMgr *mgr, AppSpawningCtx *ctx, void *data);
176 void AppSpawningCtxTraversal(ProcessTraversal traversal, void *data);
177 AppSpawningCtx *GetAppSpawningCtxByPid(pid_t pid);
178 AppSpawningCtx *CreateAppSpawningCtx();
179 void DeleteAppSpawningCtx(AppSpawningCtx *property);
180 int KillAndWaitStatus(pid_t pid, int sig, int *exitStatus);
181
182 /**
183 * @brief 消息解析、处理
184 *
185 */
186 void ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message);
187 int ProcessTerminationStatusMsg(const AppSpawnMsgNode *message, AppSpawnResult *result);
188
189 AppSpawnMsgNode *CreateAppSpawnMsg(void);
190 void DeleteAppSpawnMsg(AppSpawnMsgNode **msgNode);
191 int CheckAppSpawnMsg(const AppSpawnMsgNode *message);
192 int DecodeAppSpawnMsg(AppSpawnMsgNode *message);
193 int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
194 AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder);
195 AppSpawnMsgNode *RebuildAppSpawnMsgNode(AppSpawnMsgNode *message, AppSpawnedProcess *appInfo);
196
197 /**
198 * @brief 消息内容操作接口
199 *
200 */
201 void DumpAppSpawnMsg(const AppSpawnMsgNode *message);
202 void *GetAppSpawnMsgInfo(const AppSpawnMsgNode *message, int type);
203 void *GetAppSpawnMsgExtInfo(const AppSpawnMsgNode *message, const char *name, uint32_t *len);
204 int CheckAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index);
205 int SetAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index);
206
IsSpawnServer(const AppSpawnMgr * content)207 APPSPAWN_INLINE int IsSpawnServer(const AppSpawnMgr *content)
208 {
209 return (content != NULL) && (content->servicePid == getpid());
210 }
211
IsAppSpawnMode(const AppSpawnMgr * content)212 APPSPAWN_INLINE int IsAppSpawnMode(const AppSpawnMgr *content)
213 {
214 return (content != NULL) &&
215 (content->content.mode == MODE_FOR_APP_SPAWN || content->content.mode == MODE_FOR_APP_COLD_RUN);
216 }
217
IsNWebSpawnMode(const AppSpawnMgr * content)218 APPSPAWN_INLINE int IsNWebSpawnMode(const AppSpawnMgr *content)
219 {
220 return (content != NULL) &&
221 (content->content.mode == MODE_FOR_NWEB_SPAWN || content->content.mode == MODE_FOR_NWEB_COLD_RUN);
222 }
223
IsNativeSpawnMode(const AppSpawnMgr * content)224 APPSPAWN_INLINE int IsNativeSpawnMode(const AppSpawnMgr *content)
225 {
226 return (content != NULL) &&
227 (content->content.mode == MODE_FOR_NATIVE_SPAWN);
228 }
229
IsColdRunMode(const AppSpawnMgr * content)230 APPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content)
231 {
232 return (content != NULL) &&
233 (content->content.mode == MODE_FOR_APP_COLD_RUN || content->content.mode == MODE_FOR_NWEB_COLD_RUN);
234 }
235
IsDeveloperModeOn(const AppSpawningCtx * property)236 APPSPAWN_INLINE int IsDeveloperModeOn(const AppSpawningCtx *property)
237 {
238 return (property != NULL && ((property->client.flags & APP_DEVELOPER_MODE) == APP_DEVELOPER_MODE));
239 }
240
IsJitFortModeOn(const AppSpawningCtx * property)241 APPSPAWN_INLINE int IsJitFortModeOn(const AppSpawningCtx *property)
242 {
243 return (property != NULL && ((property->client.flags & APP_JITFORT_MODE) == APP_JITFORT_MODE));
244 }
245
GetAppSpawnMsgType(const AppSpawningCtx * appProperty)246 APPSPAWN_INLINE int GetAppSpawnMsgType(const AppSpawningCtx *appProperty)
247 {
248 return (appProperty != NULL && appProperty->message != NULL) ?
249 appProperty->message->msgHeader.msgType : MAX_TYPE_INVALID;
250 }
251
GetProcessName(const AppSpawningCtx * property)252 APPSPAWN_INLINE const char *GetProcessName(const AppSpawningCtx *property)
253 {
254 if (property == NULL || property->message == NULL) {
255 return NULL;
256 }
257 return property->message->msgHeader.processName;
258 }
259
GetBundleName(const AppSpawningCtx * property)260 APPSPAWN_INLINE const char *GetBundleName(const AppSpawningCtx *property)
261 {
262 if (property == NULL || property->message == NULL) {
263 return NULL;
264 }
265 AppSpawnMsgBundleInfo *info = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(property->message, TLV_BUNDLE_INFO);
266 if (info != NULL) {
267 return info->bundleName;
268 }
269 return NULL;
270 }
271
GetAppProperty(const AppSpawningCtx * property,uint32_t type)272 APPSPAWN_INLINE void *GetAppProperty(const AppSpawningCtx *property, uint32_t type)
273 {
274 APPSPAWN_CHECK(property != NULL && property->message != NULL,
275 return NULL, "Invalid property for type %{public}u", type);
276 return GetAppSpawnMsgInfo(property->message, type);
277 }
278
GetAppPropertyExt(const AppSpawningCtx * property,const char * name,uint32_t * len)279 APPSPAWN_INLINE void *GetAppPropertyExt(const AppSpawningCtx *property, const char *name, uint32_t *len)
280 {
281 APPSPAWN_CHECK(name != NULL, return NULL, "Invalid name ");
282 APPSPAWN_CHECK(property != NULL && property->message != NULL,
283 return NULL, "Invalid property for name %{public}s", name);
284 return GetAppSpawnMsgExtInfo(property->message, name, len);
285 }
286
CheckAppMsgFlagsSet(const AppSpawningCtx * property,uint32_t index)287 APPSPAWN_INLINE int CheckAppMsgFlagsSet(const AppSpawningCtx *property, uint32_t index)
288 {
289 APPSPAWN_CHECK(property != NULL && property->message != NULL,
290 return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS);
291 return CheckAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, index);
292 }
293
CheckAppPermissionFlagSet(const AppSpawningCtx * property,uint32_t index)294 APPSPAWN_INLINE int CheckAppPermissionFlagSet(const AppSpawningCtx *property, uint32_t index)
295 {
296 APPSPAWN_CHECK(property != NULL && property->message != NULL,
297 return 0, "Invalid property for name %{public}u", TLV_PERMISSION);
298 return CheckAppSpawnMsgFlag(property->message, TLV_PERMISSION, index);
299 }
300
SetAppPermissionFlags(const AppSpawningCtx * property,uint32_t index)301 APPSPAWN_INLINE int SetAppPermissionFlags(const AppSpawningCtx *property, uint32_t index)
302 {
303 APPSPAWN_CHECK(property != NULL && property->message != NULL,
304 return -1, "Invalid property for name %{public}u", TLV_PERMISSION);
305 return SetAppSpawnMsgFlag(property->message, TLV_PERMISSION, index);
306 }
307
IsIsolatedNativeSpawnMode(const AppSpawnMgr * content,const AppSpawningCtx * property)308 APPSPAWN_INLINE int IsIsolatedNativeSpawnMode(const AppSpawnMgr *content, const AppSpawningCtx *property)
309 {
310 return (content != NULL) && (content->content.mode == MODE_FOR_NATIVE_SPAWN) &&
311 CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE);
312 }
313
314 #ifdef __cplusplus
315 }
316 #endif
317 #endif // APPSPAWN_MANAGER_H
318