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 25static int PermissionNodeCompareIndex(ListNode *node, void *data) 26{ 27 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node); 28 return permissionNode->permissionIndex - *(int32_t *)data; 29} 30 31static 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 41static 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 52int 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 81int32_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 100int32_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 120const 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 132const 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 144int32_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}