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 "appspawn_permission.h"
16 #ifdef APPSPAWN_CLIENT
17 #include "appspawn_mount_permission.h"
18 #else
19 #include "appspawn_sandbox.h"
20 #endif
21 #include "appspawn_msg.h"
22 #include "appspawn_utils.h"
23 #include "securec.h"
24
PermissionNodeCompareIndex(ListNode * node,void * data)25 static int PermissionNodeCompareIndex(ListNode *node, void *data)
26 {
27 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
28 return permissionNode->permissionIndex - *(int32_t *)data;
29 }
30
PermissionNodeCompareName(ListNode * node,void * data)31 static int PermissionNodeCompareName(ListNode *node, void *data)
32 {
33 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
34 #ifdef APPSPAWN_CLIENT
35 return strcmp(permissionNode->name, (char *)data);
36 #else
37 return strcmp(permissionNode->section.name, (char *)data);
38 #endif
39 }
40
PermissionNodeCompareProc(ListNode * node,ListNode * newNode)41 static int PermissionNodeCompareProc(ListNode *node, ListNode *newNode)
42 {
43 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
44 SandboxPermissionNode *newPermissionNode = (SandboxPermissionNode *)ListEntry(newNode, SandboxMountNode, node);
45 #ifdef APPSPAWN_CLIENT
46 return strcmp(permissionNode->name, newPermissionNode->name);
47 #else
48 return strcmp(permissionNode->section.name, newPermissionNode->section.name);
49 #endif
50 }
51
AddSandboxPermissionNode(const char * name,SandboxQueue * queue)52 int AddSandboxPermissionNode(const char *name, SandboxQueue *queue)
53 {
54 APPSPAWN_CHECK_ONLY_EXPER(name != NULL && queue != NULL, return APPSPAWN_ARG_INVALID);
55 APPSPAWN_LOGV("Add permission name %{public}s ", name);
56 if (GetPermissionNodeInQueue(queue, name) != NULL) {
57 APPSPAWN_LOGW("Permission name %{public}s has been exist", name);
58 return 0;
59 }
60 #ifndef APPSPAWN_CLIENT
61 size_t len = sizeof(SandboxPermissionNode);
62 SandboxPermissionNode *node = (SandboxPermissionNode *)CreateSandboxSection(
63 name, len, SANDBOX_TAG_PERMISSION);
64 APPSPAWN_CHECK(node != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create permission node");
65 node->permissionIndex = 0;
66 OH_ListAddWithOrder(&queue->front, &node->section.sandboxNode.node, PermissionNodeCompareProc);
67 #else
68 size_t len = APPSPAWN_ALIGN(strlen(name) + 1) + sizeof(SandboxPermissionNode);
69 SandboxPermissionNode *node = (SandboxPermissionNode *)calloc(1, len);
70 APPSPAWN_CHECK(node != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create permission node");
71 OH_ListInit(&node->sandboxNode.node);
72 node->permissionIndex = 0;
73 int ret = strcpy_s(node->name, len, name);
74 APPSPAWN_CHECK(ret == 0, free(node);
75 return APPSPAWN_SYSTEM_ERROR, "Failed to copy name");
76 OH_ListAddWithOrder(&queue->front, &node->sandboxNode.node, PermissionNodeCompareProc);
77 #endif
78 return 0;
79 }
80
DeleteSandboxPermissions(SandboxQueue * queue)81 int32_t DeleteSandboxPermissions(SandboxQueue *queue)
82 {
83 APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return APPSPAWN_ARG_INVALID);
84 ListNode *node = queue->front.next;
85 while (node != &queue->front) {
86 SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
87 OH_ListRemove(&sandboxNode->node);
88 OH_ListInit(&sandboxNode->node);
89 #ifndef APPSPAWN_CLIENT
90 DeleteSandboxSection((SandboxSection *)sandboxNode);
91 #else
92 free(sandboxNode);
93 #endif
94 // get first
95 node = queue->front.next;
96 }
97 return 0;
98 }
99
PermissionRenumber(SandboxQueue * queue)100 int32_t PermissionRenumber(SandboxQueue *queue)
101 {
102 APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return -1);
103 ListNode *node = queue->front.next;
104 int index = -1;
105 while (node != &queue->front) {
106 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
107 permissionNode->permissionIndex = ++index;
108 #ifdef APPSPAWN_CLIENT
109 APPSPAWN_LOGV("Permission index %{public}d name %{public}s",
110 permissionNode->permissionIndex, permissionNode->name);
111 #else
112 APPSPAWN_LOGV("Permission index %{public}d name %{public}s",
113 permissionNode->permissionIndex, permissionNode->section.name);
114 #endif
115 node = node->next;
116 }
117 return index + 1;
118 }
119
GetPermissionNodeInQueue(SandboxQueue * queue,const char * permission)120 const SandboxPermissionNode *GetPermissionNodeInQueue(SandboxQueue *queue, const char *permission)
121 {
122 if (queue == NULL || permission == NULL) {
123 return NULL;
124 }
125 ListNode *node = OH_ListFind(&queue->front, (void *)permission, PermissionNodeCompareName);
126 if (node == NULL) {
127 return NULL;
128 }
129 return (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
130 }
131
GetPermissionNodeInQueueByIndex(SandboxQueue * queue,int32_t index)132 const SandboxPermissionNode *GetPermissionNodeInQueueByIndex(SandboxQueue *queue, int32_t index)
133 {
134 if (queue == NULL) {
135 return NULL;
136 }
137 ListNode *node = OH_ListFind(&queue->front, (void *)&index, PermissionNodeCompareIndex);
138 if (node == NULL) {
139 return NULL;
140 }
141 return (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
142 }
143
GetPermissionIndexInQueue(SandboxQueue * queue,const char * permission)144 int32_t GetPermissionIndexInQueue(SandboxQueue *queue, const char *permission)
145 {
146 APPSPAWN_CHECK_ONLY_EXPER(queue != NULL && permission != NULL, return INVALID_PERMISSION_INDEX);
147 const SandboxPermissionNode *permissionNode = GetPermissionNodeInQueue(queue, permission);
148 return permissionNode == NULL ? INVALID_PERMISSION_INDEX : permissionNode->permissionIndex;
149 }