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