From 624e6a655ba0bd172b2f667581a54a9cadd02239 Mon Sep 17 00:00:00 2001 From: wang-kang0512 Date: Fri, 11 Jul 2025 16:22:10 +0800 Subject: [PATCH] SEND ENCAPS TO KERNEL Signed-off-by: wang-kang0512 --- modules/common/appspawn_encaps.c | 396 ++++++----- modules/common/appspawn_encaps.h | 58 ++ test/mock/app_spawn_stub.h | 12 +- .../app_spawn_common_test.cpp | 632 ++++++++++++++++-- 4 files changed, 877 insertions(+), 221 deletions(-) create mode 100644 modules/common/appspawn_encaps.h diff --git a/modules/common/appspawn_encaps.c b/modules/common/appspawn_encaps.c index 3236e976..6d492d80 100644 --- a/modules/common/appspawn_encaps.c +++ b/modules/common/appspawn_encaps.c @@ -25,45 +25,44 @@ #include "appspawn_hook.h" #include "appspawn_manager.h" #include "appspawn_utils.h" +#include "appspawn_encaps.h" #define APP_ENCAPS "encaps" #define APP_OHOS_ENCAPS_COUNT_KEY "ohos.encaps.count" #define APP_OHOS_ENCAPS_FORK_KEY "ohos.encaps.fork.count" +#define APP_OHOS_ENCAPS_PERMISSIONS_KEY "permissions" #define MSG_EXT_NAME_MAX_DECIMAL 10 #define OH_APP_MAX_PIDS_NUM 512 #define OH_ENCAPS_PROC_TYPE_BASE 0x18 -#define OH_ENCAPS_PERMISSION_TYPE_BASE 0x1A +#define OH_ENCAPS_PERMISSION_TYPE_BASE 0x1E #define OH_ENCAPS_MAGIC 'E' #define OH_PROC_HAP 4 #define OH_ENCAPS_DEFAULT_FLAG 0 #define OH_ENCAPS_DEFAULT_STR "" +// permission value max len is 512 +#define OH_ENCAPS_VALUE_MAX_LEN 512 +// encapsCount max count is 64 +#define OH_ENCAPS_MAX_COUNT 64 #define SET_ENCAPS_PROC_TYPE_CMD _IOW(OH_ENCAPS_MAGIC, OH_ENCAPS_PROC_TYPE_BASE, uint32_t) -#define SET_ENCAPS_PERMISSION_TYPE_CMD _IOW(OH_ENCAPS_MAGIC, OH_ENCAPS_PERMISSION_TYPE_BASE, char *) +#define SET_ENCAPS_PERMISSION_TYPE_CMD _IOW(OH_ENCAPS_MAGIC, OH_ENCAPS_PERMISSION_TYPE_BASE, UserEncaps) -typedef enum { - ENCAPS_PROC_TYPE_MODE, // enable the encaps attribute of a process - ENCAPS_PERMISSION_TYPE_MODE, // set the encaps permission of a process - ENCAPS_MAX_TYPE_MODE -} AppSpawnEncapsBaseType; - -static int OpenEncapsFile(void) +APPSPAWN_STATIC int OpenEncapsFile(void) { int fd = 0; - fd = open("dev/encaps", O_RDWR); + fd = open("/dev/encaps", O_RDWR); if (fd < 0) { APPSPAWN_LOGW("Failed to open encaps file errno: %{public}d", errno); } return fd; } -static int WriteEncapsInfo(int fd, AppSpawnEncapsBaseType encapsType, const char *encapsInfo, uint32_t flag) +APPSPAWN_STATIC int WriteEncapsInfo(int fd, AppSpawnEncapsBaseType encapsType, const void *encapsInfo, uint32_t flag) { if (encapsInfo == NULL) { return APPSPAWN_ARG_INVALID; } - APPSPAWN_LOGV("root object: %{public}s", encapsInfo); int ret = 0; switch (encapsType) { @@ -74,10 +73,11 @@ static int WriteEncapsInfo(int fd, AppSpawnEncapsBaseType encapsType, const char ret = ioctl(fd, SET_ENCAPS_PERMISSION_TYPE_CMD, encapsInfo); break; default: + ret = APPSPAWN_ARG_INVALID; break; } if (ret != 0) { - APPSPAWN_LOGE("Encaps the setup failed ret: %{public}d fd: %{public}d maxPid: %{public}s", ret, fd, encapsInfo); + APPSPAWN_LOGE("Encaps the setup failed ret: %{public}d fd: %{public}d", ret, fd); return ret; } return 0; @@ -89,7 +89,7 @@ APPSPAWN_STATIC int EnableEncapsForProc(int encapsFileFd) return WriteEncapsInfo(encapsFileFd, ENCAPS_PROC_TYPE_MODE, OH_ENCAPS_DEFAULT_STR, flag); } -static uint32_t SpawnGetMaxPids(AppSpawnMgr *content, AppSpawningCtx *property) +APPSPAWN_STATIC uint32_t SpawnGetMaxPids(AppSpawningCtx *property) { uint32_t len = 0; char *pidMaxStr = GetAppPropertyExt(property, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, &len); @@ -108,26 +108,6 @@ static uint32_t SpawnGetMaxPids(AppSpawnMgr *content, AppSpawningCtx *property) return 0; } -/* set ohos.encaps.fork.count to encaps */ -static int SpawnSetMaxPids(AppSpawnMgr *content, AppSpawningCtx *property, cJSON *encaps) -{ - uint32_t maxPidCount = 0; - if (GetAppSpawnMsgType(property) != MSG_SPAWN_NATIVE_PROCESS) { - maxPidCount = SpawnGetMaxPids(content, property); - } - if (maxPidCount == 0 || maxPidCount > OH_APP_MAX_PIDS_NUM) { - APPSPAWN_LOGV("Don't need to set pid max count. Use default pid max"); - return APPSPAWN_PIDMGR_DEFAULT_PID_MAX; - } - - if (cJSON_AddNumberToObject(encaps, APP_OHOS_ENCAPS_FORK_KEY, maxPidCount) == NULL) { - APPSPAWN_LOGV("Add number to object failed.(ignore)"); - return APPSPAWN_PIDMGR_DEFAULT_PID_MAX; - } - - return 0; -} - static inline cJSON *GetJsonObjFromExtInfo(const AppSpawningCtx *property, const char *name) { uint32_t size = 0; @@ -141,196 +121,266 @@ static inline cJSON *GetJsonObjFromExtInfo(const AppSpawningCtx *property, const return extInfoJson; } -APPSPAWN_STATIC int AddPermissionArrayToItem(cJSON *encaps, const char *key, cJSON *permissionItemArr) +APPSPAWN_STATIC int AddPermissionStrToValue(const char *valueStr, UserEncap *encap) { - cJSON *arrayItem = permissionItemArr->child; - cJSON *newArray = cJSON_CreateArray(); - if (newArray == NULL) { - return APPSPAWN_ERROR_UTILS_CREATE_JSON_FAIL; + APPSPAWN_CHECK(valueStr != NULL, return APPSPAWN_ARG_INVALID, "Invalid string value"); + uint32_t valueLen = strlen(valueStr) + 1; + APPSPAWN_CHECK(valueLen > 1 && valueLen <= OH_ENCAPS_VALUE_MAX_LEN, return APPSPAWN_ARG_INVALID, + "String value len is invalied, len: %{public}u", valueLen); + char *value = (char *)calloc(1, valueLen); + APPSPAWN_CHECK(value != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to calloc value"); + + int ret = strcpy_s(value, valueLen, valueStr); + APPSPAWN_CHECK(ret == EOK, free(value); + return APPSPAWN_SYSTEM_ERROR, "Failed to copy string value"); + + encap->value.ptrValue = (void *)value; + encap->valueLen = valueLen; + encap->type = ENCAPS_CHAR_ARRAY; + return 0; +} + +APPSPAWN_STATIC int AddPermissionIntArrayToValue(cJSON *arrayItem, UserEncap *encap, int arraySize) +{ + uint32_t valueLen = sizeof(int) * arraySize; + APPSPAWN_CHECK(valueLen <= OH_ENCAPS_VALUE_MAX_LEN, return APPSPAWN_ARG_INVALID, + "Int array len too long, len: %{public}u", valueLen); + int *value = (int *)calloc(1, valueLen); + APPSPAWN_CHECK(value != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to calloc int array value"); + + cJSON *arrayItemTemp = arrayItem; + for (int index = 0; index < arraySize; index++) { + if (arrayItemTemp == NULL || !cJSON_IsNumber(arrayItemTemp)) { + free(value); + APPSPAWN_LOGE("Invalid int array item type"); + return APPSPAWN_ARG_INVALID; + } + value[index] = arrayItemTemp->valueint; + arrayItemTemp = arrayItemTemp->next; } - if (!cJSON_AddItemToObject(encaps, key, newArray)) { - cJSON_Delete(newArray); - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; + encap->value.ptrValue = (void *)value; + encap->valueLen = valueLen; + encap->type = ENCAPS_INT_ARRAY; + return 0; +} + +APPSPAWN_STATIC int AddPermissionBoolArrayToValue(cJSON *arrayItem, UserEncap *encap, int arraySize) +{ + uint32_t valueLen = sizeof(bool) * arraySize; + APPSPAWN_CHECK(valueLen <= OH_ENCAPS_VALUE_MAX_LEN, return APPSPAWN_ARG_INVALID, + "Bool array len too long, len: %{public}u", valueLen); + bool *value = (bool *)calloc(1, valueLen); + APPSPAWN_CHECK(value != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to calloc bool array value"); + + cJSON *arrayItemTemp = arrayItem; + for (int index = 0; index < arraySize; index++) { + if (arrayItemTemp == NULL || !cJSON_IsBool(arrayItemTemp)) { + free(value); + APPSPAWN_LOGE("Invalid bool array item type"); + return APPSPAWN_ARG_INVALID; + } + value[index] = cJSON_IsTrue(arrayItemTemp) ? true : false; + arrayItemTemp = arrayItemTemp->next; } + encap->value.ptrValue = (void *)value; + encap->valueLen = valueLen; + encap->type = ENCAPS_BOOL_ARRAY; + return 0; +} - while (arrayItem) { - cJSON *newItem = NULL; - if (cJSON_IsNumber(arrayItem)) { - newItem = cJSON_CreateNumber(arrayItem->valueint); - } else if (cJSON_IsString(arrayItem)) { - newItem = cJSON_CreateString(arrayItem->valuestring); - } else if (cJSON_IsBool(arrayItem)) { - newItem = cJSON_CreateBool(arrayItem->valueint); +APPSPAWN_STATIC int AddPermissionStrArrayToValue(cJSON *arrayItem, UserEncap *encap) +{ + uint32_t valueLen = 0; + for (cJSON *arrayItemTemp = arrayItem; arrayItemTemp != NULL; arrayItemTemp = arrayItemTemp->next) { + if (!cJSON_IsString(arrayItemTemp) || arrayItemTemp->valuestring == NULL) { + APPSPAWN_LOGE("Invalid string array item type"); + return APPSPAWN_ARG_INVALID; } + uint32_t tempLen = strlen(arrayItemTemp->valuestring); + APPSPAWN_CHECK(tempLen > 0, return APPSPAWN_ARG_INVALID, "String array value is invalied"); + valueLen += tempLen + 1; + } + + APPSPAWN_CHECK(valueLen > 0 && valueLen <= OH_ENCAPS_VALUE_MAX_LEN, return APPSPAWN_ARG_INVALID, + "String array len is invalied, len: %{public}u", valueLen); + char *value = (char *)calloc(1, valueLen); + APPSPAWN_CHECK(value != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to calloc string array value"); + + char *valuePtr = value; + for (cJSON *arrayItemTemp = arrayItem; arrayItemTemp != NULL; arrayItemTemp = arrayItemTemp->next) { + int len = strlen(arrayItemTemp->valuestring) + 1; + int ret = strcpy_s(valuePtr, len, arrayItemTemp->valuestring); + APPSPAWN_CHECK(ret == EOK, free(value); + return APPSPAWN_SYSTEM_ERROR, "Failed to copy string value"); + valuePtr += len; + } + encap->value.ptrValue = (void *)value; + encap->valueLen = valueLen; + encap->type = ENCAPS_CHAR_ARRAY; + return 0; +} - if (newItem == NULL || !cJSON_AddItemToArray(newArray, newItem)) { - cJSON_Delete(newItem); - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; +APPSPAWN_STATIC int AddPermissionArrayToValue(cJSON *permissionItemArr, UserEncap *encap) +{ + int arraySize = cJSON_GetArraySize(permissionItemArr); + if (arraySize == 0) { + return APPSPAWN_ARG_INVALID; + } + + // check first item type + cJSON *arrayItem = permissionItemArr->child; + if (cJSON_IsNumber(arrayItem)) { + if (AddPermissionIntArrayToValue(arrayItem, encap, arraySize) != 0) { + return APPSPAWN_ARG_INVALID; + } + } else if (cJSON_IsString(arrayItem)) { + if (AddPermissionStrArrayToValue(arrayItem, encap) != 0) { + return APPSPAWN_ARG_INVALID; + } + } else if (cJSON_IsBool(arrayItem)) { + if (AddPermissionBoolArrayToValue(arrayItem, encap, arraySize) != 0) { + return APPSPAWN_ARG_INVALID; } - arrayItem = arrayItem->next; + } else { + APPSPAWN_LOGW("Invalid array item type"); + return APPSPAWN_ARG_INVALID; } return 0; } -APPSPAWN_STATIC int AddPermissionItemToEncaps(cJSON *encaps, cJSON *permissionItem) +APPSPAWN_STATIC int AddPermissionItemToEncapsInfo(UserEncap *encap, cJSON *permissionItem) { - const char *key = permissionItem->string; + // copy json key + char *key = permissionItem->string; + if (key == NULL || strcpy_s(encap->key, OH_ENCAPS_KEY_MAX_LEN, key) != EOK) { + APPSPAWN_LOGE("Failed to copy json key"); + return APPSPAWN_SYSTEM_ERROR; + } + if (cJSON_IsNumber(permissionItem)) { - if (!cJSON_AddNumberToObject(encaps, key, permissionItem->valueint)) { - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; - } - } else if (cJSON_IsString(permissionItem)) { - if (!cJSON_AddStringToObject(encaps, key, permissionItem->valuestring)) { - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; - } + encap->type = ENCAPS_INT; + encap->value.intValue = (uint64_t)permissionItem->valueint; + encap->valueLen = sizeof(permissionItem->valueint); } else if (cJSON_IsBool(permissionItem)) { - if (!cJSON_AddBoolToObject(encaps, key, permissionItem->valueint)) { - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; + encap->type = ENCAPS_BOOL; + bool value = cJSON_IsTrue(permissionItem) ? true : false; + encap->value.intValue = (uint64_t)value; + encap->valueLen = sizeof(value); + } else if (cJSON_IsString(permissionItem)) { + if (AddPermissionStrToValue(permissionItem->valuestring, encap) != 0) { + return APPSPAWN_ARG_INVALID; } - } else if (cJSON_IsArray(permissionItem)) { - if (AddPermissionArrayToItem(encaps, key, permissionItem) != 0) { - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; + } else if (cJSON_IsArray(permissionItem)) { + if (AddPermissionArrayToValue(permissionItem, encap) != 0) { + return APPSPAWN_ARG_INVALID; } + } else { + APPSPAWN_LOGW("Invalid permission item type"); + return APPSPAWN_ARG_INVALID; } return 0; } -APPSPAWN_STATIC int AddPermissionToEncaps(cJSON *extInfoJson, cJSON *encaps, uint32_t *permissionCount) +APPSPAWN_STATIC int AddMembersToEncapsInfo(cJSON *extInfoJson, UserEncaps *encapsInfo) { // Get ohos.encaps.count - cJSON *countJson = cJSON_GetObjectItem(extInfoJson, "ohos.encaps.count"); - int encapsCount = 0; - if (cJSON_IsNumber(countJson)) { - encapsCount = countJson->valueint; - } + cJSON *countJson = cJSON_GetObjectItem(extInfoJson, APP_OHOS_ENCAPS_COUNT_KEY); + APPSPAWN_CHECK(countJson != NULL && cJSON_IsNumber(countJson), return APPSPAWN_ARG_INVALID, "Invalid countJson"); + int encapsCount = countJson->valueint; // Check input count and permissions size - cJSON *permissions = cJSON_GetObjectItemCaseSensitive(extInfoJson, "permissions"); - int count = cJSON_GetArraySize(permissions); - if (encapsCount != count) { - APPSPAWN_LOGE("Invalid args, encaps count: %{public}d, permission count: %{public}d", encapsCount, count); - return APPSPAWN_ARG_INVALID; - } + cJSON *permissionsJson = cJSON_GetObjectItemCaseSensitive(extInfoJson, APP_OHOS_ENCAPS_PERMISSIONS_KEY); + APPSPAWN_CHECK(permissionsJson != NULL && cJSON_IsArray(permissionsJson), return APPSPAWN_ARG_INVALID, + "Invalid permissionsJson"); + int count = cJSON_GetArraySize(permissionsJson); + APPSPAWN_CHECK(count > 0 && count <= OH_ENCAPS_MAX_COUNT && encapsCount == count, return APPSPAWN_ARG_INVALID, + "Invalid args, encaps count: %{public}d, permission count: %{public}d", encapsCount, count); + + encapsInfo->encap = (UserEncap *)calloc(count + 1, sizeof(UserEncap)); + APPSPAWN_CHECK(encapsInfo->encap != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to calloc encap"); - // If permissionName and permissionValue are obtained, they need to be written - // in the {"permissionName1":"permissionValue1", "permissionName2":"permissionValue2", ...} in the encaps. for (int i = 0; i < count; i++) { - // get single permission, such as {"permissionName1":"permissionValue1"} - cJSON *permission = cJSON_GetArrayItem(permissions, i); - if (permission == NULL) { - APPSPAWN_LOGE("encaps get single permission failed."); - return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL; - } + cJSON *permission = cJSON_GetArrayItem(permissionsJson, i); + APPSPAWN_CHECK(permission != NULL, return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL, + "Encaps get single permission failed") - // only one object in {}. So we only need to get first object. - // such as key:"permissionName1", value:"permissionValue1" cJSON *permissionItem = permission->child; - if (permissionItem == NULL) { - APPSPAWN_LOGE("encaps get permission item failed."); - return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL; - } + APPSPAWN_CHECK(permissionItem != NULL, return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL, + "Encaps get permission item failed") - if (AddPermissionItemToEncaps(encaps, permissionItem) != 0) { - APPSPAWN_LOGV("Add permission to object failed.(ignore)"); + if (AddPermissionItemToEncapsInfo(&encapsInfo->encap[i], permissionItem) != 0) { + APPSPAWN_LOGE("Add permission to encap failed"); return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; } + encapsInfo->encapsCount++; } - *permissionCount += count; return 0; } -static int SpawnSetPermissions(AppSpawnMgr *content, AppSpawningCtx *property, cJSON *encaps, uint32_t *count) +APPSPAWN_STATIC void FreeEncapsInfo(UserEncaps *encapsInfo) { - cJSON *extInfoJson = GetJsonObjFromExtInfo(property, MSG_EXT_NAME_JIT_PERMISSIONS); - if (extInfoJson == NULL) { - return APPSPAWN_ARG_INVALID; - } - - int ret = AddPermissionToEncaps(extInfoJson, encaps, count); - if (ret != 0) { - APPSPAWN_LOGW("Add permission to object failed.(ignore), ret: %{public}d", ret); + APPSPAWN_CHECK_ONLY_EXPER(encapsInfo != NULL, return); + + if (encapsInfo->encap != NULL) { + for (uint32_t i = 0; i < encapsInfo->encapsCount; i++) { + if (encapsInfo->encap[i].type > ENCAPS_AS_ARRAY) { + free(encapsInfo->encap[i].value.ptrValue); + encapsInfo->encap[i].value.ptrValue = NULL; + } + } + free(encapsInfo->encap); + encapsInfo->encap = NULL; } - - cJSON_Delete(extInfoJson); - return ret; } -static int AddMembersToEncaps(AppSpawnMgr *content, AppSpawningCtx *property, cJSON *encaps) +/* set ohos.encaps.fork.count to encaps */ +static int SpawnSetMaxPids(AppSpawningCtx *property, UserEncaps *encapsInfo) { - uint32_t encapsPermissionCount = 0; - // need set ohos.encaps.count to encaps firstly - if (cJSON_AddNumberToObject(encaps, APP_OHOS_ENCAPS_COUNT_KEY, encapsPermissionCount) == NULL) { - APPSPAWN_LOGV("Set ohos.encaps.count to object failed.(ignore)"); - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; - } - - int ret = SpawnSetMaxPids(content, property, encaps); - if (ret != 0) { - APPSPAWN_LOGV("Can't set max pids to encaps object.(ignore), ret: %{public}d", ret); - } else { - encapsPermissionCount += 1; - } - - uint32_t count = 0; - ret = SpawnSetPermissions(content, property, encaps, &count); - if (ret != 0) { - APPSPAWN_LOGV("Can't set JIT permission to encaps object.(ignore), ret: %{public}d", ret); - } else { - encapsPermissionCount += count; + uint32_t maxPidCount = 0; + if (GetAppSpawnMsgType(property) != MSG_SPAWN_NATIVE_PROCESS) { + maxPidCount = SpawnGetMaxPids(property); } - if (encapsPermissionCount == 0) { - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; // Don't need set permission - } + APPSPAWN_CHECK(maxPidCount > 0 && maxPidCount < OH_APP_MAX_PIDS_NUM, return 0, + "Don't need to set pid max count %{public}u. Use default pid max", maxPidCount); + APPSPAWN_CHECK(encapsInfo->encapsCount < OH_ENCAPS_MAX_COUNT, + return APPSPAWN_ARG_INVALID, "Encaps count is more than 64, cannot set permissions"); - cJSON *encapsCountItem = cJSON_GetObjectItem(encaps, APP_OHOS_ENCAPS_COUNT_KEY); - if (encapsCountItem != NULL) { - cJSON_SetNumberValue(encapsCountItem, encapsPermissionCount); - } + int count = encapsInfo->encapsCount; + int ret = strcpy_s(encapsInfo->encap[count].key, OH_ENCAPS_KEY_MAX_LEN, APP_OHOS_ENCAPS_FORK_KEY); + APPSPAWN_CHECK_ONLY_EXPER(ret == EOK, return APPSPAWN_SYSTEM_ERROR); + encapsInfo->encap[count].value.intValue = (uint64_t)maxPidCount; + encapsInfo->encap[count].valueLen = sizeof(maxPidCount); + encapsInfo->encap[count].type = ENCAPS_INT; + encapsInfo->encapsCount++; return 0; } -static int SpawnBuildEncaps(AppSpawnMgr *content, AppSpawningCtx *property, char **encapsInfoStr) +APPSPAWN_STATIC int SpawnSetPermissions(AppSpawningCtx *property, UserEncaps *encapsInfo) { - // Create root object - cJSON *root = cJSON_CreateObject(); - if (root == NULL) { - return APPSPAWN_ERROR_UTILS_CREATE_JSON_FAIL; - } - - // Create encaps object - cJSON *encaps = cJSON_CreateObject(); - if (encaps == NULL) { - cJSON_Delete(root); - return APPSPAWN_ERROR_UTILS_CREATE_JSON_FAIL; + // Get Permissions obejct + cJSON *extInfoJson = GetJsonObjFromExtInfo(property, MSG_EXT_NAME_JIT_PERMISSIONS); + if (extInfoJson == NULL) { + APPSPAWN_LOGW("GetJsonObjFromExtInfo failed"); + return APPSPAWN_ARG_INVALID; } - int ret = AddMembersToEncaps(content, property, encaps); + int ret = AddMembersToEncapsInfo(extInfoJson, encapsInfo); if (ret != 0) { - APPSPAWN_LOGW("Add members to encaps object failed.(ignore), ret: %{public}d", ret); - cJSON_Delete(root); - cJSON_Delete(encaps); + APPSPAWN_LOGW("Add member to encaps failed, ret: %{public}d", ret); + cJSON_Delete(extInfoJson); return ret; } - if (cJSON_AddItemToObject(root, APP_ENCAPS, encaps) != true) { // add encaps object to root - cJSON_Delete(root); - cJSON_Delete(encaps); - APPSPAWN_LOGW("Add encaps object to root failed.(ignore)"); - return APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL; - } - - *encapsInfoStr = cJSON_PrintUnformatted(root); // need to free - if (*encapsInfoStr == NULL) { - cJSON_Delete(root); - return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL; - } + ret = SpawnSetMaxPids(property, encapsInfo); + APPSPAWN_CHECK(ret == 0, cJSON_Delete(extInfoJson); + return ret, "Set max pids count to encaps failed"); - cJSON_Delete(root); + cJSON_Delete(extInfoJson); return 0; } @@ -356,19 +406,19 @@ APPSPAWN_STATIC int SpawnSetEncapsPermissions(AppSpawnMgr *content, AppSpawningC return 0; // Can't enable encaps ability } - char *encapsInfoStr = NULL; - ret = SpawnBuildEncaps(content, property, &encapsInfoStr); + UserEncaps encapsInfo = {0}; + ret = SpawnSetPermissions(property, &encapsInfo); if (ret != 0) { close(encapsFileFd); - APPSPAWN_LOGW("Build encaps object failed, ret: %{public}d", ret); + FreeEncapsInfo(&encapsInfo); + APPSPAWN_LOGW("Build encaps info failed, ret: %{public}d", ret); return 0; // Can't set permission encpas ability } - (void)WriteEncapsInfo(encapsFileFd, ENCAPS_PERMISSION_TYPE_MODE, encapsInfoStr, OH_ENCAPS_DEFAULT_FLAG); + (void)WriteEncapsInfo(encapsFileFd, ENCAPS_PERMISSION_TYPE_MODE, &encapsInfo, OH_ENCAPS_DEFAULT_FLAG); + APPSPAWN_LOGV("Set encaps info finish"); - if (encapsInfoStr != NULL) { - free(encapsInfoStr); - } + FreeEncapsInfo(&encapsInfo); close(encapsFileFd); return 0; diff --git a/modules/common/appspawn_encaps.h b/modules/common/appspawn_encaps.h new file mode 100644 index 00000000..70d3e9be --- /dev/null +++ b/modules/common/appspawn_encaps.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APPSPAWN_ENCAPS_CPP +#define APPSPAWN_ENCAPS_CPP + +#ifdef __cplusplus +extern "C" { +#endif + +#define OH_ENCAPS_KEY_MAX_LEN 64 + +typedef enum { + ENCAPS_PROC_TYPE_MODE, // enable the encaps attribute of a process + ENCAPS_PERMISSION_TYPE_MODE, // set the encaps permission of a process + ENCAPS_MAX_TYPE_MODE +} AppSpawnEncapsBaseType; + +typedef enum { + ENCAPS_BOOL, + ENCAPS_INT, + ENCAPS_AS_ARRAY = 10, + ENCAPS_BOOL_ARRAY, + ENCAPS_INT_ARRAY, + ENCAPS_CHAR_ARRAY +} EncapsType; + +typedef struct { + char key[OH_ENCAPS_KEY_MAX_LEN]; + EncapsType type; + union { + uint64_t intValue; + void *ptrValue; + } value; + uint32_t valueLen; // valueLen < 512 +} UserEncap; + +typedef struct { + UserEncap *encap; + uint32_t encapsCount; +} UserEncaps; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/test/mock/app_spawn_stub.h b/test/mock/app_spawn_stub.h index 75222f45..d9929068 100644 --- a/test/mock/app_spawn_stub.h +++ b/test/mock/app_spawn_stub.h @@ -26,6 +26,7 @@ #include "cJSON.h" #include "appspawn_client.h" #include "appspawn_hook.h" +#include "appspawn_encaps.h" #ifdef __cplusplus extern "C" { @@ -122,7 +123,16 @@ void SetSystemEnv(void); void RunAppSandbox(const char *ptyName); HOOK_MGR *GetAppSpawnHookMgr(void); int SpawnKickDogStart(AppSpawnMgr *mgrContent); -int AddPermissionToEncaps(cJSON *extInfoJson, cJSON *encaps, uint32_t *permissionCount); +int AddMembersToEncapsInfo(cJSON *extInfoJson, UserEncaps *encapsInfo); +int SpawnSetPermissions(AppSpawningCtx *property, UserEncaps *encapsInfo); +int AddPermissionItemToEncapsInfo(UserEncap *encap, cJSON *permissionItem); +void FreeEncapsInfo(UserEncaps *encapsInfo); +int SpawnSetEncapsPermissions(AppSpawnMgr *content, AppSpawningCtx *property); +int WriteEncapsInfo(int fd, AppSpawnEncapsBaseType encapsType, const void *encapsInfo, uint32_t flag); +int AddPermissionIntArrayToValue(cJSON *arrayItem, UserEncap *encap, int arraySize); +int AddPermissionBoolArrayToValue(cJSON *arrayItem, UserEncap *encap, int arraySize); +int AddPermissionStrArrayToValue(cJSON *arrayItem, UserEncap *encap); +int AddPermissionArrayToValue(cJSON *permissionItemArr, UserEncap *encap); #ifdef APPSPAWN_HITRACE_OPTION int FilterAppSpawnTrace(AppSpawnMgr *content, AppSpawningCtx *property); diff --git a/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp index 22462e2f..8fe419b2 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp @@ -28,6 +28,7 @@ #include "appspawn_server.h" #include "appspawn_manager.h" #include "appspawn_adapter.h" +#include "appspawn_encaps.h" #include "appspawn.h" #include "appspawn_hook.h" #include "appspawn_permission.h" @@ -735,95 +736,632 @@ HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_PreForkSetPidNamespace, TestSize.L HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_001, TestSize.Level0) { - const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":0,\"permissions\":" - "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," - "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnMgr *mgr = nullptr; + int ret = -1; + do { + mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + // create msg + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + const char *permissions = "{\"name\":\"Permissions\",\"ohos.encaps.count\":6,\"permissions\":" + "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"nihaoma\"}," + "{\"ohos.permission.strarray\":[\"abc\",\"def\"]},{\"ohos.permission.intarray\":[1,2,3,4,5]}," + "{\"ohos.permission.boolarray\":[true,false,true]}]}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, + reinterpret_cast(const_cast(permissions)), strlen(permissions) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add permissions"); + const char *maxChildProcess = "512"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, + reinterpret_cast(const_cast(maxChildProcess)), strlen(maxChildProcess) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add maxChildProcess"); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); - cJSON *encapsJson = cJSON_Parse(encapsJsonStr); - uint32_t permissionCount = 0; - int ret = AddPermissionToEncaps(encapsJson, NULL, &permissionCount); - EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + ret = SpawnSetEncapsPermissions(NULL, property); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); - cJSON_Delete(encapsJson); + ret = SpawnSetEncapsPermissions(mgr, NULL); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + ret = SpawnSetEncapsPermissions(mgr, property); + } while (0); + + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + DeleteAppSpawnMgr(mgr); } HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_002, TestSize.Level0) { - const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":4,\"permissions\":" + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnMgr *mgr = nullptr; + int ret = -1; + do { + mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + // create msg + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SpawnSetEncapsPermissions(mgr, property); + } while (0); + + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + DeleteAppSpawnMgr(mgr); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_003, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + UserEncaps encapsInfo = {0}; + int ret = -1; + do { + // create msg + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + const char *permissions = "{\"name\":\"Permissions\",\"ohos.encaps.count\":0,\"permissions\":" "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, + reinterpret_cast(const_cast(permissions)), strlen(permissions) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add permissions"); + const char *maxChildProcess = "512"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, + reinterpret_cast(const_cast(maxChildProcess)), strlen(maxChildProcess) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add maxChildProcess"); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SpawnSetPermissions(property, &encapsInfo); + } while (0); - cJSON *encapsJson = cJSON_Parse(encapsJsonStr); - uint32_t permissionCount = 0; - int ret = AddPermissionToEncaps(encapsJson, NULL, &permissionCount); - EXPECT_EQ(ret, APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + FreeEncapsInfo(&encapsInfo); +} - cJSON_Delete(encapsJson); +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_004, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + UserEncaps encapsInfo = {0}; + int ret = -1; + do { + // create msg + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + const char *permissions = "{\"name\":\"Permissions\",\"ohos.encaps.count\":2,\"permissions\":" + "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225}]}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, + reinterpret_cast(const_cast(permissions)), strlen(permissions) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add permissions"); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SpawnSetPermissions(property, &encapsInfo); + } while (0); + + EXPECT_EQ(ret, 0); + EXPECT_EQ(encapsInfo.encapsCount, 2); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + FreeEncapsInfo(&encapsInfo); } -HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_003, TestSize.Level0) +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_005, TestSize.Level0) +{ + UserEncaps encapsInfo = {0}; + int ret = AddMembersToEncapsInfo(NULL, &encapsInfo); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_006, TestSize.Level0) { const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":5,\"permissions\":" "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; - cJSON *encapsOut = cJSON_CreateObject(); - EXPECT_NE(encapsOut, nullptr); cJSON *encapsJson = cJSON_Parse(encapsJsonStr); - uint32_t permissionCount = 0; - + EXPECT_NE(encapsJson, nullptr); cJSON *permissions = cJSON_GetObjectItemCaseSensitive(encapsJson, "permissions"); EXPECT_NE(permissions, nullptr); cJSON *emptyItem = cJSON_CreateObject(); - cJSON_AddItemToArray(permissions, emptyItem); - - int ret = AddPermissionToEncaps(encapsJson, encapsOut, &permissionCount); + EXPECT_TRUE(cJSON_AddItemToArray(permissions, emptyItem)); + UserEncaps encapsInfo = {0}; + int ret = AddMembersToEncapsInfo(encapsJson, &encapsInfo); EXPECT_EQ(ret, APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL); cJSON_Delete(encapsJson); - cJSON_Delete(encapsOut); + FreeEncapsInfo(&encapsInfo); } -HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_004, TestSize.Level0) +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_007, TestSize.Level0) { const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":4,\"permissions\":" "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," - "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; + "{\"ohos.permission.array\":[1,\"abc\",3,4,5]}]}"; - cJSON *encapsOut = cJSON_CreateObject(); - EXPECT_NE(encapsOut, nullptr); cJSON *encapsJson = cJSON_Parse(encapsJsonStr); - uint32_t permissionCount = 0; + EXPECT_NE(encapsJson, nullptr); + UserEncaps encapsInfo = {0}; + int ret = AddMembersToEncapsInfo(encapsJson, &encapsInfo); + EXPECT_EQ(ret, APPSPAWN_ERROR_UTILS_ADD_JSON_FAIL); - cJSON *permissions = cJSON_GetObjectItemCaseSensitive(encapsJson, "permissions"); - EXPECT_NE(permissions, nullptr); - cJSON *permission = cJSON_GetArrayItem(permissions, 0); - EXPECT_NE(permission, nullptr); - permission->child = nullptr; - int ret = AddPermissionToEncaps(encapsJson, encapsOut, &permissionCount); - EXPECT_EQ(ret, APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL); + cJSON_Delete(encapsJson); + FreeEncapsInfo(&encapsInfo); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_008, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.bool\":true}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + // permissionItem->string is NULL + int ret = AddPermissionItemToEncapsInfo(&encap, permissionItem); + EXPECT_EQ(ret, APPSPAWN_SYSTEM_ERROR); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_009, TestSize.Level0) +{ + // len = 512 + "\0" + const char permissionItemStr[] = "{\"ohos.permission.string\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_010, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.strarray\":[\"abc\",\"def\",1]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_011, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.boolarray\":[true,false,\"abc\"]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_012, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.intarray\":[1,2,3,4,false]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_013, TestSize.Level0) +{ + // array len = 510 + "\0" * 3 + const char permissionItemStr[] = "{\"ohos.permission.strarray\":[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAA\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_014, TestSize.Level0) +{ + // array len = 509 + "\0" * 3 + const char permissionItemStr[] = "{\"ohos.permission.strarray\":[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAA\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, 0); + EXPECT_EQ(encap.valueLen, 512); + EXPECT_EQ(encap.type, ENCAPS_CHAR_ARRAY); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_015, TestSize.Level0) +{ + // key len = 64 + "\0" + const char permissionItemStr[] = "{\"ohos.permission.strarrayabcdefghijklmnopqrstuvwxyzaaaaaaaaaaaaaa\":\"abc\"}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_SYSTEM_ERROR); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_016, TestSize.Level0) +{ + // key len = 63 + "\0" + const char permissionItemStr[] = "{\"ohos.permission.strarrayabcdefghijklmnopqrstuvwxyzaaaaaaaaaaaaa\":\"abc\"}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, 0); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_017, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.int\":128}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, 0); + EXPECT_EQ(encap.type, ENCAPS_INT); + EXPECT_EQ(encap.value.intValue, 128); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_018, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.bool\":true}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, 0); + EXPECT_EQ(encap.type, ENCAPS_BOOL); + EXPECT_EQ(encap.value.intValue, 1); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_019, TestSize.Level0) +{ + const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":6,\"permissions\":100}"; + + cJSON *encapsJson = cJSON_Parse(encapsJsonStr); + EXPECT_NE(encapsJson, nullptr); + UserEncaps encapsInfo = {0}; + int ret = AddMembersToEncapsInfo(encapsJson, &encapsInfo); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); cJSON_Delete(encapsJson); - cJSON_Delete(encapsOut); + FreeEncapsInfo(&encapsInfo); } -HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_005, TestSize.Level0) +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_020, TestSize.Level0) { - const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":4,\"permissions\":" - "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," - "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; + const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":\"6\",\"permissions\":" + "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"nihaoma\"}," + "{\"ohos.permission.strarray\":[\"abc\",\"def\"]},{\"ohos.permission.intarray\":[1,2,3,4,5]}," + "{\"ohos.permission.boolarray\":[true,false,true]}]}"; - cJSON *encapsOut = cJSON_CreateObject(); - EXPECT_NE(encapsOut, nullptr); cJSON *encapsJson = cJSON_Parse(encapsJsonStr); - uint32_t permissionCount = 0; + EXPECT_NE(encapsJson, nullptr); + UserEncaps encapsInfo = {0}; + int ret = AddMembersToEncapsInfo(encapsJson, &encapsInfo); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); - int ret = AddPermissionToEncaps(encapsJson, encapsOut, &permissionCount); - EXPECT_EQ(ret, 0); - EXPECT_EQ(permissionCount, 4); + cJSON_Delete(encapsJson); + FreeEncapsInfo(&encapsInfo); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_021, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.intarray\":[]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_022, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.strarray\":[\"abc\",\"\",\"def\"]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_023, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.str\":\"\"}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_024, TestSize.Level0) +{ + const char permissionItemStr[] = "[1,2,3,4,5]"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionIntArrayToValue(permissionChild, &encap, 6); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_025, TestSize.Level0) +{ + const char permissionItemStr[] = "[true,false,true]"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionBoolArrayToValue(permissionChild, &encap, 4); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_026, TestSize.Level0) +{ + const char permissionItemStr[] = "[\"abc\",\"def\"]"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *item = cJSON_CreateString(""); + EXPECT_NE(item, nullptr); + free(item->valuestring); + item->valuestring = nullptr; + EXPECT_EQ(cJSON_AddItemToArray(permissionItem, item), 1); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionStrArrayToValue(permissionChild, &encap); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_027, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"ohos.permission.intarray\":[{\"ohos.permission.bool\":true},2,3,4,5]}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionArrayToValue(permissionChild, &encap); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_028, TestSize.Level0) +{ + const char permissionItemStr[] = "{\"permissions\":{\"ohos.permission.bool\":true}}"; + + cJSON *permissionItem = cJSON_Parse(permissionItemStr); + EXPECT_NE(permissionItem, nullptr); + cJSON *permissionChild = permissionItem->child; + EXPECT_NE(permissionChild, nullptr); + UserEncap encap; + (void)memset_s(&encap, sizeof(encap), 0, sizeof(encap)); + int ret = AddPermissionItemToEncapsInfo(&encap, permissionChild); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); + + cJSON_Delete(permissionItem); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_029, TestSize.Level0) +{ + const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":6,\"permissions\":[]}"; + + cJSON *encapsJson = cJSON_Parse(encapsJsonStr); + EXPECT_NE(encapsJson, nullptr); + UserEncaps encapsInfo = {0}; + int ret = AddMembersToEncapsInfo(encapsJson, &encapsInfo); + EXPECT_EQ(ret, APPSPAWN_ARG_INVALID); cJSON_Delete(encapsJson); - cJSON_Delete(encapsOut); + FreeEncapsInfo(&encapsInfo); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_030, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + UserEncaps encapsInfo = {0}; + int ret = -1; + do { + // create msg + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + const char *permissions = "{\"name\":\"Permissions\",\"ohos.encaps.count\":4,\"permissions\":" + "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," + "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, + reinterpret_cast(const_cast(permissions)), strlen(permissions) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add permissions"); + const char *maxChildProcess = "512"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, + reinterpret_cast(const_cast(maxChildProcess)), strlen(maxChildProcess) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add maxChildProcess"); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SpawnSetPermissions(property, &encapsInfo); + } while (0); + + EXPECT_EQ(ret, 0); + EXPECT_EQ(encapsInfo.encapsCount, 4); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + FreeEncapsInfo(&encapsInfo); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_031, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + UserEncaps encapsInfo = {0}; + int ret = -1; + do { + // create msg + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + const char *permissions = "{\"name\":\"Permissions\",\"ohos.encaps.count\":4,\"permissions\":" + "[{\"ohos.permission.bool\":true},{\"ohos.permission.int\":3225},{\"ohos.permission.string\":\"test\"}," + "{\"ohos.permission.array\":[1,2,3,4,5]}]}"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_JIT_PERMISSIONS, + reinterpret_cast(const_cast(permissions)), strlen(permissions) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add permissions"); + const char *maxChildProcess = "0"; + ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, + reinterpret_cast(const_cast(maxChildProcess)), strlen(maxChildProcess) + 1); + APPSPAWN_CHECK(ret == 0, break, "Failed to add maxChildProcess"); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SpawnSetPermissions(property, &encapsInfo); + } while (0); + + EXPECT_EQ(ret, 0); + EXPECT_EQ(encapsInfo.encapsCount, 4); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + FreeEncapsInfo(&encapsInfo); } HWTEST_F(AppSpawnCommonTest, App_Spawn_SetFdEnv, TestSize.Level0) -- Gitee