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