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 }