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_SANDBOX_H
17 #define APPSPAWN_SANDBOX_H
18
19 #include "appspawn.h"
20 #include "appspawn_hook.h"
21 #include "appspawn_manager.h"
22 #include "appspawn_utils.h"
23 #include "list.h"
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29 #define SANDBOX_STAMP_FILE_SUFFIX ".stamp"
30 #define JSON_FLAGS_INTERNAL "__internal__"
31 #define SANDBOX_NWEBSPAWN_ROOT_PATH APPSPAWN_BASE_DIR "/mnt/sandbox/com.ohos.render/"
32 #define OHOS_RENDER "__internal__.com.ohos.render"
33
34 #define PHYSICAL_APP_INSTALL_PATH "/data/app/el1/bundle/public/"
35 #define APL_SYSTEM_CORE "system_core"
36 #define APL_SYSTEM_BASIC "system_basic"
37 #define DEFAULT_NWEB_SANDBOX_SEC_PATH "/data/app/el1/bundle/public/com.ohos.nweb" // persist.nweb.sandbox.src_path
38
39 #define PARAMETER_PACKAGE_NAME "<PackageName>"
40 #define PARAMETER_USER_ID "<currentUserId>"
41 #define PARAMETER_HOST_USER_ID "<hostUserId>"
42 #define PARAMETER_PACKAGE_INDEX "<PackageName_index>"
43 #define ARK_WEB_PERSIST_PACKAGE_NAME "persist.arkwebcore.package_name"
44 #define PARAMETER_ARK_WEB_PACKAGE_INDEX "<arkWebPackageName>"
45 #define SHAREFS_OPTION_USER ",user_id="
46
47 #define FILE_MODE 0711
48 #define MAX_SANDBOX_BUFFER 256
49 #define OPTIONS_MAX_LEN 256
50 #define APP_FLAGS_SECTION 0x80000000
51 #define FILE_MANAGER_GID 1006
52 #define BASIC_MOUNT_FLAGS (MS_REC | MS_BIND)
53 #define INVALID_UID ((uint32_t)-1)
54 #define PARAM_BUFFER_SIZE 128
55
56 #ifdef APPSPAWN_64
57 #define APPSPAWN_LIB_NAME "lib64"
58 #else
59 #define APPSPAWN_LIB_NAME "lib"
60 #endif
61
62 #define MOUNT_MODE_NONE 0 // "none"
63 #define MOUNT_MODE_ALWAYS 1 // "always"
64 #define MOUNT_MODE_NOT_EXIST 2 // "not-exists"
65
66 #define MOUNT_PATH_OP_NONE ((uint32_t)-1)
67 #define MOUNT_PATH_OP_SYMLINK SANDBOX_TAG_INVALID
68 #define MOUNT_PATH_OP_UNMOUNT (SANDBOX_TAG_INVALID + 1)
69 #define MOUNT_PATH_OP_ONLY_SANDBOX (SANDBOX_TAG_INVALID + 2)
70 #define MOUNT_PATH_OP_REPLACE_BY_SANDBOX (SANDBOX_TAG_INVALID + 3)
71 #define MOUNT_PATH_OP_REPLACE_BY_SRC (SANDBOX_TAG_INVALID + 4)
72 #define FILE_CROSS_APP_MODE "ohos.permission.FILE_CROSS_APP"
73 #define FILE_ACCESS_COMMON_DIR_MODE "ohos.permission.FILE_ACCESS_COMMON_DIR"
74 #define ACCESS_DLP_FILE_MODE "ohos.permission.ACCESS_DLP_FILE"
75 #define FILE_ACCESS_MANAGER_MODE "ohos.permission.FILE_ACCESS_MANAGER"
76 #define READ_WRITE_USER_FILE_MODE "ohos.permission.READ_WRITE_USER_FILE"
77 #define GET_ALL_PROCESSES_MODE "ohos.permission.GET_ALL_PROCESSES"
78 #define APP_ALLOW_IOURING "ohos.permission.ALLOW_IOURING"
79
80 typedef enum SandboxTag {
81 SANDBOX_TAG_MOUNT_PATH = 0,
82 SANDBOX_TAG_MOUNT_FILE,
83 SANDBOX_TAG_SYMLINK,
84 SANDBOX_TAG_PERMISSION,
85 SANDBOX_TAG_PACKAGE_NAME,
86 SANDBOX_TAG_SPAWN_FLAGS,
87 SANDBOX_TAG_NAME_GROUP,
88 SANDBOX_TAG_SYSTEM_CONST,
89 SANDBOX_TAG_APP_VARIABLE,
90 SANDBOX_TAG_APP_CONST,
91 SANDBOX_TAG_REQUIRED,
92 SANDBOX_TAG_INVALID
93 } SandboxNodeType;
94
95 typedef enum {
96 SANDBOX_PACKAGENAME_DEFAULT = 0,
97 SANDBOX_PACKAGENAME_CLONE,
98 SANDBOX_PACKAGENAME_EXTENSION,
99 SANDBOX_PACKAGENAME_CLONE_AND_EXTENSION,
100 SANDBOX_PACKAGENAME_ATOMIC_SERVICE,
101 } SandboxVarPackageNameType;
102
103 typedef struct {
104 struct ListNode node;
105 uint32_t type;
106 } SandboxMountNode;
107
108 typedef struct TagSandboxQueue {
109 struct ListNode front;
110 uint32_t type;
111 } SandboxQueue;
112
113 /*
114 "create-on-demand": {
115 "uid": "userId", // 默认使用消息的uid、gid
116 "gid": "groupId",
117 "ugo": 750
118 }
119 */
120 typedef struct {
121 uid_t uid;
122 gid_t gid;
123 uint32_t mode;
124 } PathDemandInfo;
125
126 typedef struct {
127 uint32_t decPathCount; // dec放行目录数量
128 char **decPath; // dec放行目录数组
129 } DecPolicyPaths;
130
131 typedef struct TagPathMountNode {
132 SandboxMountNode sandboxNode;
133 char *source; // source 目录,一般是全局的fs 目录
134 char *target; // 沙盒化后的目录
135 mode_t destMode; // "dest-mode": "S_IRUSR | S_IWOTH | S_IRWXU " 默认值:0
136 uint32_t mountSharedFlag : 1; // "mount-shared-flag" : "true", 默认值:false
137 uint32_t createSandboxPath : 1; // "create-sandbox-path" : "true", 默认值 : true
138 uint32_t createDemand : 1;
139 uint32_t checkErrorFlag : 1;
140 uint32_t category;
141 char *appAplName;
142 PathDemandInfo demandInfo[0];
143 DecPolicyPaths decPolicyPaths;
144 } PathMountNode;
145
146 typedef struct TagSymbolLinkNode {
147 SandboxMountNode sandboxNode;
148 char *target;
149 char *linkName;
150 mode_t destMode; // "dest-mode": "S_IRUSR | S_IWOTH | S_IRWXU "
151 uint32_t checkErrorFlag : 1;
152 } SymbolLinkNode;
153
154 typedef struct TagSandboxSection {
155 SandboxMountNode sandboxNode;
156 struct ListNode front; // mount-path
157 char *name;
158 uint32_t number : 16;
159 uint32_t gidCount : 16;
160 gid_t *gidTable; // "gids": [1006, 1008],
161 uint32_t sandboxSwitch : 1; // "sandbox-switch": "ON",
162 uint32_t sandboxShared : 1; // "sandbox-switch": "ON",
163 SandboxMountNode **nameGroups;
164 } SandboxSection;
165
166 typedef struct {
167 SandboxSection section;
168 } SandboxPackageNameNode;
169
170 typedef struct {
171 SandboxSection section;
172 uint32_t flagIndex;
173 } SandboxFlagsNode;
174
175 typedef struct TagSandboxGroupNode {
176 SandboxSection section;
177 uint32_t destType;
178 PathMountNode *depNode;
179 uint32_t depMode;
180 uint32_t depMounted : 1; // 是否执行了挂载
181 } SandboxNameGroupNode;
182
183 typedef struct TagPermissionNode {
184 SandboxSection section;
185 int32_t permissionIndex;
186 } SandboxPermissionNode;
187
188 typedef struct TagAppSpawnSandboxCfg {
189 AppSpawnExtData extData;
190 SandboxQueue requiredQueue;
191 SandboxQueue permissionQueue;
192 SandboxQueue packageNameQueue; // SandboxSection
193 SandboxQueue spawnFlagsQueue;
194 SandboxQueue nameGroupsQueue;
195 uint32_t depNodeCount;
196 SandboxNameGroupNode **depGroupNodes;
197 int32_t maxPermissionIndex;
198 uint32_t sandboxNsFlags; // "sandbox-ns-flags": [ "pid", "net" ], // for appspawn and newspawn
199 // for comm section
200 uint32_t topSandboxSwitch : 1; // "top-sandbox-switch": "ON",
201 uint32_t appFullMountEnable : 1;
202 uint32_t pidNamespaceSupport : 1;
203 uint32_t mounted : 1;
204 char *rootPath;
205 } AppSpawnSandboxCfg;
206
207 enum {
208 BUFFER_FOR_SOURCE,
209 BUFFER_FOR_TARGET,
210 BUFFER_FOR_TMP,
211 MAX_BUFFER
212 };
213
214 typedef struct TagSandboxBuffer {
215 uint32_t bufferLen;
216 uint32_t current;
217 char *buffer;
218 } SandboxBuffer;
219
220 typedef struct TagSandboxContext {
221 SandboxBuffer buffer[MAX_BUFFER];
222 const char *bundleName;
223 const AppSpawnMsgNode *message; // 修改成操作消息
224 uint32_t sandboxSwitch : 1;
225 uint32_t sandboxShared : 1;
226 uint32_t bundleHasWps : 1;
227 uint32_t dlpBundle : 1;
228 uint32_t appFullMountEnable : 1;
229 uint32_t nwebspawn : 1;
230 uint32_t sandboxNsFlags;
231 char *rootPath;
232 } SandboxContext;
233
234 typedef struct {
235 const char *sandboxPath;
236 const char *permission;
237 } MountSharedTemplate;
238
239 /**
240 * @brief AppSpawnSandboxCfg op
241 *
242 * @return AppSpawnSandboxCfg*
243 */
244 AppSpawnSandboxCfg *CreateAppSpawnSandbox(ExtDataType type);
245 AppSpawnSandboxCfg *GetAppSpawnSandbox(const AppSpawnMgr *content, ExtDataType type);
246 void DeleteAppSpawnSandbox(AppSpawnSandboxCfg *sandbox);
247 int LoadAppSandboxConfig(AppSpawnSandboxCfg *sandbox, ExtDataType type);
248 void DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox);
249
250 /**
251 * @brief Init sandbox context
252 *
253 */
254 int InitSandboxContext(SandboxContext *context, const AppSpawnSandboxCfg *sandbox,
255 const AppSpawningCtx *property, int nwebspawn);
256
257 /**
258 * @brief SandboxSection op
259 *
260 */
261 SandboxSection *CreateSandboxSection(const char *name, uint32_t dataLen, uint32_t type);
262 SandboxSection *GetSandboxSection(const SandboxQueue *queue, const char *name);
263 void AddSandboxSection(SandboxSection *node, SandboxQueue *queue);
264 void DeleteSandboxSection(SandboxSection *node);
GetSectionType(const SandboxSection * section)265 __attribute__((always_inline)) inline uint32_t GetSectionType(const SandboxSection *section)
266 {
267 return section != NULL ? section->sandboxNode.type : SANDBOX_TAG_INVALID;
268 }
269
270 /**
271 * @brief SandboxMountNode op
272 *
273 */
274 SandboxMountNode *CreateSandboxMountNode(uint32_t dataLen, uint32_t type);
275 SandboxMountNode *GetFirstSandboxMountNode(const SandboxSection *section);
276 void DeleteSandboxMountNode(SandboxMountNode *mountNode);
277 void AddSandboxMountNode(SandboxMountNode *node, SandboxSection *section);
278 PathMountNode *GetPathMountNode(const SandboxSection *section, int type, const char *source, const char *target);
279 SymbolLinkNode *GetSymbolLinkNode(const SandboxSection *section, const char *target, const char *linkName);
280
SetMountPathOperation(uint32_t * operation,uint32_t index)281 __attribute__((always_inline)) inline void SetMountPathOperation(uint32_t *operation, uint32_t index)
282 {
283 *operation |= (1 << index);
284 }
285
286 /**
287 * @brief sandbox mount interface
288 *
289 */
290 int MountSandboxConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox,
291 const SandboxSection *section, uint32_t op);
292 int MountSandboxConfigs(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn);
293 int StagedMountSystemConst(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn);
294 int StagedMountPreUnShare(const SandboxContext *context, AppSpawnSandboxCfg *sandbox);
295 int StagedMountPostUnshare(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox);
296 // 在子进程退出时,由父进程发起unmount操作
297 int UnmountDepPaths(const AppSpawnSandboxCfg *sandbox, uid_t uid);
298 int UnmountSandboxConfigs(const AppSpawnSandboxCfg *sandbox, uid_t uid, const char *name);
299
300 /**
301 * @brief Variable op
302 *
303 */
304 typedef struct {
305 struct ListNode node;
306 ReplaceVarHandler replaceVar;
307 char name[0];
308 } AppSandboxVarNode;
309
310 typedef struct TagVarExtraData {
311 uint32_t sandboxTag;
312 uint32_t operation;
313 char *variablePackageName;
314 union {
315 PathMountNode *depNode;
316 } data;
317 } VarExtraData;
318
319 void ClearVariable(void);
320 void AddDefaultVariable(void);
321 const char *GetSandboxRealVar(const SandboxContext *context, uint32_t bufferType, const char *source,
322 const char *prefix, const VarExtraData *extraData);
323
324 /**
325 * @brief expand config
326 *
327 */
328 typedef struct {
329 struct ListNode node;
330 ProcessExpandSandboxCfg cfgHandle;
331 int prio;
332 char name[0];
333 } AppSandboxExpandAppCfgNode;
334 int ProcessExpandAppSandboxConfig(const SandboxContext *context,
335 const AppSpawnSandboxCfg *appSandbox, const char *name);
336 void AddDefaultExpandAppSandboxConfigHandle(void);
337 void ClearExpandAppSandboxConfigHandle(void);
338
GetSandboxCtxMsgInfo(const SandboxContext * context,uint32_t type)339 __attribute__((always_inline)) inline void *GetSandboxCtxMsgInfo(const SandboxContext *context, uint32_t type)
340 {
341 APPSPAWN_CHECK(context->message != NULL,
342 return NULL, "Invalid property for type %{public}u", type);
343 return GetAppSpawnMsgInfo(context->message, type);
344 }
345
CheckSandboxCtxMsgFlagSet(const SandboxContext * context,uint32_t index)346 __attribute__((always_inline)) inline bool CheckSandboxCtxMsgFlagSet(const SandboxContext *context, uint32_t index)
347 {
348 APPSPAWN_CHECK(context->message != NULL, return false, "Invalid property for type %{public}d", TLV_MSG_FLAGS);
349 return CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, index);
350 }
351
CheckSandboxCtxPermissionFlagSet(const SandboxContext * context,uint32_t index)352 __attribute__((always_inline)) inline bool CheckSandboxCtxPermissionFlagSet(
353 const SandboxContext *context, uint32_t index)
354 {
355 APPSPAWN_CHECK(context != NULL && context->message != NULL,
356 return false, "Invalid property for type %{public}d", TLV_PERMISSION);
357 return CheckAppSpawnMsgFlag(context->message, TLV_PERMISSION, index);
358 }
359
360 /**
361 * @brief Sandbox Context op
362 *
363 * @return SandboxContext*
364 */
365 SandboxContext *GetSandboxContext(void);
366 void DeleteSandboxContext(SandboxContext **context);
367
368 /**
369 * @brief defineMount Arg Template and operation
370 *
371 */
372 enum {
373 MOUNT_TMP_DEFAULT,
374 MOUNT_TMP_RDONLY,
375 MOUNT_TMP_EPFS,
376 MOUNT_TMP_DAC_OVERRIDE_DELETE,
377 MOUNT_TMP_DAC_OVERRIDE,
378 MOUNT_TMP_FUSE,
379 MOUNT_TMP_DLP_FUSE,
380 MOUNT_TMP_SHRED,
381 MOUNT_TMP_MAX
382 };
383
384 typedef struct {
385 char *name;
386 uint32_t category;
387 const char *fsType;
388 unsigned long mountFlags;
389 const char *options;
390 mode_t mountSharedFlag;
391 } MountArgTemplate;
392
393 typedef struct {
394 const char *name;
395 unsigned long flags;
396 } SandboxFlagInfo;
397
398 uint32_t GetMountCategory(const char *name);
399 const MountArgTemplate *GetMountArgTemplate(uint32_t category);
400 const SandboxFlagInfo *GetSandboxFlagInfo(const char *key, const SandboxFlagInfo *flagsInfos, uint32_t count);
401 int GetPathMode(const char *name);
402
403 void DumpMountPathMountNode(const PathMountNode *pathNode);
404
405 typedef struct TagMountArg {
406 const char *originPath;
407 const char *destinationPath;
408 const char *fsType;
409 unsigned long mountFlags;
410 const char *options;
411 mode_t mountSharedFlag;
412 } MountArg;
413
414 int SandboxMountPath(const MountArg *arg);
415
IsPathEmpty(const char * path)416 __attribute__((always_inline)) inline int IsPathEmpty(const char *path)
417 {
418 if (path == NULL || path[0] == '\0') {
419 return 1;
420 }
421 return 0;
422 }
423
CheckPath(const char * name)424 __attribute__((always_inline)) inline bool CheckPath(const char *name)
425 {
426 return name != NULL && strcmp(name, ".") != 0 && strcmp(name, "..") != 0 && strstr(name, "/") == NULL;
427 }
428
429 #ifdef __cplusplus
430 }
431 #endif
432 #endif // APPSPAWN_SANDBOX_H
433