• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <pthread.h>
16 #include <stdlib.h>
17 
18 #ifndef APPSPAWN_CLIENT
19 #include "appspawn_sandbox.h"
20 #endif
21 #include "appspawn_client.h"
22 #include "appspawn_mount_permission.h"
23 #include "appspawn_msg.h"
24 #include "appspawn_permission.h"
25 #include "appspawn_utils.h"
26 #include "json_utils.h"
27 #include "securec.h"
28 
29 typedef struct TagParseJsonContext {
30     SandboxQueue permissionQueue;
31     int32_t maxPermissionIndex;
32     uint32_t inited;
33     AppSpawnClientType type;
34 } ParseJsonContext, PermissionManager;
35 
36 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
37 static PermissionManager g_permissionMgr[CLIENT_MAX] = {};
38 
39 #ifdef APPSPAWN_SANDBOX_NEW
ParseAppSandboxConfig(const cJSON * root,PermissionManager * mgr)40 static int ParseAppSandboxConfig(const cJSON *root, PermissionManager *mgr)
41 {
42     // conditional
43     cJSON *json = cJSON_GetObjectItemCaseSensitive(root, "conditional");
44     APPSPAWN_CHECK(json != NULL, return 0, "No found conditional in config");
45 
46     // permission
47     cJSON *config = cJSON_GetObjectItemCaseSensitive(json, "permission");
48     APPSPAWN_CHECK(config != NULL && cJSON_IsArray(config), return 0, "No found permission in config");
49 
50     uint32_t configSize = cJSON_GetArraySize(config);
51     for (uint32_t i = 0; i < configSize; i++) {
52         json = cJSON_GetArrayItem(config, i);
53         char *name = GetStringFromJsonObj(json, "name");
54         APPSPAWN_CHECK(name != NULL, break, "No found name in config");
55 
56         int ret = AddSandboxPermissionNode(name, &mgr->permissionQueue);
57         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
58     }
59     return 0;
60 }
61 
GetPermissionMgrByType(AppSpawnClientType type)62 static PermissionManager *GetPermissionMgrByType(AppSpawnClientType type)
63 {
64     APPSPAWN_CHECK_ONLY_EXPER(type < CLIENT_MAX, return NULL);
65     g_permissionMgr[type].type = type;
66     return &g_permissionMgr[type];
67 }
68 #else
69 
ParsePermissionConfig(const cJSON * permissionConfigs,PermissionManager * mgr)70 static int ParsePermissionConfig(const cJSON *permissionConfigs, PermissionManager *mgr)
71 {
72     cJSON *config = NULL;
73     cJSON_ArrayForEach(config, permissionConfigs)
74     {
75         const char *name = config->string;
76         int ret = AddSandboxPermissionNode(name, &mgr->permissionQueue);
77         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
78     }
79     return 0;
80 }
81 
ParseAppSandboxConfig(const cJSON * appSandboxConfig,PermissionManager * mgr)82 static int ParseAppSandboxConfig(const cJSON *appSandboxConfig, PermissionManager *mgr)
83 {
84     cJSON *configs = cJSON_GetObjectItemCaseSensitive(appSandboxConfig, "permission");
85     APPSPAWN_CHECK(configs != NULL && cJSON_IsArray(configs), return 0, "No permission in json");
86 
87     int ret = 0;
88     uint32_t configSize = (uint32_t)cJSON_GetArraySize(configs);
89     for (uint32_t i = 0; i < configSize; i++) {
90         cJSON *json = cJSON_GetArrayItem(configs, i);
91         ret = ParsePermissionConfig(json, mgr);
92         APPSPAWN_CHECK(ret == 0, return ret, "Parse permission config fail result: %{public}d ", ret);
93     }
94     return ret;
95 }
96 
GetPermissionMgrByType(AppSpawnClientType type)97 static PermissionManager *GetPermissionMgrByType(AppSpawnClientType type)
98 {
99     APPSPAWN_CHECK_ONLY_EXPER(type < CLIENT_MAX, return NULL);
100     g_permissionMgr[0].type = CLIENT_FOR_APPSPAWN;
101     return &g_permissionMgr[0];
102 }
103 #endif
104 
LoadPermissionConfig(PermissionManager * mgr)105 static int LoadPermissionConfig(PermissionManager *mgr)
106 {
107     (void)ParseJsonConfig("etc/sandbox",
108                           mgr->type == CLIENT_FOR_APPSPAWN ? APP_SANDBOX_FILE_NAME : RENDER_SANDBOX_FILE_NAME,
109                           ParseAppSandboxConfig, mgr);
110     size_t count = sizeof(g_spawnerPermissionList) / sizeof(g_spawnerPermissionList[0]);
111     for (size_t i = 0; i < count; i++) {
112         AddSandboxPermissionNode(g_spawnerPermissionList[i], &mgr->permissionQueue);
113     }
114     mgr->maxPermissionIndex = PermissionRenumber(&mgr->permissionQueue);
115     return 0;
116 }
117 
CheckPermissionManager(PermissionManager * mgr)118 static inline int32_t CheckPermissionManager(PermissionManager *mgr)
119 {
120     if (mgr != NULL && mgr->inited) {
121         return 1;
122     }
123     return 0;
124 }
125 
PMGetPermissionIndex(AppSpawnClientType type,const char * permission)126 static int32_t PMGetPermissionIndex(AppSpawnClientType type, const char *permission)
127 {
128     PermissionManager *mgr = GetPermissionMgrByType(type);
129     APPSPAWN_CHECK_ONLY_EXPER(CheckPermissionManager(mgr), return INVALID_PERMISSION_INDEX);
130     return GetPermissionIndexInQueue((SandboxQueue *)&mgr->permissionQueue, permission);
131 }
132 
PMGetMaxPermissionIndex(AppSpawnClientType type)133 static int32_t PMGetMaxPermissionIndex(AppSpawnClientType type)
134 {
135     PermissionManager *mgr = GetPermissionMgrByType(type);
136     APPSPAWN_CHECK_ONLY_EXPER(CheckPermissionManager(mgr), return INVALID_PERMISSION_INDEX);
137     return mgr->maxPermissionIndex;
138 }
139 
PMGetPermissionByIndex(AppSpawnClientType type,int32_t index)140 static const char *PMGetPermissionByIndex(AppSpawnClientType type, int32_t index)
141 {
142     PermissionManager *mgr = GetPermissionMgrByType(type);
143     APPSPAWN_CHECK_ONLY_EXPER(CheckPermissionManager(mgr), return NULL);
144     if (mgr->maxPermissionIndex <= index) {
145         return NULL;
146     }
147     const SandboxPermissionNode *node = GetPermissionNodeInQueueByIndex((SandboxQueue *)&mgr->permissionQueue, index);
148     return PERMISSION_NAME(node);
149 }
150 
LoadPermission(AppSpawnClientType type)151 APPSPAWN_STATIC int LoadPermission(AppSpawnClientType type)
152 {
153     APPSPAWN_LOGW("LoadPermission %{public}d", type);
154     pthread_mutex_lock(&g_mutex);
155     PermissionManager *mgr = GetPermissionMgrByType(type);
156     if (mgr == NULL) {
157         pthread_mutex_unlock(&g_mutex);
158         return APPSPAWN_ARG_INVALID;
159     }
160 
161     if (mgr->inited) {
162         pthread_mutex_unlock(&g_mutex);
163         return 0;
164     }
165     mgr->maxPermissionIndex = -1;
166     mgr->permissionQueue.type = 0;
167     OH_ListInit(&mgr->permissionQueue.front);
168     int ret = LoadPermissionConfig(mgr);
169     if (ret == 0) {
170         mgr->inited = 1;
171     }
172     pthread_mutex_unlock(&g_mutex);
173     return ret;
174 }
175 
DeletePermission(AppSpawnClientType type)176 APPSPAWN_STATIC void DeletePermission(AppSpawnClientType type)
177 {
178     pthread_mutex_lock(&g_mutex);
179     PermissionManager *mgr = GetPermissionMgrByType(type);
180     if (mgr == NULL || !mgr->inited) {
181         pthread_mutex_unlock(&g_mutex);
182         return;
183     }
184     DeleteSandboxPermissions(&mgr->permissionQueue);
185     mgr->maxPermissionIndex = -1;
186     mgr->inited = 0;
187     pthread_mutex_unlock(&g_mutex);
188 }
189 
GetPermissionMaxCount()190 int32_t GetPermissionMaxCount()
191 {
192     int32_t maxCount = 0;
193     for (uint32_t i = 0; i < CLIENT_MAX; i++) {
194         int32_t max = PMGetMaxPermissionIndex(i);
195         if (max > maxCount) {
196             maxCount = max;
197         }
198     }
199     return maxCount;
200 }
201 
GetPermissionIndex(AppSpawnClientHandle handle,const char * permission)202 int32_t GetPermissionIndex(AppSpawnClientHandle handle, const char *permission)
203 {
204     APPSPAWN_CHECK(permission != NULL, return INVALID_PERMISSION_INDEX, "Invalid permission name");
205     if (handle == NULL) {
206         return PMGetPermissionIndex(CLIENT_FOR_APPSPAWN, permission);
207     }
208     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
209     return PMGetPermissionIndex(reqMgr->type, permission);
210 }
211 
GetMaxPermissionIndex(AppSpawnClientHandle handle)212 int32_t GetMaxPermissionIndex(AppSpawnClientHandle handle)
213 {
214     if (handle == NULL) {
215         return PMGetMaxPermissionIndex(CLIENT_FOR_APPSPAWN);
216     }
217     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
218     return PMGetMaxPermissionIndex(reqMgr->type);
219 }
220 
GetPermissionByIndex(AppSpawnClientHandle handle,int32_t index)221 const char *GetPermissionByIndex(AppSpawnClientHandle handle, int32_t index)
222 {
223     if (handle == NULL) {
224         return PMGetPermissionByIndex(CLIENT_FOR_APPSPAWN, index);
225     }
226     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
227     return PMGetPermissionByIndex(reqMgr->type, index);
228 }
229 
LoadPermissionModule(void)230 __attribute__((constructor)) static void LoadPermissionModule(void)
231 {
232     (void)LoadPermission(CLIENT_FOR_APPSPAWN);
233     (void)LoadPermission(CLIENT_FOR_NWEBSPAWN);
234 }
235 
DeletePermissionModule(void)236 __attribute__((destructor)) static void DeletePermissionModule(void)
237 {
238     DeletePermission(CLIENT_FOR_APPSPAWN);
239     DeletePermission(CLIENT_FOR_NWEBSPAWN);
240 }