插件化全部使能

Signed-off-by: zhongning5 <zhongning5@huawei.com>
This commit is contained in:
zhongning5 2024-04-13 18:58:15 +08:00
parent bdc431d43d
commit df424b8ab5
76 changed files with 9268 additions and 6554 deletions

219
BUILD.gn
View File

@ -1,4 +1,4 @@
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Copyright (c) 2024 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
@ -16,219 +16,50 @@ import("//build/ohos.gni")
config("appspawn_config") {
visibility = [ "./*" ]
include_dirs = [
"${appspawn_path}",
"common",
"standard",
"adapter",
"interfaces/innerkits/include",
"interfaces/innerkits_new/include",
"util/include",
"//third_party/json/include",
"${appspawn_innerkits_path}/include",
"${appspawn_path}/modules/module_engine/include",
"${appspawn_path}/util/include",
"//commonlibrary/c_utils/base/include",
]
cflags = []
if (build_selinux) {
cflags = [ "-DWITH_SELINUX" ]
cflags += [ "-DWITH_SELINUX" ]
}
if (build_seccomp) {
cflags += [ "-DWITH_SECCOMP" ]
}
}
if (!defined(ohos_lite)) {
ohos_executable("appspawn") {
defines = []
if (target_cpu == "arm64") {
defines += [ "webview_arm64" ]
}
if (target_cpu == "x86_64") {
defines += [ "webview_x86_64" ]
}
sources = [
"${appspawn_path}/adapter/appspawn_ace.cpp",
"${appspawn_path}/adapter/appspawn_nweb.cpp",
"${appspawn_path}/adapter/nwebspawn_lancher.cpp",
"${appspawn_path}/interfaces/innerkits/src/appspawn_mount_permission.cpp",
"${appspawn_path}/standard/main.c",
"${appspawn_path}/util/src/command_lexer.cpp",
"${appspawn_path}/util/src/json_utils.cpp",
"${appspawn_path}/util/src/param_helper.c",
"${appspawn_path}/util/src/sandbox_utils.cpp",
]
if (asan_detector || is_asan) {
defines += [ "ASAN_DETECTOR" ]
}
configs = [ ":appspawn_config" ]
deps = [ "${appspawn_path}:appspawn_server" ]
external_deps = [
"ability_base:want",
"ability_runtime:app_manager",
"ability_runtime:appkit_native",
"ability_runtime:runtime",
"access_token:libtoken_setproc",
"ace_engine:ace_forward_compatibility",
"cJSON:cjson",
"c_utils:utils",
"common_event_service:cesfwk_innerkits",
"config_policy:configpolicy_util",
"eventhandler:libeventhandler",
"hilog:libhilog",
"hitrace:hitrace_meter",
"init:libbegetutil",
"ipc:ipc_single",
"libuv:uv",
"napi:ace_napi",
"os_account:os_account_innerkits",
"resource_management:global_resmgr",
"selinux:libselinux",
]
if (build_selinux) {
external_deps += [ "selinux_adapter:libhap_restorecon" ]
}
cflags = []
if (build_seccomp) {
cflags += [ "-DWITH_SECCOMP" ]
external_deps += [ "init:seccomp" ]
}
if (!defined(global_parts_info) ||
defined(global_parts_info.security_code_signature)) {
defines += [ "CODE_SIGNATURE_ENABLE" ]
external_deps += [ "code_signature:libcode_sign_attr_utils" ]
}
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_shared_library("appspawn_helper") {
sources = [ "${appspawn_path}/common/appspawn_server.c" ]
configs = [ ":appspawn_config" ]
defines = [ "APPSPAWN_HELPER" ]
cflags = [
"-fvisibility=hidden",
"-fstack-protector-all",
]
external_deps = [
"ability_runtime:appkit_native",
"access_token:libtoken_setproc",
"c_utils:utils",
"eventhandler:libeventhandler",
"hilog:libhilog",
"init:libbegetutil",
"ipc:ipc_single",
"libuv:uv",
"napi:ace_napi",
"resource_management:global_resmgr",
"selinux:libselinux",
]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_static_library("appspawn_server") {
sources = [
"${appspawn_path}/adapter/appspawn_adapter.cpp",
"${appspawn_path}/adapter/appspawn_cgroup.c",
"${appspawn_path}/adapter/appspawn_nweb.cpp",
"${appspawn_path}/adapter/appspawn_sandbox.cpp",
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/interfaces/innerkits/src/appspawn_mount_permission.cpp",
"${appspawn_path}/standard/appspawn_msgmgr.c",
"${appspawn_path}/standard/appspawn_process.c",
"${appspawn_path}/standard/appspawn_service.c",
"${appspawn_path}/util/src/env_utils.cpp",
"${appspawn_path}/util/src/json_utils.cpp",
"${appspawn_path}/util/src/sandbox_utils.cpp",
]
defines = [
"GRAPHIC_PERMISSION_CHECK",
"INIT_AGENT",
]
if (asan_detector || is_asan) {
defines += [ "ASAN_DETECTOR" ]
}
configs = [ ":appspawn_config" ]
ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64z" ]
deps = []
external_deps = [
"ability_runtime:appkit_native",
"access_token:libtoken_setproc",
"access_token:libtokenid_sdk",
"cJSON:cjson",
"c_utils:utils",
"config_policy:configpolicy_util",
"eventhandler:libeventhandler",
"hilog:libhilog",
"init:libbegetutil",
"ipc:ipc_single",
"libuv:uv",
"napi:ace_napi",
"netmanager_base:netsys_client",
"os_account:os_account_innerkits",
"resource_management:global_resmgr",
"selinux:libselinux",
]
if (!defined(global_parts_info) ||
defined(global_parts_info.security_security_component_manager)) {
defines += [ "SECURITY_COMPONENT_ENABLE" ]
external_deps +=
[ "security_component_manager:libsecurity_component_sdk" ]
}
if (!defined(global_parts_info) ||
defined(global_parts_info.security_code_signature)) {
defines += [ "CODE_SIGNATURE_ENABLE" ]
external_deps += [ "code_signature:libcode_sign_attr_utils" ]
}
if (build_selinux) {
external_deps += [ "selinux_adapter:libhap_restorecon" ]
}
cflags = []
if (build_seccomp) {
cflags += [ "-DWITH_SECCOMP" ]
external_deps += [ "init:seccomp" ]
}
if (appspawn_report_event) {
cflags += [ "-DREPORT_EVENT" ]
deps += [ "adapter/sysevent:event_reporter" ]
}
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_prebuilt_etc("appspawn.rc") {
source = "appspawn.cfg"
relative_install_dir = "init"
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_executable("pid_ns_init") {
sources = [ "${appspawn_path}/standard/pid_ns_init.c" ]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
}
group("appspawn_all") {
deps = []
if (!defined(ohos_lite)) {
deps += [ ":pid_ns_init" ]
deps += [ ":appspawn" ]
deps += [ "standard:appspawn" ]
deps += [ "standard:appspawn_helper" ]
deps += [ "standard:pid_ns_init" ]
deps += [ ":appspawn.rc" ]
deps += [ ":appspawn_helper" ]
deps += [ ":appspawn_server" ]
deps += [ "etc:etc_files" ]
deps += [ "interfaces/innerkits:appspawn_socket_client" ]
deps += [ "modules/ace_adapter:appspawn_ace" ]
deps += [ "modules/asan:appspawn_asan" ]
deps += [ "modules/nweb_adapter:appspawn_nweb" ]
deps += [ "modules/sandbox:appspawn_sandbox" ]
deps += [ "modules/common:appspawn_common" ]
deps += [ "modules/sysevent:event_reporter" ]
deps += [ "${appspawn_innerkits_path}/client:appspawn_client" ]
deps += [
"${appspawn_path}/modules/module_engine:libappspawn_module_engine",
"${appspawn_path}/modules/module_engine:libappspawn_stub_empty",
]
deps += [ "service/hnp:hnp" ]
} else {
deps += [ "lite:appspawn_lite" ]

428
appdata-sandbox-app.json Executable file
View File

@ -0,0 +1,428 @@
{
"global": {
"sandbox-root": "/mnt/sandbox/<currentUserId>/app-root",
"sandbox-ns-flags": [ "pid" ]
},
"required": {
"system-const": {
"mount-paths": [{
"sandbox-path" : "/config",
"src-path" : "/config"
}, {
"sandbox-path" : "/dev",
"src-path" : "/dev"
}, {
"sandbox-path" : "/proc",
"src-path" : "/proc"
}, {
"sandbox-path" : "/sys",
"src-path" : "/sys"
}, {
"sandbox-path" : "/sys_prod",
"src-path" : "/sys_prod"
}, {
"sandbox-path" : "/system/app",
"src-path" : "/system/app"
}, {
"sandbox-path" : "/system/fonts",
"src-path" : "/system/fonts"
}, {
"src-path" : "/system/<lib>",
"sandbox-path" : "/system/<lib>"
}, {
"src-path" : "/system/<lib>/platformsdk",
"sandbox-path" : "/system/<lib>/platformsdk"
}, {
"src-path" : "/system/<lib>/ndk",
"sandbox-path" : "/system/<lib>/ndk"
}, {
"src-path" : "/system/<lib>/module",
"sandbox-path" : "/system/<lib>/module"
}, {
"src-path" : "/system/<lib>/chipset-pub-sdk",
"sandbox-path" : "/system/<lib>/chipset-pub-sdk"
}, {
"src-path" : "/system/<lib>/chipset-sdk",
"sandbox-path" : "/system/<lib>/chipset-sdk"
}, {
"src-path" : "/system/<lib>/seccomp",
"sandbox-path" : "/system/<lib>/seccomp"
}, {
"src-path" : "/system/<lib>/extensionability",
"sandbox-path" : "/system/<lib>/extensionability"
}, {
"src-path" : "/system/<lib>/media",
"sandbox-path" : "/system/<lib>/media"
}, {
"sandbox-path" : "/system/data",
"src-path" : "/system/data"
}, {
"sandbox-path" : "/system/usr",
"src-path" : "/system/usr"
}, {
"sandbox-path" : "/system/profile",
"src-path" : "/system/profile"
}, {
"sandbox-path" : "/system/bin",
"src-path" : "/system/bin"
}, {
"sandbox-path" : "/system/etc",
"src-path" : "/system/etc"
}, {
"sandbox-path" : "/system/resources",
"src-path" : "/system/resources"
}, {
"sandbox-path" : "/vendor/<lib>",
"src-path" : "/vendor/<lib>"
}, {
"sandbox-path" : "/vendor/etc/vulkan",
"src-path" : "/vendor/etc/vulkan"
}, {
"sandbox-path" : "/vendor/etc/hiai",
"src-path" : "/vendor/etc/hiai"
}],
"mount-files": [{
"src-path" : "/system/<lib>/ld-musl-arm.so.1",
"sandbox-path" : "/system/<lib>/ld-musl-arm.so.1"
}],
"symbol-links" : [{
"target-name" : "/system/bin",
"link-name" : "/bin",
"check-action-status": "false"
}, {
"target-name" : "/system/lib",
"link-name" : "/lib",
"check-action-status": "false"
}, {
"target-name" : "/system/etc",
"link-name" : "/etc",
"check-action-status": "false"
}, {
"target-name" : "/sys/kernel/debug",
"link-name" : "/d",
"check-action-status": "false"
}],
"mount-groups" : []
},
"app-variable": {
"mount-paths": [{
"sandbox-path": "/data/storage/el1/base",
"src-path": "/data/app/el1/<currentUserId>/base/<PackageName>"
}, {
"sandbox-path": "/data/storage/el1/database",
"src-path": "/data/app/el1/<currentUserId>/database/<PackageName>"
}, {
"src-path" : "/system/app/ohos.global.systemres",
"sandbox-path" : "/data/global/systemResources"
}, {
"src-path" : "/system/app/SystemResources",
"sandbox-path" : "/data/global/systemResources"
}, {
"src-path" : "/data/app/el1/bundle/public/<PackageName>",
"sandbox-path" : "/data/storage/el1/bundle",
"check-action-status": "true"
}, {
"src-path" : "/data/misc",
"sandbox-path" : "/data/storage/el1/bundle/misc"
}, {
"src-path" : "/data/local/ark-cache/<PackageName>",
"sandbox-path" : "/data/storage/ark-cache"
}, {
"src-path" : "/data/local/ark-profile/<currentUserId>/<PackageName>",
"sandbox-path" : "/data/storage/ark-profile"
}, {
"src-path" : "/mnt/share/<currentUserId>/<PackageName_index>",
"sandbox-path" : "/data/storage/el2/share"
}, {
"src-path" : "/data/service/el1/public/themes/<currentUserId>/a/app",
"sandbox-path" : "/data/themes/a/app"
}, {
"src-path" : "/data/service/el1/public/themes/<currentUserId>/b/app",
"sandbox-path" : "/data/themes/b/app"
}, {
"src-path" : "/data/service/el1/<currentUserId>/distributeddata/utd",
"sandbox-path" : "/data/utd"
}, {
"src-path" : "/data/service/el1/public/cert_manager_service/certificates/user_open",
"sandbox-path" : "/data/certificates/user_cacerts"
}, {
"src-path" : "/data/app/el1/bundle/public/com.ohos.nweb",
"sandbox-path" : "/data/storage/el1/bundle/nweb"
},{
"src-path" : "/mnt/hmdfs/<currentUserId>",
"sandbox-path" : "/mnt/hmdfs/<currentUserId>"
}],
"mount-groups": ["el2", "el3", "el4"]
}
},
"conditional": {
"permission": [{
"name": "ohos.permission.FILE_ACCESS_MANAGER",
"sandbox-switch": "ON",
"gids": ["file_manager", "user_data_rw"],
"mount-paths": [{
"sandbox-path": "/storage/Users/<currentUserId>",
"src-path": "/storage/media/<currentUserId>/local/files/Docs"
}, {
"sandbox-path": "/storage/Users/<currentUserId>/.Recent",
"src-path": "/storage/media/<currentUserId>/local/files/.Recent"
}],
"mount-groups": [ "user-public" ]
}, {
"name": "ohos.permission.CLOUDFILE_SYNC",
"mount-paths": [{
"src-path" : "/mnt/hmdfs/<currentUserId>/cloud/data/<PackageName>",
"sandbox-path" : "/data/storage/el2/cloud"
}]
}, {
"name": "ohos.permission.READ_IMAGEVIDEO",
"sandbox-switch": "ON",
"gids": ["user_data_rw"],
"mount-paths": [{
"sandbox-path": "/storage/Share/.thumbs/Photo",
"src-path": "/storage/cloud/<currentUserId>/files/.thumbs/Photo"
}]
}, {
"name": "ohos.permission.FILE_CROSS_APP",
"gids": ["file_manager"],
"mount-paths": [{
"src-path": "/storage/media/<currentUserId>/local/files/Docs",
"sandbox-path": "/storage/Users/<currentUserId>"
}, {
"src-path": "/data/app/el1/<currentUserId>/base",
"sandbox-path": "/storage/Users/<currentUserId>/appdata/el1",
"category": "dac_override"
}, {
"src-path": "/data/app/el2/<currentUserId>/base",
"sandbox-path": "/storage/Users/<currentUserId>/appdata/el2",
"category": "dac_override"
}],
"mount-groups": [ "user-public" ]
}, {
"name": "ohos.permission.ACTIVATE_THEME_PACKAGE",
"mount-paths": [{
"sandbox-path": "/data/themes/a/system",
"src-path": "/data/service/el1/public/themes/<currentUserId>/a/system"
}, {
"sandbox-path": "/data/themes/b/system",
"src-path": "/data/service/el1/public/themes/<currentUserId>/b/system"
}, {
"src-path": "/data/service/el1/public/themes/<currentUserId>/fa",
"sandbox-path": "/data/themes/f"
},{
"src-path": "/data/service/el1/public/themes/<currentUserId>/share",
"sandbox-path": "/data/themes/s"
}]
}, {
"name": "ohos.permission.GET_WALLPAPER",
"mount-paths": [{
"sandbox-path": "/data/wallpaper",
"src-path": "/data/service/el1/public/wallpaper/<currentUserId>"
}]
}, {
"name": "ohos.permission.ACCESS_BUNDLE_DIR",
"gids": ["wifi"],
"mount-paths": [{
"sandbox-path": "/data/bundles/",
"src-path": "/data/app/el1/bundle/public"
}]
}, {
"name": "ohos.permission.ACCESS_PROTOCOL_DFX_DATA",
"mount-paths": [{
"sandbox-path": "/data/log/protocol",
"src-path": "/data/log/protocol"
}, {
"sandbox-path": "/log/chr",
"src-path": "/log/chr"
}]
}, {
"name": "ohos.permission.ACCESS_MEDIALIB_THUMB_DB",
"gids": [3008],
"mount-paths": [{
"src-path": "/data/app/el2/<currentUserId>/database/com.ohos.medialibrary.medialibrarydata",
"sandbox-path": "/data/medialibrary/database"
}
]
}],
"spawn-flag": [{
"name": "START_FLAGS_BACKUP",
"mount-paths": [{
"sandbox-path": "/data/storage/el2/backup",
"src-path": "/data/service/el2/<currentUserId>/backup/bundles/<PackageName>"
}, {
"sandbox-path": "/data/storage/el1/backup",
"src-path": "/data/service/el1/<currentUserId>/backup/bundles/<PackageName>"
}],
"mount-groups": []
}, {
"name": "DLP_MANAGER",
"mount-paths": [ {
"sandbox-path": "/data/storage/el1/base",
"src-path": "/data/app/el1/<currentUserId>/base/<PackageName_index>"
}, {
"sandbox-path": "/data/storage/el1/database",
"src-path": "/data/app/el1/<currentUserId>/database/<PackageName_index>"
}, {
"sandbox-path": "/data/storage/el2/base",
"src-path": "/data/app/el2/<currentUserId>/base/<PackageName_index>"
}, {
"sandbox-path": "/data/storage/el2/database",
"src-path": "/data/app/el2/<currentUserId>/database/<PackageName_index>"
}, {
"sandbox-path": "/data/storage/el2/log",
"src-path": "/data/app/el2/<currentUserId>/log/<PackageName_index>"
}, {
"sandbox-path": "/data/storage/el2/share",
"src-path": "/mnt/share/<currentUserId>/<PackageName_index>"
}],
"mount-groups": []
}],
"package-name": [{
"name": "com.ohos.medialibrary.medialibrarydata",
"mount-paths" : [{
"src-path" : "/storage/media/<currentUserId>",
"sandbox-path" : "/storage/media"
}, {
"src-path" : "/data/service/el2/<currentUserId>/hmdfs/cache/account_cache",
"sandbox-path" : "/data/service/el2/<currentUserId>/hmdfs/cache/account_cache"
}, {
"src-path" : "/storage/cloud/<currentUserId>",
"sandbox-path" : "/storage/cloud"
}, {
"src-path" : "none",
"sandbox-path" : "/storage/cloud/epfs",
"category": "epfs"
}, {
"src-path" : "/mnt/data/<currentUserId>",
"sandbox-path" : "/mnt/data/<currentUserId>"
}]
}, {
"name" : "com.ohos.amsdialog",
"sandbox-switch": "ON",
"mount-paths" : [{
"src-path" : "/data/app/el1/bundle/public/",
"sandbox-path" : "/data/bundles/",
"check-action-status": "true"
}],
"symbol-links" : []
}, {
"name": "com.ohos.dlpmanager",
"sandbox-switch": "ON",
"sandbox-shared" : "true",
"mount-paths" :[{
"src-path" : "/mnt/data/<currentUserId>",
"sandbox-path" : "/mnt/data",
"category": "shared",
"check-action-status": "true"
}, {
"src-path" : "/dev/fuse",
"sandbox-path" : "/mnt/data/fuse",
"category": "dlp_fuse"
}],
"mount-groups": ["dlpmgr"]
}, {
"name" : "com.ohos.permissionmanager",
"sandbox-switch": "ON",
"mount-paths" : [{
"src-path" : "/data/app/el1/bundle/public/",
"sandbox-path" : "/data/bundles/",
"check-action-status": "true"
}
],
"symbol-links" : []
}]
},
"name-groups": [{
"name": "user-public",
"type": "system-const",
"mount-paths": [{
"sandbox-path": "/storage/Share",
"src-path": "/data/service/el1/public/storage_daemon/share/public"
}, {
"sandbox-path": "/storage/External",
"src-path": "/mnt/data/external"
}]
}, {
"name": "el2",
"type": "app-variable",
"deps-mode": "not-exists",
"mount-paths-deps": {
"sandbox-path": "/data/storage/el2",
"src-path": "/data/app/el2/<currentUserId>/base",
"category": "shared"
},
"mount-paths": [{
"sandbox-path": "<deps-path>/base",
"src-path": "/data/app/el2/<currentUserId>/base/<PackageName>"
}, {
"sandbox-path": "<deps-path>/database",
"src-path": "/data/app/el2/<currentUserId>/database/<PackageName>"
}, {
"sandbox-path": "<deps-path>/log",
"src-path": "/data/app/el2/<currentUserId>/log/<PackageName>"
}, {
"sandbox-path": "<deps-path>/auth_groups",
"src-path": "/mnt/hmdfs/<currentUserId>/non_account/merge_view/data"
}, {
"sandbox-path": "<deps-path>/distributedfiles",
"src-path": "/mnt/hmdfs/<currentUserId>/account/merge_view/data/<PackageName>"
}, {
"sandbox-path": "<deps-path>/share",
"src-path": "/mnt/share/<currentUserId>/<PackageName_index>"
}]
}, {
"name": "el3",
"type": "app-variable",
"deps-mode": "not-exists",
"mount-paths-deps": {
"sandbox-path": "/data/storage/el3",
"src-path": "/data/app/el3/<currentUserId>/base",
"category": "shared"
},
"mount-paths": [{
"sandbox-path": "<deps-path>/base",
"src-path": "/data/app/el3/<currentUserId>/base/<PackageName>"
}, {
"sandbox-path": "<deps-path>/database",
"src-path": "/data/app/el3/<currentUserId>/database/<PackageName>"
}]
}, {
"name": "el4",
"type": "app-variable",
"deps-mode": "not-exists",
"mount-paths-deps": {
"sandbox-path": "/data/storage/el4",
"src-path": "/data/app/el4/<currentUserId>/base",
"category": "shared"
},
"mount-paths": [{
"sandbox-path": "<deps-path>/base",
"src-path": "/data/app/el4/<currentUserId>/base/<PackageName>"
}, {
"sandbox-path": "<deps-path>/database",
"src-path": "/data/app/el4/<currentUserId>/database/<PackageName>"
}]
}, {
"name": "hsp",
"type": "app-variable",
"mount-paths": [{
"sandbox-path": "/data/storage/el2/group/<bundle-name>/<module-name>",
"src-path": "/data/app/el1/bundle/public/<bundle-name>/<version>/<module-name>"
}]
}, {
"name": "data-group",
"type": "app-variable",
"mount-paths": [{
"sandbox-path": "/data/storage/el2/group/<uuid>",
"src-path": "<data-dir>"
}]
}, {
"name": "overlay",
"type": "app-variable",
"mount-paths": [{
"sandbox-path": "/data/storage/overlay/<hap-name>",
"src-path": "<hap-path>",
"category": "shared"
}]
}]
}

92
appdata-sandbox-nweb.json Executable file
View File

@ -0,0 +1,92 @@
{
"global": {
"sandbox-root" : "/mnt/sandbox/com.ohos.render/<PackageName>",
"sandbox-ns-flags" : [ "pid", "net" ]
},
"required": {
"system-const": {
"mount-paths": [{
"src-path" : "/dev",
"sandbox-path" : "/dev"
}, {
"src-path" : "/proc",
"sandbox-path" : "/proc"
}, {
"src-path" : "/sys",
"sandbox-path" : "/sys"
}, {
"src-path" : "/system/fonts",
"sandbox-path" : "/system/fonts"
}, {
"src-path" : "/system/etc",
"sandbox-path" : "/system/etc"
}, {
"src-path" : "/system/bin",
"sandbox-path" : "/system/bin"
}, {
"src-path" : "/system/<lib>",
"sandbox-path" : "/system/<lib>"
}, {
"src-path" : "/data/app/el1/bundle/public/com.ohos.nweb",
"sandbox-path" : "/data/storage/el1/bundle/nweb"
}, {
"src-path" : "/system/<lib>/platformsdk",
"sandbox-path" : "/system/<lib>/platformsdk"
}, {
"src-path" : "/system/<lib>/ndk",
"sandbox-path" : "/system/<lib>/ndk"
}, {
"src-path" : "/system/<lib>/module",
"sandbox-path" : "/system/<lib>/module"
}, {
"src-path" : "/system/<lib>/chipset-pub-sdk",
"sandbox-path" : "/system/<lib>/chipset-pub-sdk"
}, {
"src-path" : "/system/<lib>/chipset-sdk",
"sandbox-path" : "/system/<lib>/chipset-sdk"
}, {
"src-path" : "/system/<lib>/seccomp",
"sandbox-path" : "/system/<lib>/seccomp"
}, {
"src-path" : "/system/<lib>/extensionability",
"sandbox-path" : "/system/<lib>/extensionability"
}, {
"src-path" : "/system/<lib>/media",
"sandbox-path" : "/system/<lib>/media"
}, {
"src-path" : "/system/app/com.ohos.nweb",
"sandbox-path" : "/system/app/com.ohos.nweb"
}, {
"src-path" : "/vendor/lib",
"sandbox-path" : "/vendor/lib",
"sandbox-flags" : [ "bind", "rec" ],
"check-action-status": "false"
}, {
"src-path" : "/system/app/NWeb",
"sandbox-path" : "/system/app/NWeb"
}],
"symbol-links" : [{
"target-name" : "/system/etc",
"link-name" : "/etc",
"check-action-status": "false"
}, {
"target-name" : "/system/bin",
"link-name" : "/bin",
"check-action-status": "false"
}, {
"target-name" : "/system/lib",
"link-name" : "/lib",
"check-action-status": "false"
}
],
"mount-files": [{
"src-path" : "/system/<lib>/ld-musl-arm.so.1",
"sandbox-path" : "/system/<lib>/ld-musl-arm.so.1"
}],
"mount-groups" : []
},
"app-variable": {
"mount-groups": []
}
}
}

View File

@ -3,7 +3,10 @@
"name" : "service:nwebspawn",
"cmds" : [
"mkdir /mnt/sandbox",
"mkdir /mnt/sandbox/com.ohos.render/ 0711 nwebspawn nwebspawn"
"mkdir /mnt/sandbox/com.ohos.render/ 0711 nwebspawn nwebspawn",
"mkdir /mnt/startup",
"mkdir /mnt/startup/appspawn 0700 root root",
"mkdir /mnt/startup/nwebspawn/ 0700 nwebspawn nwebspawn"
]
},
{
@ -23,6 +26,7 @@
"services" : [{
"name" : "appspawn",
"path" : ["/system/bin/appspawn",
"-mode appspawn",
"--process-name com.ohos.appspawn.startup --start-flags daemon --type standard ",
"--sandbox-switch on --bundle-name com.ohos.appspawn.startup --app-operate-type operate ",
"--render-command command --app-launch-type singleton --app-visible true"],

View File

@ -24,4 +24,5 @@ declare_args() {
appspawn_support_nweb = true
appspawn_report_event = true
appspawn_test_cmd = false
appspawn_sandbox_new = false
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Copyright (c) 20214 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
@ -15,40 +15,17 @@
#include "appspawn_server.h"
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <malloc.h>
#include <fcntl.h>
#include <stdio.h>
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <sched.h>
#include <signal.h>
#include <time.h>
#ifdef SECURITY_COMPONENT_ENABLE
#include "sec_comp_enhance_kit_c.h"
#endif
#define DEFAULT_UMASK 0002
long long DiffTime(struct timespec *startTime)
{
struct timespec tmEnd = {0};
clock_gettime(CLOCK_REALTIME, &tmEnd);
long long diff = (long long)((tmEnd.tv_sec - startTime->tv_sec) * 1000000); // 1000000 1000ms
if (tmEnd.tv_nsec > startTime->tv_nsec) {
diff += (tmEnd.tv_nsec - startTime->tv_nsec) / 1000; // 1000 ms
} else {
diff -= (startTime->tv_nsec - tmEnd.tv_nsec) / 1000; // 1000 ms
}
return diff;
}
#include "appspawn_utils.h"
static void NotifyResToParent(struct AppSpawnContent *content, AppSpawnClient *client, int result)
{
APPSPAWN_LOGI("NotifyResToParent: %{public}d", result);
if (content->notifyResToParent != NULL) {
content->notifyResToParent(content, client, result);
}
@ -81,169 +58,79 @@ void exit(int code)
}
#endif
int DoStartApp(struct AppSpawnContent *content, AppSpawnClient *client, char *longProcName, uint32_t longProcNameLen)
APPSPAWN_STATIC int AppSpawnChild(AppSpawnContent *content, AppSpawnClient *client)
{
int32_t ret = 0;
APPSPAWN_LOGV("DoStartApp id %{public}d longProcNameLen %{public}u", client->id, longProcNameLen);
if (content->handleInternetPermission != NULL) {
content->handleInternetPermission(client);
}
APPSPAWN_CHECK(content != NULL && client != NULL, return -1, "Invalid arg for appspawn child");
APPSPAWN_LOGI("AppSpawnChild id %{public}u flags: 0x%{public}x", client->id, client->flags);
if (content->setAppSandbox) {
ret = content->setAppSandbox(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to set app sandbox");
}
int ret = AppSpawnExecuteClearEnvHook(content, client);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0,
NotifyResToParent(content, client, ret);
return 0);
(void)umask(DEFAULT_UMASK);
if (content->setKeepCapabilities) {
ret = content->setKeepCapabilities(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret);
return ret, "Failed to set KeepCapabilities");
}
if (content->setXpmConfig) {
ret = content->setXpmConfig(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to set setXpmConfig");
}
if (content->setProcessName) {
ret = content->setProcessName(content, client, content->longProcName, content->longProcNameLen);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to set setProcessName");
}
if (content->setUidGid) {
ret = content->setUidGid(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to setUidGid");
}
if (content->setFileDescriptors) {
ret = content->setFileDescriptors(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to setFileDescriptors");
}
if (content->setCapabilities) {
ret = content->setCapabilities(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to setCapabilities");
}
if (content->waitForDebugger) {
ret = content->waitForDebugger(client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to waitForDebugger");
}
#ifdef SECURITY_COMPONENT_ENABLE
InitSecCompClientEnhance();
#endif
// notify success to father process and start app process
NotifyResToParent(content, client, 0);
return 0;
}
static int AppSpawnChild(void *arg)
{
APPSPAWN_CHECK(arg != NULL, return -1, "Invalid arg for appspawn child");
AppSandboxArg *sandbox = (AppSandboxArg *)arg;
struct AppSpawnContent *content = sandbox->content;
AppSpawnClient *client = sandbox->client;
int ret = -1;
if (content->setProcessName) {
ret = content->setProcessName(content, client, content->longProcName, content->longProcNameLen);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to set setProcessName");
}
#ifdef OHOS_DEBUG
struct timespec tmStart = {0};
clock_gettime(CLOCK_REALTIME, &tmStart);
#endif
// close socket id and signal for child
if (content->clearEnvironment != NULL) {
content->clearEnvironment(content, client);
}
if (content->setAppAccessToken != NULL) {
ret = content->setAppAccessToken(content, client);
APPSPAWN_CHECK(ret == 0, return -1, "AppSpawnChild, set app token id failed");
}
if (content->setEnvInfo) {
ret = content->setEnvInfo(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); return ret, "Failed to setEnvInfo");
}
if ((content->getWrapBundleNameValue != NULL && content->getWrapBundleNameValue(content, client) == 0) ||
((client->flags & APP_COLD_START) != 0)) {
if (client->flags & APP_COLD_START) {
// cold start fail, to start normal
if (content->coldStartApp != NULL && content->coldStartApp(content, client) == 0) {
return 0;
}
APPSPAWN_LOGW("AppSpawnChild cold start fail %{public}u", client->id);
}
#ifndef OHOS_LITE
// enable cache for app process
mallopt(M_OHOS_CONFIG, M_TCACHE_PERFORMANCE_MODE);
mallopt(M_OHOS_CONFIG, M_ENABLE_OPT_TCACHE);
mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_ENABLE);
mallopt(M_DELAYED_FREE, M_DELAYED_FREE_ENABLE);
#endif
ret = DoStartApp(content, client, content->longProcName, content->longProcNameLen);
if (content->initDebugParams != NULL) {
content->initDebugParams(content, client);
ret = AppSpawnExecuteSpawningHook(content, client);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0,
NotifyResToParent(content, client, ret);
return 0);
ret = AppSpawnExecutePreReplyHook(content, client);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0,
NotifyResToParent(content, client, ret);
return 0);
// notify success to father process and start app process
NotifyResToParent(content, client, 0);
(void)AppSpawnExecutePostReplyHook(content, client);
if (content->runChildProcessor != NULL) {
ret = content->runChildProcessor(content, client);
}
#ifdef OHOS_DEBUG
long long diff = DiffTime(&tmStart);
APPSPAWN_LOGI("App timeused %{public}d %lld ns.", getpid(), diff);
#endif
if (ret == 0 && content->runChildProcessor != NULL) {
content->runChildProcessor(content, client);
if (ret != 0) {
AppSpawnEnvClear(content, client);
}
return 0;
}
static int CloneAppSpawn(void *arg)
{
ProcessExit(AppSpawnChild(arg));
APPSPAWN_CHECK(arg != NULL, return -1, "Invalid content for appspawn");
AppSpawnForkArg *forkArg = (AppSpawnForkArg *)arg;
ProcessExit(AppSpawnChild(forkArg->content, forkArg->client));
return 0;
}
static int ForkProcess(AppSandboxArg *sandbox)
int AppSpawnProcessMsg(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid)
{
pid_t pid = fork();
if (pid == 0) {
ProcessExit(AppSpawnChild((void *)sandbox));
}
return pid;
}
// after calling setns, new process will be in the same pid namespace of the input pid
static int SetPidNamespace(int nsPidFd, int nsType)
{
if (setns(nsPidFd, nsType) < 0) {
APPSPAWN_LOGE("set pid namespace nsType:%{pudblic}d failed", nsType);
return -1;
}
return 0;
}
int AppSpawnProcessMsg(AppSandboxArg *sandbox, pid_t *childPid)
{
APPSPAWN_CHECK(sandbox != NULL && sandbox->content != NULL, return -1, "Invalid content for appspawn");
APPSPAWN_CHECK(sandbox->client != NULL && childPid != NULL, return -1, "Invalid client for appspawn");
APPSPAWN_LOGI("AppSpawnProcessMsg id %{public}d 0x%{public}x", sandbox->client->id, sandbox->client->flags);
APPSPAWN_CHECK(content != NULL, return -1, "Invalid content for appspawn");
APPSPAWN_CHECK(client != NULL && childPid != NULL, return -1, "Invalid client for appspawn");
APPSPAWN_LOGI("AppSpawnProcessMsg id: %{public}d mode: %{public}d sandboxNsFlags: 0x%{public}x",
client->id, content->mode, content->sandboxNsFlags);
pid_t pid = 0;
if (sandbox->content->isNweb) {
pid = clone(CloneAppSpawn, NULL, sandbox->client->cloneFlags | SIGCHLD, (void *)sandbox);
#ifndef OHOS_LITE
if (content->mode == MODE_FOR_NWEB_SPAWN) {
AppSpawnForkArg arg;
arg.client = client;
arg.content = content;
pid = clone(CloneAppSpawn, NULL, content->sandboxNsFlags | SIGCHLD, (void *)&arg);
} else {
if (sandbox->content->sandboxNsFlags & CLONE_NEWPID) {
SetPidNamespace(sandbox->content->nsInitPidFd, CLONE_NEWPID); // pid_ns_init is the init process
pid = ForkProcess(sandbox);
SetPidNamespace(sandbox->content->nsSelfPidFd, 0); // go back to original pid namespace
} else {
pid = ForkProcess(sandbox);
#else
{
#endif
pid = fork();
if (pid == 0) {
ProcessExit(AppSpawnChild(content, client));
}
}
APPSPAWN_CHECK(pid >= 0, return -errno, "fork child process error: %{public}d", -errno);
APPSPAWN_CHECK(pid >= 0, return APPSPAWN_FORK_FAIL, "fork child process error: %{public}d", errno);
*childPid = pid;
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -17,135 +17,52 @@
#define APPSPAWN_SERVER_H
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
#include "beget_ext.h"
#include "hilog/log.h"
#include "securec.h"
#include "appspawn_utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#define UNUSED(x) (void)(x)
#define APP_COLD_START 0x01
#define ERR_PIPE_FAIL (-100)
#define MAX_LEN_SHORT_NAME 16
#define WAIT_DELAY_US (100 * 1000) // 100ms
#define GID_FILE_ACCESS 1006 // only used for ExternalFileManager.hap
#define GID_USER_DATA_RW 1008
#define APPSPAWN_CHECK_EXIT "AppSpawnCheckUnexpectedExitCall"
typedef enum {
MODE_FOR_APP_SPAWN,
MODE_FOR_NWEB_SPAWN,
MODE_FOR_APP_COLD_RUN,
MODE_FOR_NWEB_COLD_RUN,
MODE_INVALID
} RunMode;
typedef struct AppSpawnClient {
uint32_t id;
uint32_t flags; // Save negotiated flags
uint32_t cloneFlags; // for clone flags
uint32_t flags; // Save negotiated flags
} AppSpawnClient;
#define MAX_SOCKEYT_NAME_LEN 128
typedef struct AppSpawnContent {
char *longProcName;
uint32_t longProcNameLen;
uint32_t sandboxNsFlags;
bool isNweb;
int nsSelfPidFd; // ns pid fd of appspawn
int nsInitPidFd; // ns pid fd of pid_ns_init
RunMode mode;
// system
void (*loadExtendLib)(struct AppSpawnContent *content);
int (*initAppSpawn)(struct AppSpawnContent *content);
void (*runAppSpawn)(struct AppSpawnContent *content, int argc, char *const argv[]);
void (*setUidGidFilter)(struct AppSpawnContent *content);
// for child
void (*clearEnvironment)(struct AppSpawnContent *content, AppSpawnClient *client);
void (*initDebugParams)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setAppAccessToken)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setAppSandbox)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setKeepCapabilities)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setFileDescriptors)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setEnvInfo)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setProcessName)(struct AppSpawnContent *content, AppSpawnClient *client,
char *longProcName, uint32_t longProcNameLen);
int (*setUidGid)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setCapabilities)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setXpmConfig)(struct AppSpawnContent *content, AppSpawnClient *client);
void (*notifyResToParent)(struct AppSpawnContent *content, AppSpawnClient *client, int result);
void (*runChildProcessor)(struct AppSpawnContent *content, AppSpawnClient *client);
#ifndef ASAN_DETECTOR
int (*setAsanEnabledEnv)(struct AppSpawnContent *content, AppSpawnClient *client);
#endif
// for pid namespace
int (*enablePidNs)(struct AppSpawnContent *content);
int (*runChildProcessor)(struct AppSpawnContent *content, AppSpawnClient *client);
// for cold start
int (*coldStartApp)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*getWrapBundleNameValue)(struct AppSpawnContent *content, AppSpawnClient *client);
int (*setSeccompFilter)(struct AppSpawnContent *content, AppSpawnClient *client);
void (*handleInternetPermission)(const AppSpawnClient *client);
int (*waitForDebugger)(AppSpawnClient *client);
} AppSpawnContent;
typedef struct {
typedef struct TagAppSpawnForkArg {
struct AppSpawnContent *content;
AppSpawnClient *client;
} AppSandboxArg;
} AppSpawnForkArg;
AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcName, uint32_t longProcNameLen, int cold);
int AppSpawnProcessMsg(AppSandboxArg *sandbox, pid_t *childPid);
int DoStartApp(struct AppSpawnContent *content, AppSpawnClient *client, char *longProcName, uint32_t longProcNameLen);
long long DiffTime(struct timespec *startTime);
pid_t AppSpawnFork(int (*childFunc)(void *arg), void *args);
#define UNUSED(x) (void)(x)
#ifndef OHOS_LITE
#undef LOG_TAG
#define LOG_TAG "APPSPAWN"
#undef LOG_DOMAIN
#define LOG_DOMAIN (BASE_DOMAIN + 0x11)
#define APPSPAWN_LOGI(fmt, ...) \
HILOG_INFO(LOG_CORE, "[%{public}s:%{public}d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGE(fmt, ...) \
HILOG_ERROR(LOG_CORE, "[%{public}s:%{public}d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGV(fmt, ...) \
HILOG_DEBUG(LOG_CORE, "[%{public}s:%{public}d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGW(fmt, ...) \
HILOG_WARN(LOG_CORE, "[%{public}s:%{public}d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGF(fmt, ...) \
HILOG_FATAL(LOG_CORE, "[%{public}s:%{public}d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#else
#define APPSPAWN_LOGI(fmt, ...) \
HILOG_INFO(HILOG_MODULE_HIVIEW, "[%s:%d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGE(fmt, ...) \
HILOG_ERROR(HILOG_MODULE_HIVIEW, "[%s:%d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGV(fmt, ...) \
HILOG_DEBUG(HILOG_MODULE_HIVIEW, "[%s:%d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGW(fmt, ...) \
HILOG_FATAL(HILOG_MODULE_HIVIEW, "[%s:%d]" fmt, (FILE_NAME), (__LINE__), ##__VA_ARGS__)
#endif
#define APPSPAWN_CHECK(retCode, exper, fmt, ...) \
if (!(retCode)) { \
APPSPAWN_LOGE(fmt, ##__VA_ARGS__); \
exper; \
}
#define APPSPAWN_CHECK_ONLY_EXPER(retCode, exper) \
if (!(retCode)) { \
exper; \
} \
#define APPSPAWN_CHECK_ONLY_LOG(retCode, fmt, ...) \
if (!(retCode)) { \
APPSPAWN_LOGE(fmt, ##__VA_ARGS__); \
}
int AppSpawnExecuteClearEnvHook(AppSpawnContent *content, AppSpawnClient *client);
int AppSpawnExecuteSpawningHook(AppSpawnContent *content, AppSpawnClient *client);
int AppSpawnExecutePreReplyHook(AppSpawnContent *content, AppSpawnClient *client);
int AppSpawnExecutePostReplyHook(AppSpawnContent *content, AppSpawnClient *client);
void AppSpawnEnvClear(AppSpawnContent *content, AppSpawnClient *client);
int AppSpawnProcessMsg(AppSpawnContent *content, AppSpawnClient *client, pid_t *childPid);
#ifdef __cplusplus
}

View File

@ -15,19 +15,34 @@ import("//base/startup/appspawn/appspawn.gni")
import("//base/startup/appspawn/etc/sandbox/appdata_sandbox_fixer.gni")
import("//build/ohos.gni")
ohos_prebuilt_appdata_sandbox("appdata-sandbox.json") {
source = "../appdata-sandbox.json"
patterns = []
extra_sandbox_cfgs = []
if (target_cpu == "arm64" || target_cpu == "x86_64") {
extra_sandbox_cfgs += [ "../appdata-sandbox64.json" ]
if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) {
ohos_prebuilt_etc("appdata-sandbox-nweb.json") {
source = "../appdata-sandbox-nweb.json"
part_name = "${part_name}"
module_install_dir = "etc/sandbox"
}
if (is_asan) {
extra_sandbox_cfgs += [ "../appdata-sandbox-asan.json" ]
ohos_prebuilt_etc("appdata-sandbox.json") {
source = "../appdata-sandbox-app.json"
output = "appdata-sandbox.json"
part_name = "${part_name}"
module_install_dir = "etc/sandbox"
}
} else {
ohos_prebuilt_appdata_sandbox("appdata-sandbox.json") {
source = "../appdata-sandbox.json"
patterns = []
extra_sandbox_cfgs = []
if (target_cpu == "arm64" || target_cpu == "x86_64") {
extra_sandbox_cfgs += [ "../appdata-sandbox64.json" ]
}
if (is_asan) {
extra_sandbox_cfgs += [ "../appdata-sandbox-asan.json" ]
}
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
module_install_dir = "etc/sandbox"
}
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
module_install_dir = "etc/sandbox"
}
ohos_prebuilt_etc("appspawn_preload.json") {
@ -41,4 +56,7 @@ group("etc_files") {
":appdata-sandbox.json",
":appspawn_preload.json",
]
if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) {
deps += [ ":appdata-sandbox-nweb.json" ]
}
}

View File

@ -27,6 +27,8 @@ ohos_static_library("appspawn_socket_client") {
"src/appspawn_mount_permission.cpp",
]
include_dirs = [
"//base/startup/appspawn",
"//base/startup/appspawn/util/include",
"include",
"//base/startup/appspawn/common",
"//third_party/json/include",

View File

@ -23,7 +23,6 @@ if (!defined(ohos_lite)) {
ohos_shared_library("appspawn_client") {
sources = [
"${appspawn_path}/modules/sandbox/appspawn_permission.c",
"${appspawn_path}/util/src/appspawn_utils.c",
"../permission/appspawn_mount_permission.c",
"appspawn_client.c",
"appspawn_msg.c",
@ -32,18 +31,20 @@ if (!defined(ohos_lite)) {
".",
"../include",
"../permission",
"../module_engine/include",
"${appspawn_path}/modules/module_engine/include",
"${appspawn_path}",
"${appspawn_path}/common",
"${appspawn_path}/modules/sandbox",
"${appspawn_path}/util/include",
"${appspawn_path}/modules//module_engine//include",
]
defines = [
"APPSPAWN_CLIENT",
"APPSPAWN_LABEL=\"APPSPAWN_CLIENT\"",
]
if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) {
defines += [ "APPSPAWN_SANDBOX_NEW" ]
}
if (is_asan) {
defines += [ "APPSPAWN_ASAN" ]
}
@ -53,6 +54,7 @@ if (!defined(ohos_lite)) {
public_configs = [ ":exported_header_files" ]
version_script = "libappspawn_client.versionscript"
deps = [ "${appspawn_path}/util:libappspawn_util" ]
external_deps = [
"cJSON:cjson",
"c_utils:utils",

View File

@ -518,15 +518,3 @@ int AppSpawnTerminateMsgCreate(pid_t pid, AppSpawnReqMsgHandle *reqHandle)
*reqHandle = (AppSpawnReqMsgHandle)(reqNode);
return 0;
}
int AppSpawnReqMsgSetFlags(AppSpawnReqMsgHandle reqHandle, uint32_t tlv, uint32_t flags)
{
AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
if (tlv == TLV_MSG_FLAGS) {
*(uint32_t *)reqNode->msgFlags->flags = flags;
} else if (tlv == TLV_PERMISSION) {
*(uint32_t *)reqNode->permissionFlags->flags = flags;
}
return 0;
}

View File

@ -93,8 +93,8 @@ int AppSpawnClientSendMsg(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqH
typedef enum {
MSG_APP_SPAWN = 0,
MSG_SPAWN_NATIVE_PROCESS,
MSG_GET_RENDER_TERMINATION_STATUS,
MSG_SPAWN_NATIVE_PROCESS,
MSG_DUMP,
MAX_TYPE_INVALID
} AppSpawnMsgType;
@ -155,6 +155,7 @@ typedef enum {
APP_FLAGS_BUNDLE_RESOURCES = 9,
APP_FLAGS_GWP_ENABLED_FORCE, // APP_GWP_ENABLED_FORCE 0x400
APP_FLAGS_GWP_ENABLED_NORMAL, // APP_GWP_ENABLED_NORMAL 0x800
APP_FLAGS_TSAN_ENABLED, // APP_TSANENABLED 0x1000
MAX_FLAGS_INDEX = 63,
} AppFlagsIndex;

View File

@ -12,20 +12,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <pthread.h>
#include <stdlib.h>
#include <pthread.h>
#ifdef APPSPAWN_CLIENT
#include "appspawn_mount_permission.h"
#else
#include "appspawn_sandbox.h"
#endif
#include "appspawn_msg.h"
#include "appspawn_permission.h"
#include "appspawn_utils.h"
#include "cJSON.h"
#include "json_utils.h"
#include "securec.h"
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static int32_t g_maxPermissionIndex = -1;
static SandboxQueue g_permissionQueue = {0};
#ifdef APPSPAWN_SANDBOX_NEW
static int ParseAppSandboxConfig(const cJSON *root, ParseJsonContext *context)
{
// conditional
cJSON *json = cJSON_GetObjectItemCaseSensitive(root, "conditional");
if (json == NULL) {
return 0;
}
// permission
cJSON *config = cJSON_GetObjectItemCaseSensitive(json, "permission");
if (config == NULL || !cJSON_IsArray(config)) {
return 0;
}
uint32_t configSize = cJSON_GetArraySize(config);
for (uint32_t i = 0; i < configSize; i++) {
cJSON *json = cJSON_GetArrayItem(config, i);
if (json == NULL) {
continue;
}
char *name = GetStringFromJsonObj(json, "name");
if (name == NULL) {
APPSPAWN_LOGE("No name in permission configs");
continue;
}
int ret = AddSandboxPermissionNode(name, &g_permissionQueue);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
}
return 0;
}
#else
static int ParsePermissionConfig(const cJSON *permissionConfigs)
{
cJSON *config = NULL;
@ -53,6 +89,7 @@ static int ParseAppSandboxConfig(const cJSON *appSandboxConfig, ParseJsonContext
}
return ret;
}
#endif
static int LoadPermissionConfig(void)
{
@ -83,7 +120,11 @@ const char *GetPermissionByIndex(int32_t index)
return NULL;
}
const SandboxPermissionNode *node = GetPermissionNodeInQueueByIndex(&g_permissionQueue, index);
#ifdef APPSPAWN_CLIENT
return node == NULL ? NULL : node->name;
#else
return node == NULL ? NULL : node->section.name;
#endif
}
static void LoadPermission(void)

View File

@ -31,7 +31,8 @@ typedef struct TagSandboxQueue {
} SandboxQueue;
typedef struct TagParseJsonContext {
uint32_t type;
SandboxQueue permissionQueue;
int32_t maxPermissionIndex;
} ParseJsonContext;
typedef struct {

View File

@ -47,6 +47,7 @@ executable("appspawn") {
".",
"../common",
"//base/startup/appspawn/interfaces/innerkits/include",
"//base/startup/appspawn/util/include",
"//base/startup/init/interfaces/innerkits/include",
"//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr",
"//foundation/systemabilitymgr/samgr_lite/interfaces/kits/registry",

View File

@ -180,18 +180,46 @@ static void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client)
void SetContentFunction(AppSpawnContent *content)
{
APPSPAWN_LOGI("SetContentFunction");
content->setProcessName = SetProcessName;
content->setKeepCapabilities = SetKeepCapabilities;
content->setUidGid = SetUidGid;
content->setCapabilities = SetCapabilities;
content->runChildProcessor = RunChildProcessor;
content->setFileDescriptors = NULL;
content->setAppSandbox = NULL;
content->setAppAccessToken = NULL;
content->notifyResToParent = NULL;
content->loadExtendLib = NULL;
content->initAppSpawn = NULL;
content->runAppSpawn = NULL;
content->clearEnvironment = NULL;
}
int AppSpawnExecuteSpawningHook(AppSpawnContent *content, AppSpawnClient *client)
{
(void)umask(DEFAULT_UMASK);
int ret = SetKeepCapabilities(content, client);
if (ret != 0) {
return ret;
}
ret = SetProcessName(content, client, content->longProcName, content->longProcNameLen);
if (ret != 0) {
return ret;
}
ret = SetUidGid(content, client);
if (ret != 0) {
return ret;
}
ret = SetCapabilities(content, client);
if (ret != 0) {
return ret;
}
return 0;
}
int AppSpawnExecuteClearEnvHook(AppSpawnContent *content, AppSpawnClient *client)
{
return 0;
}
int AppSpawnExecutePreReplyHook(AppSpawnContent *content, AppSpawnClient *client)
{
return 0;
}
int AppSpawnExecutePostReplyHook(AppSpawnContent *content, AppSpawnClient *client)
{
return 0;
}
void AppSpawnEnvClear(AppSpawnContent *content, AppSpawnClient *client)
{
}

View File

@ -31,6 +31,19 @@
static const int INVALID_PID = -1;
static const int CLIENT_ID = 100;
#ifdef OHOS_DEBUG
uint64_t DiffTime(const struct timespec *startTime, const struct timespec *endTime)
{
uint64_t diff = (uint64_t)((endTime->tv_sec - startTime->tv_sec) * 1000000); // 1000000 s-us
if (endTime->tv_nsec > startTime->tv_nsec) {
diff += (endTime->tv_nsec - startTime->tv_nsec) / 1000; // 1000 ns - us
} else {
diff -= (startTime->tv_nsec - endTime->tv_nsec) / 1000; // 1000 ns - us
}
return diff;
}
#endif
typedef struct AppSpawnFeatureApi {
INHERIT_SERVER_IPROXY;
} AppSpawnFeatureApi;
@ -131,7 +144,6 @@ static int Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, Ip
AppSpawnClientLite client = {};
client.client.id = CLIENT_ID;
client.client.flags = 0;
client.client.cloneFlags = 0;
if (GetMessageSt(&client.message, req) != EC_SUCCESS) {
APPSPAWN_LOGE("[appspawn] invoke, parse failed! reply %d.", INVALID_PID);
WriteInt64(reply, INVALID_PID);
@ -140,27 +152,18 @@ static int Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, Ip
APPSPAWN_LOGI("[appspawn] invoke, msg<%s,%s,%d,%d %d>", client.message.bundleName, client.message.identityID,
client.message.uID, client.message.gID, client.message.capsCnt);
/* Clone support only one parameter, so need to package application parameters */
AppSandboxArg *sandboxArg = (AppSandboxArg *)malloc(sizeof(AppSandboxArg));
if (sandboxArg == NULL) {
WriteInt64(reply, INVALID_PID);
return EC_FAILURE;
}
(void)memset_s(sandboxArg, sizeof(AppSandboxArg), 0, sizeof(AppSandboxArg));
pid_t newPid = 0;
sandboxArg->content = &g_appSpawnContentLite->content;
sandboxArg->client = &client.client;
int ret = AppSpawnProcessMsg(sandboxArg, &newPid);
int ret = AppSpawnProcessMsg(&g_appSpawnContentLite->content, &client.client, &newPid);
if (ret != 0) {
newPid = -1;
}
FreeMessageSt(&client.message);
WriteInt64(reply, newPid);
free(sandboxArg);
#ifdef OHOS_DEBUG
long long diff = DiffTime(&tmStart);
struct timespec tmEnd = {0};
clock_gettime(CLOCK_MONOTONIC, &tmEnd);
long long diff = DiffTime(&tmStart, &tmEnd);
APPSPAWN_LOGI("[appspawn] invoke, reply pid %d, timeused %lld ns.", newPid, diff);
#else
APPSPAWN_LOGI("[appspawn] invoke, reply pid %d.", newPid);

View File

@ -46,6 +46,12 @@ static int SetAsanEnabledEnv(const AppSpawnMgr *content, const AppSpawningCtx *p
setenv("ASAN_OPTIONS", asanOptions, 1);
return 0;
}
if (CheckAppMsgFlagsSet(property, APP_FLAGS_TSAN_ENABLED)) {
setenv("LD_PRELOAD", "/system/lib64/libclang_rt.tsan.so", 1);
unsetenv("UBSAN_OPTIONS");
setenv("TSAN_OPTIONS", "include=/system/etc/tsan.options", 1);
return 0;
}
return -1;
}

View File

@ -40,8 +40,10 @@ ohos_shared_library("appspawn_common") {
]
if (build_selinux) {
defines += [ "WITH_SELINUX" ]
deps += [ "//third_party/selinux:libselinux" ]
external_deps += [ "selinux_adapter:libhap_restorecon" ]
external_deps += [
"selinux:libselinux",
"selinux_adapter:libhap_restorecon",
]
}
if (build_seccomp) {
defines += [ "WITH_SECCOMP" ]

View File

@ -220,7 +220,16 @@ static int SetUidGid(const AppSpawnMgr *content, const AppSpawningCtx *property)
"setgroups failed: %{public}d, gids.size=%{public}u", errno, dacInfo->gidCount);
// set gid
ret = setresgid(dacInfo->gid, dacInfo->gid, dacInfo->gid);
if (IsNWebSpawnMode(content)) {
gid_t gid = dacInfo->gid / UID_BASE;
if (gid >= 100) { // 100
APPSPAWN_LOGE("SetUidGid invalid uid for nwebspawn %{public}d", dacInfo->gid);
return 0;
}
ret = setresgid(dacInfo->gid, dacInfo->gid, dacInfo->gid);
} else {
ret = setresgid(dacInfo->gid, dacInfo->gid, dacInfo->gid);
}
APPSPAWN_CHECK(ret == 0, return errno,
"setgid(%{public}u) failed: %{public}d", dacInfo->gid, errno);

View File

@ -149,6 +149,7 @@ static int NsInitFunc()
setcon("u:r:pid_ns_init:s0");
char *argv[] = {"/system/bin/pid_ns_init", NULL};
execve("/system/bin/pid_ns_init", argv, NULL);
_exit(0);
return 0;
}
@ -174,6 +175,9 @@ static int PreLoadEnablePidNs(AppSpawnMgr *content)
if (IsColdRunMode(content)) {
return 0;
}
if (IsNWebSpawnMode(content)) { // only for appspawn
return 0;
}
if (!(content->content.sandboxNsFlags & CLONE_NEWPID)) {
return 0;
}
@ -222,7 +226,7 @@ static int SetPidNamespace(int nsPidFd, int nsType)
{
APPSPAWN_LOGI("SetPidNamespace 0x%{public}x", nsType);
if (setns(nsPidFd, nsType) < 0) {
APPSPAWN_LOGE("set pid namespace nsType:%{pudblic}d failed", nsType);
APPSPAWN_LOGE("set pid namespace nsType:%{public}d failed", nsType);
return -1;
}
return 0;

View File

@ -103,6 +103,7 @@ typedef struct {
typedef struct {
uint8_t setAllowInternet;
uint8_t allowInternet; // hap sockect allowed
uint8_t res[2];
} AppSpawnMsgInternetInfo;
typedef struct {

View File

@ -194,7 +194,11 @@ int AppSpawnHookExecute(AppSpawnHookStage stage, uint32_t flags, AppSpawnContent
options.preHook = PreAppSpawnHookExec;
options.postHook = PostAppSpawnHookExec;
int ret = HookMgrExecute(GetAppSpawnHookMgr(), stage, (void *)(&forkArg), &options);
return ret == ERR_NO_HOOK_STAGE ? 0 : ret;
ret = (ret == ERR_NO_HOOK_STAGE) ? 0 : ret;
if (ret != 0) {
APPSPAWN_LOGE("Execute hook [%{public}d] result %{public}d", stage, ret);
}
return ret;
}
int AppSpawnExecuteClearEnvHook(AppSpawnContent *content, AppSpawnClient *client)
@ -239,7 +243,8 @@ int AddAppSpawnHook(AppSpawnHookStage stage, int prio, AppSpawnHook hook)
int ProcessMgrHookExecute(AppSpawnHookStage stage, const AppSpawnContent *content,
const AppSpawnedProcessInfo *appInfo)
{
APPSPAWN_CHECK(content != NULL && appInfo != NULL, return APPSPAWN_ARG_INVALID, "Invalid hook");
APPSPAWN_CHECK(content != NULL && appInfo != NULL,
return APPSPAWN_ARG_INVALID, "Invalid hook");
APPSPAWN_CHECK((stage >= STAGE_SERVER_APP_ADD) && (stage <= STAGE_SERVER_APP_DIED),
return APPSPAWN_ARG_INVALID, "Invalid stage %{public}d", (int)stage);

View File

@ -14,44 +14,88 @@
import("//base/startup/appspawn/appspawn.gni")
import("//build/ohos.gni")
ohos_shared_library("appspawn_sandbox") {
sources = [
"appspawn_mount_template.c",
"appspawn_permission.c",
"appspawn_sandbox.c",
"sandbox_cfgvar.c",
"sandbox_expand.c",
"sandbox_load.c",
"sandbox_manager.c",
]
if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) {
ohos_shared_library("appspawn_sandbox") {
sources = [
"appspawn_mount_template.c",
"appspawn_permission.c",
"appspawn_sandbox.c",
"sandbox_cfgvar.c",
"sandbox_expand.c",
"sandbox_load.c",
"sandbox_manager.c",
]
include_dirs = [
".",
"${appspawn_path}/common",
"${appspawn_path}/standard",
]
include_dirs = [
".",
"${appspawn_path}/common",
"${appspawn_path}/standard",
]
configs = [ "${appspawn_path}:appspawn_config" ]
configs = [ "${appspawn_path}:appspawn_config" ]
defines = []
deps = [
"${appspawn_path}/modules/module_engine:libappspawn_module_engine",
"${appspawn_path}/util:libappspawn_util",
]
external_deps = [
"cJSON:cjson",
"c_utils:utils",
"hilog:libhilog",
"init:libbegetutil",
]
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
install_enable = true
if (target_cpu == "arm64" || target_cpu == "x86_64" ||
target_cpu == "riscv64") {
defines += [ "APPSPAWN_64" ]
module_install_dir = "lib64/appspawn/common"
} else {
module_install_dir = "lib/appspawn/common"
defines = [ "APPSPAWN_SANDBOX_NEW" ]
deps = [
"${appspawn_path}/modules/module_engine:libappspawn_module_engine",
"${appspawn_path}/util:libappspawn_util",
]
external_deps = [
"cJSON:cjson",
"c_utils:utils",
"hilog:libhilog",
"init:libbegetutil",
]
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
install_enable = true
if (target_cpu == "arm64" || target_cpu == "x86_64" ||
target_cpu == "riscv64") {
defines += [ "APPSPAWN_64" ]
module_install_dir = "lib64/appspawn/common"
} else {
module_install_dir = "lib/appspawn/common"
}
}
} else {
ohos_shared_library("appspawn_sandbox") {
sources = [
"${appspawn_innerkits_path}/permission/appspawn_mount_permission.c",
"appspawn_permission.c",
"sandbox_utils.cpp",
]
include_dirs = [
".",
"${appspawn_path}/common",
"${appspawn_path}/standard",
"${appspawn_innerkits_path}/permission",
"//third_party/json/include",
]
configs = [ "${appspawn_path}:appspawn_config" ]
defines = [ "APPSPAWN_CLIENT" ]
deps = [
"${appspawn_path}/modules/module_engine:libappspawn_module_engine",
"${appspawn_path}/util:libappspawn_util",
]
external_deps = [
"cJSON:cjson",
"c_utils:utils",
"config_policy:configpolicy_util",
"hilog:libhilog",
"init:libbegetutil",
]
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
install_enable = true
if (target_cpu == "arm64" || target_cpu == "x86_64" ||
target_cpu == "riscv64") {
defines += [ "APPSPAWN_64" ]
module_install_dir = "lib64/appspawn/common"
} else {
module_install_dir = "lib/appspawn/common"
}
}
}

View File

@ -223,7 +223,7 @@ const char *GetSandboxRealVar(const SandboxContext *context,
APPSPAWN_CHECK_ONLY_EXPER(sandboxBuffer != NULL && sandboxBuffer->buffer != NULL, return NULL);
const char *tmp = source;
int ret = 0;
if (prefix != NULL) { // copy prefix data
if (!IsPathEmpty(prefix)) { // copy prefix data
ret = HandleVariableReplace(context, sandboxBuffer, prefix, extraData);
APPSPAWN_CHECK(ret == 0, return NULL, "Failed to replace source %{public}s ", prefix);
@ -231,7 +231,7 @@ const char *GetSandboxRealVar(const SandboxContext *context,
tmp = source + 1;
}
}
if (tmp != NULL) { // copy source data
if (!IsPathEmpty(tmp)) { // copy source data
ret = HandleVariableReplace(context, sandboxBuffer, tmp, extraData);
APPSPAWN_CHECK(ret == 0, return NULL, "Failed to replace source %{public}s ", source);
}

View File

@ -77,6 +77,8 @@ SandboxMountNode *CreateSandboxMountNode(uint32_t dataLen, uint32_t type)
void AddSandboxMountNode(SandboxMountNode *node, SandboxSection *queue)
{
APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return);
APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return);
OH_ListAddWithOrder(&queue->front, &node->node, SandboxNodeCompareProc);
}
@ -130,6 +132,7 @@ SymbolLinkNode *GetSymbolLinkNode(const SandboxSection *section, const char *tar
void DeleteSandboxMountNode(SandboxMountNode *sandboxNode)
{
APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
OH_ListRemove(&sandboxNode->node);
OH_ListInit(&sandboxNode->node);
switch (sandboxNode->type) {
@ -149,7 +152,7 @@ void DeleteSandboxMountNode(SandboxMountNode *sandboxNode)
SandboxMountNode *GetFirstSandboxMountNode(const SandboxSection *section)
{
if (ListEmpty(section->front)) {
if (section == NULL || ListEmpty(section->front)) {
return NULL;
}
return (SandboxMountNode *)ListEntry(section->front.next, SandboxMountNode, node);
@ -157,6 +160,7 @@ SandboxMountNode *GetFirstSandboxMountNode(const SandboxSection *section)
void DumpSandboxMountNode(const SandboxMountNode *sandboxNode, uint32_t index)
{
APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
switch (sandboxNode->type) {
case SANDBOX_TAG_MOUNT_PATH:
case SANDBOX_TAG_MOUNT_FILE: {
@ -218,7 +222,6 @@ static void ClearSandboxSection(SandboxSection *section)
}
if (section->sandboxNode.type == SANDBOX_TAG_NAME_GROUP) {
SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section;
APPSPAWN_LOGV("Free deps %p ", groupNode->depNode);
if (groupNode->depNode) {
DeleteSandboxMountNode((SandboxMountNode *)groupNode->depNode);
}
@ -477,7 +480,7 @@ void DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox)
DumpSandboxQueue(&sandbox->nameGroupsQueue.front, DumpSandboxNameGroupNode);
}
static int PreLoadSandboxCfg(AppSpawnMgr *content)
APPSPAWN_STATIC int PreLoadSandboxCfg(AppSpawnMgr *content)
{
AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
APPSPAWN_CHECK(sandbox == NULL, return 0, "Sandbox has been load");
@ -497,7 +500,7 @@ static int PreLoadSandboxCfg(AppSpawnMgr *content)
return 0;
}
static int SandboxHandleServerExit(AppSpawnMgr *content)
APPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
{
AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
@ -523,6 +526,10 @@ int SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
if (strncmp(GetBundleName(property), MODULE_TEST_BUNDLE_NAME, strlen(MODULE_TEST_BUNDLE_NAME)) == 0) {
return 0;
}
// no sandbox
if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
return 0;
}
return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
}
@ -588,7 +595,7 @@ int SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
return 0;
}
static int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
APPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
{
APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1);
@ -597,6 +604,7 @@ static int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProces
return UnmountDepPaths(sandbox, appInfo->uid);
}
#ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)
{
APPSPAWN_LOGV("Load sandbox module ...");
@ -612,3 +620,4 @@ MODULE_DESTRUCTOR(void)
ClearVariable();
ClearExpandAppSandboxConfigHandle();
}
#endif

1559
modules/sandbox/sandbox_utils.cpp Executable file

File diff suppressed because it is too large Load Diff

130
modules/sandbox/sandbox_utils.h Executable file
View File

@ -0,0 +1,130 @@
/*
* Copyright (C) 2022-2023 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 SANDBOX_UTILS_H
#define SANDBOX_UTILS_H
#include <set>
#include <string>
#include <sys/mount.h>
#include <sys/types.h>
#include <vector>
#include "nlohmann/json.hpp"
#include "appspawn_server.h"
#include "appspawn_manager.h"
namespace OHOS {
namespace AppSpawn {
class SandboxUtils {
public:
static void StoreJsonConfig(nlohmann::json &appSandboxConfig);
static std::vector<nlohmann::json> &GetJsonConfig();
static int32_t SetAppSandboxProperty(AppSpawningCtx *client);
static int32_t SetAppSandboxPropertyNweb(AppSpawningCtx *client);
static uint32_t GetSandboxNsFlags(bool isNweb);
static std::set<std::string> GetMountPermissionNames();
static std::string GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type);
typedef struct {
unsigned long mountFlags;
std::string optionsPoint;
std::string fsType;
std::string sandboxPath;
} SandboxMountConfig;
#ifndef APPSPAWN_TEST
private:
#endif
static int32_t DoAppSandboxMountOnce(const char *originPath, const char *destinationPath,
const char *fsType, unsigned long mountFlags,
const char *options, mode_t mountSharedFlag = MS_SLAVE);
static int32_t DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig);
static int32_t DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty,
nlohmann::json &wholeConfig);
static int32_t DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig);
static int32_t DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty,
nlohmann::json &wholeConfig);
static int32_t DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty,
nlohmann::json &wholeConfig);
static int32_t DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty,
nlohmann::json &wholeConfig);
static int32_t HandleFlagsPoint(const AppSpawningCtx *appProperty,
nlohmann::json &wholeConfig);
static int32_t SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty);
static int32_t SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty,
std::string &sandboxPackagePath);
static int32_t MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath);
static int32_t MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath);
static int32_t DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath);
static int32_t DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty,
std::string &sandboxPackagePath);
static void DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot);
static int DoAllMntPointsMount(const AppSpawningCtx *appProperty,
nlohmann::json &appConfig, const std::string &section = "app-base");
static int DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, nlohmann::json &appConfig);
static std::string ConvertToRealPath(const AppSpawningCtx *appProperty, std::string sandboxRoot);
static std::string ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty,
std::string sandboxRoot);
static std::string GetSbxPathByConfig(const AppSpawningCtx *appProperty, nlohmann::json &config);
static bool CheckTotalSandboxSwitchStatus(const AppSpawningCtx *appProperty);
static bool CheckAppSandboxSwitchStatus(const AppSpawningCtx *appProperty);
static bool CheckBundleNameForPrivate(const std::string &bundleName);
static bool GetSbxSwitchStatusByConfig(nlohmann::json &config);
static unsigned long GetMountFlagsFromConfig(const std::vector<std::string> &vec);
static int32_t SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty,
nlohmann::json &config);
static int32_t SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty,
nlohmann::json &config);
static int32_t SetRenderSandboxProperty(const AppSpawningCtx *appProperty,
std::string &sandboxPackagePath);
static int32_t SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty,
std::string &sandboxPackagePath);
static int32_t SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty,
std::string &sandboxPackagePath);
static int32_t SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty,
std::string &sandboxPackagePath);
static int32_t DoSandboxFilePermissionBind(AppSpawningCtx *appProperty,
nlohmann::json &wholeConfig);
static int32_t SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty,
nlohmann::json &config);
static int32_t SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty);
static int32_t DoAddGid(AppSpawningCtx *appProperty, nlohmann::json &appConfig,
const char* permissionName, const std::string &section);
static bool CheckAppFullMountEnable();
static int32_t SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath);
static int32_t ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName,
bool sandboxSharedStatus);
static int32_t GetMountPermissionFlags(const std::string permissionName);
static bool GetSandboxDacOverrideEnable(nlohmann::json &config);
static unsigned long GetSandboxMountFlags(nlohmann::json &config);
static std::string GetSandboxFsType(nlohmann::json &config);
static std::string GetSandboxOptions(nlohmann::json &config);
static std::string GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint,
const std::string &section, std::string sandboxRoot);
static void GetSandboxMountConfig(const std::string &section, nlohmann::json &mntPoint,
SandboxMountConfig &mountConfig);
static std::vector<nlohmann::json> appSandboxConfig_;
static bool deviceTypeEnable_;
};
class JsonUtils {
public:
static bool GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath);
static bool GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value);
};
} // namespace AppSpawn
} // namespace OHOS
int LoadAppSandboxConfig(AppSpawnMgr *content);
#endif // SANDBOX_UTILS_H

127
standard/BUILD.gn Executable file
View File

@ -0,0 +1,127 @@
# Copyright (c) 2021-2022 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.
import("//base/startup/appspawn/appspawn.gni")
import("//build/ohos.gni")
import("//build/ohos/native_stub/native_stub.gni")
config("appspawn_server_config") {
visibility = [ ":*" ]
include_dirs = [
"${appspawn_path}/common",
"${appspawn_path}/standard",
"${appspawn_path}/modules/modulemgr",
]
cflags = []
if (build_selinux) {
cflags += [ "-DWITH_SELINUX" ]
}
if (build_seccomp) {
cflags += [ "-DWITH_SECCOMP" ]
}
configs = [ "${appspawn_path}:appspawn_config" ]
}
ohos_executable("appspawn") {
sources = [
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/modules/modulemgr/appspawn_modulemgr.c",
"${appspawn_path}/standard/appspawn_appmgr.c",
"${appspawn_path}/standard/appspawn_main.c",
"${appspawn_path}/standard/appspawn_msgmgr.c",
"${appspawn_path}/standard/appspawn_service.c",
"${appspawn_path}/standard/nwebspawn_launcher.c",
]
defines = []
configs = [
":appspawn_server_config",
"${appspawn_path}:appspawn_config",
]
deps = [
"${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript",
"${appspawn_path}/util:libappspawn_util",
]
if (asan_detector || is_asan) {
defines += [ "ASAN_DETECTOR" ]
}
external_deps = [
"c_utils:utils",
"config_policy:configpolicy_util",
"hilog:libhilog",
"init:libbegetutil",
]
if (build_selinux) {
defines += [ "WITH_SELINUX" ]
external_deps += [
"selinux:libselinux",
"selinux_adapter:libhap_restorecon",
]
}
cflags = []
#ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64z" ]
if (!defined(global_parts_info) ||
defined(global_parts_info.security_code_signature)) {
defines += [ "CODE_SIGNATURE_ENABLE" ]
external_deps += [ "code_signature:libcode_sign_attr_utils" ]
}
version_script = get_label_info(
"${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript",
"target_gen_dir") + "/" + get_label_info(
"${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript",
"name") + stub_version_script_suffix
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_shared_library("appspawn_helper") {
sources = [ "${appspawn_path}/common/appspawn_server.c" ]
defines = [ "APPSPAWN_HELPER" ]
configs = [
":appspawn_server_config",
"${appspawn_path}:appspawn_config",
]
cflags = [
"-fvisibility=hidden",
"-fstack-protector-all",
]
external_deps = [
"hilog:libhilog",
"init:libbegetutil",
]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_prebuilt_etc("appspawn.rc") {
source = "appspawn.cfg"
relative_install_dir = "init"
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}
ohos_executable("pid_ns_init") {
sources = [ "${appspawn_path}/standard/pid_ns_init.c" ]
install_enable = true
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}

View File

@ -20,7 +20,7 @@
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
@ -231,7 +231,7 @@ AppSpawningCtx *CreateAppSpawningCtx(void)
property->forkCtx.timer = NULL;
property->forkCtx.fd[0] = -1;
property->forkCtx.fd[1] = -1;
property->forkCtx.shmId = -1;
property->forkCtx.childMsg = NULL;
property->message = NULL;
property->pid = 0;
property->state = APP_STATE_IDLE;
@ -245,8 +245,22 @@ AppSpawningCtx *CreateAppSpawningCtx(void)
void DeleteAppSpawningCtx(AppSpawningCtx *property)
{
APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return);
APPSPAWN_LOGV("DeleteAppSpawningCtx");
if (property->forkCtx.childMsg != NULL) {
munmap((char *)property->forkCtx.childMsg, property->forkCtx.msgSize);
property->forkCtx.childMsg = NULL;
if (property->message != NULL) {
char path[PATH_MAX] = {};
int len = sprintf_s(path, sizeof(path),
APPSPAWN_MSG_DIR "/%s_%d", property->message->msgHeader.processName, property->client.id);
if (len > 0) {
unlink(path);
}
}
}
DeleteAppSpawnMsg(property->message);
APPSPAWN_LOGV("DeleteAppSpawningCtx %{public}d %{public}d", property->forkCtx.fd[0], property->forkCtx.fd[1]);
OH_ListRemove(&property->node);
if (property->forkCtx.timer) {
LE_StopTimer(LE_GetDefaultLoop(), property->forkCtx.timer);
@ -266,10 +280,7 @@ void DeleteAppSpawningCtx(AppSpawningCtx *property)
if (property->forkCtx.fd[1] >= 0) {
close(property->forkCtx.fd[1]);
}
if (property->forkCtx.shmId >= 0) {
(void)shmctl(property->forkCtx.shmId, IPC_RMID, NULL);
property->forkCtx.shmId = -1;
}
free(property);
}
@ -346,7 +357,9 @@ static int DumpAppQueue(ListNode *node, void *data)
static int DumpExtData(ListNode *node, void *data)
{
AppSpawnExtData *extData = ListEntry(node, AppSpawnExtData, node);
extData->dumpNode(extData);
if (extData->dumpNode) {
extData->dumpNode(extData);
}
return 0;
}

View File

@ -70,11 +70,11 @@ int main(int argc, char *const argv[])
if (argc <= MODE_VALUE_INDEX) { // appspawn start
arg.mode = MODE_FOR_APP_SPAWN;
} else if (strcmp(argv[MODE_VALUE_INDEX], "app_cold") == 0) { // cold start
APPSPAWN_CHECK(argc > PARAM_VALUE_INDEX, return 0, "Invalid arg for cold start %{public}d", argc);
APPSPAWN_CHECK(argc >= ARG_NULL, return 0, "Invalid arg for cold start %{public}d", argc);
arg.mode = MODE_FOR_APP_COLD_RUN;
arg.initArg = 0;
} else if (strcmp(argv[MODE_VALUE_INDEX], "nweb_cold") == 0) { // cold start
APPSPAWN_CHECK(argc > PARAM_VALUE_INDEX, return 0, "Invalid arg for cold start %{public}d", argc);
APPSPAWN_CHECK(argc >= ARG_NULL, return 0, "Invalid arg for cold start %{public}d", argc);
arg.mode = MODE_FOR_NWEB_COLD_RUN;
arg.moduleType = MODULE_NWEBSPAWN;
arg.serviceName = NWEBSPAWN_SERVER_NAME;

View File

@ -37,9 +37,11 @@ extern "C" {
#define FD_ID_INDEX 3
#define FD_VALUE_INDEX 4
#define FLAGS_VALUE_INDEX 5
#define SHM_ID_INDEX 6
#define SHM_SIZE_INDEX 6
#define PARAM_ID_INDEX 7
#define PARAM_VALUE_INDEX 8
#define CLIENT_ID_INDEX 9
#define ARG_NULL 10
#define MAX_DIED_PROCESS_COUNT 5
@ -66,8 +68,8 @@ typedef struct {
int32_t fd[2]; // 2 fd count
WatcherHandle watcherHandle;
TimerHandle timer;
int shmId;
uint32_t memSize;
char *childMsg;
uint32_t msgSize;
char *coldRunPath;
} AppSpawnForkCtx;
@ -144,12 +146,12 @@ int KillAndWaitStatus(pid_t pid, int sig);
void ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message);
int ProcessTerminationStatusMsg(const AppSpawnMsgNode *message, AppSpawnResult *result);
AppSpawnMsgNode *CreateAppSpawnMsg(void);
void DeleteAppSpawnMsg(AppSpawnMsgNode *msgNode);
int CheckAppSpawnMsg(const AppSpawnMsgNode *message);
int DecodeAppSpawnMsg(AppSpawnMsgNode *message);
int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder);
int SendAppSpawnMsgToChild(AppSpawningCtx *forkCtx, AppSpawnMsgNode *message);
/**
* @brief
@ -199,6 +201,9 @@ APPSPAWN_INLINE const char *GetProcessName(const AppSpawningCtx *property)
APPSPAWN_INLINE const char *GetBundleName(const AppSpawningCtx *property)
{
if (property == NULL || property->message == NULL) {
return NULL;
}
AppSpawnMsgBundleInfo *info = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(property->message, TLV_BUNDLE_INFO);
if (info != NULL) {
return info->bundleName;

View File

@ -16,23 +16,19 @@
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include "interfaces/innerkits/include/appspawn_msg.h"
#include "interfaces/innerkits_new/include/appspawn.h"
#include "modules/module_engine/include/appspawn_msg.h"
#include "appspawn_service.h"
#include "appspawn.h"
#include "appspawn_manager.h"
#include "appspawn_msg.h"
#include "appspawn_utils.h"
#include "securec.h"
#define INVALID_OFFSET 0xffffffff
void *GetAppSpawnMsgInfo(const AppSpawnMsgNode *message, int type)
{
APPSPAWN_CHECK(type < TLV_MAX, return NULL, "Invalid tlv type %{public}u", type);
APPSPAWN_CHECK_ONLY_EXPER(message != NULL && message->buffer != NULL, return NULL);
APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset != NULL, return NULL);
APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset[type] != INVALID_OFFSET, return NULL);
return (void *)(message->buffer + message->tlvOffset[type] + sizeof(AppSpawnTlv));
}
@ -41,6 +37,7 @@ void *GetAppSpawnMsgExtInfo(const AppSpawnMsgNode *message, const char *name, ui
{
APPSPAWN_CHECK(name != NULL, return NULL, "Invalid name ");
APPSPAWN_CHECK_ONLY_EXPER(message != NULL && message->buffer != NULL, return NULL);
APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset != NULL, return NULL);
APPSPAWN_LOGV("GetAppSpawnMsgExtInfo tlvCount %{public}d name %{public}s", message->tlvCount, name);
for (uint32_t index = TLV_MAX; index < (TLV_MAX + message->tlvCount); index++) {
@ -75,13 +72,12 @@ int CheckAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t
return CHECK_FLAGS_BY_INDEX(msgFlags->flags[blockIndex], bitIndex);
}
static AppSpawnMsgNode *CreateAppSpawnMsg(void)
AppSpawnMsgNode *CreateAppSpawnMsg(void)
{
AppSpawnMsgNode *message = (AppSpawnMsgNode *)calloc(1, sizeof(AppSpawnMsgNode));
APPSPAWN_CHECK(message != NULL, return NULL, "Failed to create message");
message->buffer = NULL;
message->tlvOffset = NULL;
(void)memset_s(&message->msgHeader, sizeof(message->msgHeader), 0, sizeof(message->msgHeader));
return message;
}
@ -136,6 +132,7 @@ static int AppSpawnMsgRebuild(AppSpawnMsgNode *message, const AppSpawnMsg *msg)
int CheckAppSpawnMsg(const AppSpawnMsgNode *message)
{
APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return APPSPAWN_MSG_INVALID);
APPSPAWN_CHECK(strlen(message->msgHeader.processName) > 0,
return APPSPAWN_MSG_INVALID, "Invalid property processName %{public}s", message->msgHeader.processName);
APPSPAWN_CHECK(message->tlvOffset != NULL,
@ -146,9 +143,12 @@ int CheckAppSpawnMsg(const AppSpawnMsgNode *message)
if (message->tlvOffset[TLV_BUNDLE_INFO] == INVALID_OFFSET ||
message->tlvOffset[TLV_MSG_FLAGS] == INVALID_OFFSET ||
message->tlvOffset[TLV_ACCESS_TOKEN_INFO] == INVALID_OFFSET ||
message->tlvOffset[TLV_DOMAIN_INFO] == INVALID_OFFSET ||
message->tlvOffset[TLV_DAC_INFO] == INVALID_OFFSET) {
APPSPAWN_LOGE("No must tlv: %{public}u %{public}u %{public}u", message->tlvOffset[TLV_BUNDLE_INFO],
message->tlvOffset[TLV_MSG_FLAGS], message->tlvOffset[TLV_DAC_INFO]);
APPSPAWN_LOGE("No must tlv bundle: %{public}u flags: %{public}u token: %{public}u domain %{public}u %{public}u",
message->tlvOffset[TLV_BUNDLE_INFO], message->tlvOffset[TLV_MSG_FLAGS],
message->tlvOffset[TLV_ACCESS_TOKEN_INFO],
message->tlvOffset[TLV_DOMAIN_INFO], message->tlvOffset[TLV_DAC_INFO]);
return APPSPAWN_MSG_INVALID;
}
AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(message, TLV_BUNDLE_INFO);
@ -211,6 +211,7 @@ static int CheckMsgTlv(const AppSpawnTlv *tlv, uint32_t remainLen)
int DecodeAppSpawnMsg(AppSpawnMsgNode *message)
{
APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return APPSPAWN_MSG_INVALID);
int ret = 0;
uint32_t tlvCount = 0;
uint32_t bufferLen = message->msgHeader.msgLen - sizeof(AppSpawnMsg);
@ -246,6 +247,8 @@ int DecodeAppSpawnMsg(AppSpawnMsgNode *message)
int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder)
{
APPSPAWN_CHECK_ONLY_EXPER(buffer != NULL && outMsg != NULL, return APPSPAWN_MSG_INVALID);
APPSPAWN_CHECK_ONLY_EXPER(msgRecvLen != NULL && reminder != NULL, return APPSPAWN_MSG_INVALID);
*reminder = 0;
AppSpawnMsgNode *message = *outMsg;
if (message == NULL) {
@ -294,122 +297,72 @@ int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
return 0;
}
pid_t GetPidFromTerminationMsg(AppSpawnMsgNode *message)
static inline void DumpMsgFlags(const char *info, const AppSpawnMsgFlags *msgFlags)
{
pid_t *pid = (pid_t *)GetAppSpawnMsgInfo(message, TLV_RENDER_TERMINATION_INFO);
if (pid != NULL) {
return *pid;
APPSPAPWN_DUMP("%{public}s count: %{public}u ", info, msgFlags->count);
for (uint32_t i = 0; i < msgFlags->count; i++) {
APPSPAPWN_DUMP("%{public}s flags: 0x%{public}x", info, msgFlags->flags[i]);
}
return -1;
}
static int ChangeAppSpawnMsgExt2Property(AppSpawnMsgNode *message, AppSpawnClientExt *appProperty)
static inline void DumpMsgExtInfo(const AppSpawnTlv *tlv)
{
static const char *extInfoNames[] = { "HspList", "Overlay", "DataGroup", "AppEnv"};
static const char *extraNames[] = { "|HspList|", "|Overlay|", "|DataGroup|", "|AppEnv|"};
char *data[sizeof(extInfoNames) / sizeof(extInfoNames[0])] = {};
char *renderCmd = (char *)GetAppSpawnMsgExtInfo(message, MSG_EXT_NAME_RENDER_CMD, NULL);
if (renderCmd != NULL) {
int ret = strcpy_s(appProperty->property.renderCmd, sizeof(appProperty->property.renderCmd), renderCmd);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to copy renderCmd");
if (tlv->tlvType != TLV_MAX) {
APPSPAPWN_DUMP("App tlv info: [%{public}d %{public}d]", tlv->tlvType, tlv->tlvLen);
return;
}
AppSpawnTlvExt *tlvExt = (AppSpawnTlvExt *)(tlv);
APPSPAPWN_DUMP("App extend info name: %{public}s len: %{public}u", tlvExt->tlvName, tlvExt->dataLen);
if (tlvExt->dataType == DATA_TYPE_STRING) {
APPSPAPWN_DUMP("App extend info value: '%{public}s'", (char *)(tlvExt + 1));
}
}
void DumpAppSpawnMsg(const AppSpawnMsgNode *message)
{
APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return);
APPSPAPWN_DUMP("App spawn msg msgId: %{public}u msgLen: %{public}u tlvCount: %{public}u",
message->msgHeader.msgId, message->msgHeader.msgLen, message->tlvCount);
APPSPAPWN_DUMP("App spawn msg process name: %{public}s", message->msgHeader.processName);
AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(message, TLV_MSG_FLAGS);
APPSPAWN_ONLY_EXPER(msgFlags != NULL, DumpMsgFlags("App flags", msgFlags));
msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(message, TLV_PERMISSION);
APPSPAWN_ONLY_EXPER(msgFlags != NULL, DumpMsgFlags("App permission bits", msgFlags));
AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppSpawnMsgInfo(message, TLV_DAC_INFO);
if (dacInfo != NULL) {
appProperty->property.uid = dacInfo->uid;
appProperty->property.gid = dacInfo->gid;
appProperty->property.gidCount = dacInfo->gidCount;
APPSPAPWN_DUMP("App dac info uid: %{public}d gid: %{public}d count: %{public}d",
dacInfo->uid, dacInfo->gid, dacInfo->gidCount);
for (uint32_t i = 0; i < dacInfo->gidCount; i++) {
appProperty->property.gidTable[i] = dacInfo->gidTable[i];
APPSPAPWN_DUMP("gid group[%{public}d]: %{public}d", i, dacInfo->gidTable[i]);
}
}
AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(message, TLV_BUNDLE_INFO);
APPSPAWN_ONLY_EXPER(bundleInfo != NULL,
APPSPAPWN_DUMP("App bundle info name: \"%{public}s\" index: %{public}d",
bundleInfo->bundleName, bundleInfo->bundleIndex));
ExtraInfo *extraInfo = &appProperty->property.extraInfo;
uint32_t totalLength = 0;
uint32_t currLen = 0;
uint32_t nameCount = sizeof(extInfoNames) / sizeof(extInfoNames[0]);
for (uint32_t i = 0; i < nameCount; i++) {
currLen = 0;
data[i] = (char *)GetAppSpawnMsgExtInfo(message, extInfoNames[i], &currLen);
if (data[i]) {
totalLength += currLen + strlen(extraNames[i]) * 2 + 1; // 2 format |type1|...|type1|type2|...|type2|
}
}
APPSPAWN_CHECK_ONLY_EXPER(totalLength != 0, return 0);
AppSpawnMsgDomainInfo *domainInfo = (AppSpawnMsgDomainInfo *)GetAppSpawnMsgInfo(message, TLV_DOMAIN_INFO);
APPSPAWN_ONLY_EXPER(domainInfo != NULL,
APPSPAPWN_DUMP("App domain info hap: 0x%{public}x apl: \"%{public}s\"", domainInfo->hapFlags, domainInfo->apl));
extraInfo->data = (char *)calloc(1, totalLength);
APPSPAWN_CHECK(extraInfo->data != NULL, return -1, "Failed to alloc mem for extra");
currLen = 0;
for (uint32_t i = 0; i < nameCount; i++) {
if (data[i] == NULL) {
AppSpawnMsgOwnerId *owner = (AppSpawnMsgOwnerId *)GetAppSpawnMsgInfo(message, TLV_OWNER_INFO);
APPSPAWN_ONLY_EXPER(owner != NULL, APPSPAPWN_DUMP("App owner info: \"%{public}s\" ", owner->ownerId));
AppSpawnMsgAccessToken *t = (AppSpawnMsgAccessToken *)GetAppSpawnMsgInfo(message, TLV_ACCESS_TOKEN_INFO);
APPSPAWN_ONLY_EXPER(t != NULL,
APPSPAPWN_DUMP("App access token info: %{public}" PRId64 "", t->accessTokenIdEx));
AppSpawnMsgInternetInfo *info = (AppSpawnMsgInternetInfo *)GetAppSpawnMsgInfo(message, TLV_INTERNET_INFO);
APPSPAWN_ONLY_EXPER(info != NULL,
APPSPAPWN_DUMP("App internet permission info [%{public}d %{public}d]",
info->setAllowInternet, info->allowInternet));
for (uint32_t i = TLV_MAX; i < TLV_MAX + message->tlvCount; i++) {
if (message->tlvOffset[i] == INVALID_OFFSET) {
continue;
}
int len = snprintf_s(extraInfo->data + currLen, totalLength - currLen, totalLength - currLen - 1,
"%s%s%s", extraNames[i], data[i], extraNames[i]);
if (len <= 0) {
free(extraInfo->data);
extraInfo->data = NULL;
return 0;
}
currLen += len;
DumpMsgExtInfo((AppSpawnTlv *)(message->buffer + message->tlvOffset[i]));
}
extraInfo->totalLength = currLen;
extraInfo->savedLength = currLen;
APPSPAWN_LOGV("extraInfo %{public}s", extraInfo->data);
return 0;
}
int ChangeAppSpawnMsg2Property(AppSpawnMsgNode *message, AppSpawnClientExt *appProperty)
{
APPSPAWN_CHECK_ONLY_EXPER(message != NULL && appProperty != NULL, return -1);
appProperty->property.code = (AppOperateType)message->msgHeader.msgType;
if (message->msgHeader.msgType == MSG_GET_RENDER_TERMINATION_STATUS) {
appProperty->property.code = GET_RENDER_TERMINATION_STATUS;
} else if (message->msgHeader.msgType == MSG_SPAWN_NATIVE_PROCESS) {
appProperty->property.code = SPAWN_NATIVE_PROCESS;
}
int ret = 0;
do {
ret = strcpy_s(appProperty->property.processName, APP_LEN_PROC_NAME, message->msgHeader.processName);
APPSPAWN_CHECK(ret == 0, break, "Failed to copy processName");
ret = DecodeAppSpawnMsg(message);
APPSPAWN_CHECK(ret == 0, break, "Failed to decode message");
AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(message, TLV_MSG_FLAGS);
appProperty->property.flags = msgFlags ? *(uint32_t *)msgFlags->flags : 0;
msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(message, TLV_PERMISSION);
appProperty->property.mountPermissionFlags = msgFlags ? *(uint32_t *)msgFlags->flags : 0;
AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(message, TLV_BUNDLE_INFO);
if (bundleInfo != NULL) {
ret = strcpy_s(appProperty->property.bundleName, APP_LEN_BUNDLE_NAME, bundleInfo->bundleName);
APPSPAWN_CHECK(ret == 0, break, "Failed to copy bundle name");
appProperty->property.bundleIndex = (int32_t)bundleInfo->bundleIndex;
}
AppSpawnMsgDomainInfo *domainInfo = (AppSpawnMsgDomainInfo *)GetAppSpawnMsgInfo(message, TLV_DOMAIN_INFO);
if (domainInfo != NULL) {
ret = strcpy_s(appProperty->property.apl, sizeof(appProperty->property.apl), domainInfo->apl);
APPSPAWN_CHECK(ret == 0, break, "Failed to copy apl");
appProperty->property.hapFlags = domainInfo->hapFlags;
}
AppSpawnMsgOwnerId *owner = (AppSpawnMsgOwnerId *)GetAppSpawnMsgInfo(message, TLV_OWNER_INFO);
if (owner != NULL) {
ret = strcpy_s(appProperty->property.ownerId, sizeof(appProperty->property.ownerId), owner->ownerId);
APPSPAWN_CHECK(ret == 0, break, "Failed to copy ownerId");
}
AppSpawnMsgAccessToken *token = (AppSpawnMsgAccessToken *)GetAppSpawnMsgInfo(message, TLV_ACCESS_TOKEN_INFO);
appProperty->property.accessTokenIdEx = token ? token->accessTokenIdEx : 0;
AppSpawnMsgInternetInfo *info = (AppSpawnMsgInternetInfo *)GetAppSpawnMsgInfo(message, TLV_INTERNET_INFO);
if (info != NULL) {
appProperty->property.allowInternet = info->allowInternet;
appProperty->property.setAllowInternet = info->setAllowInternet;
}
pid_t *pid = (pid_t *)GetAppSpawnMsgInfo(message, TLV_RENDER_TERMINATION_INFO);
APPSPAWN_CHECK_ONLY_EXPER(pid == NULL, appProperty->property.pid = *pid);
ret = ChangeAppSpawnMsgExt2Property(message, appProperty);
} while (0);
DeleteAppSpawnMsg(message);
return ret;
}

View File

@ -1,756 +0,0 @@
/*
* Copyright (c) 2021-2023 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.
*/
#include "appspawn_service.h"
#include "appspawn_adapter.h"
#include "env_utils.h"
#include "param_helper.h"
#include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/capability.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/signalfd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sched.h>
#include <dirent.h>
#include "securec.h"
#include "selinux/selinux.h"
#include "parameter.h"
#include "limits.h"
#include "string.h"
#include "init_param.h"
#ifdef CODE_SIGNATURE_ENABLE
#include "code_sign_attr_utils.h"
#endif
#define DEVICE_NULL_STR "/dev/null"
#define PID_NS_INIT_UID 100000 // reserved for pid_ns_init process, avoid app, render proc, etc.
#define PID_NS_INIT_GID 100000
// ide-asan
#ifndef ASAN_DETECTOR
static int SetAsanEnabledEnv(struct AppSpawnContent *content, AppSpawnClient *client)
{
AppParameter *appProperty = &((AppSpawnClientExt *)client)->property;
if (appProperty->code == SPAWN_NATIVE_PROCESS) {
return 0;
}
char *bundleName = appProperty->bundleName;
if ((appProperty->flags & APP_ASANENABLED) != 0) {
char *devPath = "/dev/asanlog";
char logPath[PATH_MAX] = {0};
int ret = snprintf_s(logPath, sizeof(logPath), sizeof(logPath) - 1,
"/data/app/el1/100/base/%s/log", bundleName);
APPSPAWN_CHECK(ret > 0, return -1, "Invalid snprintf_s");
char asanOptions[PATH_MAX] = {0};
ret = snprintf_s(asanOptions, sizeof(asanOptions), sizeof(asanOptions) - 1,
"log_path=%s/asan.log:include=/system/etc/asan.options", devPath);
APPSPAWN_CHECK(ret > 0, return -1, "Invalid snprintf_s");
#if defined (__aarch64__) || defined (__x86_64__)
setenv("LD_PRELOAD", "/system/lib64/libclang_rt.asan.so", 1);
#else
setenv("LD_PRELOAD", "/system/lib/libclang_rt.asan.so", 1);
#endif
unsetenv("UBSAN_OPTIONS");
setenv("ASAN_OPTIONS", asanOptions, 1);
client->flags |= APP_COLD_START;
} else if ((appProperty->flags & APP_TSANENABLED) != 0) {
setenv("LD_PRELOAD", "/system/lib64/libclang_rt.tsan.so", 1);
unsetenv("UBSAN_OPTIONS");
setenv("TSAN_OPTIONS", "include=/system/etc/tsan.options", 1);
client->flags |= APP_COLD_START;
}
return 0;
}
#endif
static void SetGwpAsanEnabled(struct AppSpawnContent *content, AppSpawnClient *client)
{
AppParameter *appProperty = &((AppSpawnClientExt *)client)->property;
char debugValue[10] = {0};
int flag = appProperty->flags;
if ((flag & (APP_GWP_ENABLED_FORCE | APP_GWP_ENABLED_NORMAL)) == 0) {
return;
}
int ret = GetParameter("const.security.developermode.state", "", debugValue, sizeof(debugValue));
if (ret > 0 && (strcmp(debugValue, "true") == 0)) {
APPSPAWN_LOGI("SetGwpAsanEnabled with falg: %{public}d", flag);
may_init_gwp_asan(flag & APP_GWP_ENABLED_FORCE);
}
}
static int SetProcessName(struct AppSpawnContent *content, AppSpawnClient *client,
char *longProcName, uint32_t longProcNameLen)
{
AppSpawnClientExt *appPropertyExt = (AppSpawnClientExt *)client;
AppParameter *appProperty = &appPropertyExt->property;
size_t len = strlen(appProperty->processName);
bool isRet = longProcName == NULL || len <= 0;
APPSPAWN_CHECK(!isRet, return -EINVAL, "process name is nullptr or length error");
char shortName[MAX_LEN_SHORT_NAME] = {0};
// process short name max length 16 bytes.
size_t copyLen = len;
const char *pos = appProperty->processName;
if (len >= MAX_LEN_SHORT_NAME) {
copyLen = MAX_LEN_SHORT_NAME - 1;
pos += (len - copyLen);
}
isRet = strncpy_s(shortName, MAX_LEN_SHORT_NAME, pos, copyLen) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "strncpy_s short name error: %{public}d", errno);
// set short name
isRet = prctl(PR_SET_NAME, shortName) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "prctl(PR_SET_NAME) error: %{public}d", errno);
// reset longProcName
isRet = memset_s(longProcName, (size_t)longProcNameLen, 0, (size_t)longProcNameLen) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset long process name");
// set long process name
isRet = strncpy_s(longProcName, longProcNameLen, appProperty->processName, len) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL,
"strncpy_s long name error: %{public}d longProcNameLen %{public}u", errno, longProcNameLen);
return 0;
}
static int SetKeepCapabilities(struct AppSpawnContent *content, AppSpawnClient *client)
{
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
// set keep capabilities when user not root.
if (appProperty->property.uid != 0) {
bool isRet = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "set keepcaps failed: %{public}d", errno);
}
return 0;
}
static int SetCapabilities(struct AppSpawnContent *content, AppSpawnClient *client)
{
// init cap
struct __user_cap_header_struct cap_header;
bool isRet = memset_s(&cap_header, sizeof(cap_header), 0, sizeof(cap_header)) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap header");
cap_header.version = _LINUX_CAPABILITY_VERSION_3;
cap_header.pid = 0;
struct __user_cap_data_struct cap_data[2];
isRet = memset_s(&cap_data, sizeof(cap_data), 0, sizeof(cap_data)) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap data");
// init inheritable permitted effective zero
#ifdef GRAPHIC_PERMISSION_CHECK
const uint64_t inheriTable = 0;
const uint64_t permitted = 0;
const uint64_t effective = 0;
#else
const uint64_t inheriTable = 0x3fffffffff;
const uint64_t permitted = 0x3fffffffff;
const uint64_t effective = 0x3fffffffff;
#endif
cap_data[0].inheritable = (__u32)(inheriTable);
cap_data[1].inheritable = (__u32)(inheriTable >> BITLEN32);
cap_data[0].permitted = (__u32)(permitted);
cap_data[1].permitted = (__u32)(permitted >> BITLEN32);
cap_data[0].effective = (__u32)(effective);
cap_data[1].effective = (__u32)(effective >> BITLEN32);
// set capabilities
isRet = capset(&cap_header, &cap_data[0]) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "capset failed: %{public}d", errno);
isRet = SetSelinuxCon(content, client) == -1;
APPSPAWN_CHECK(!isRet, return -ECANCELED, "Failed to set selinux context");
return 0;
}
static void InitDebugParams(struct AppSpawnContent *content, AppSpawnClient *client)
{
#ifndef APPSPAWN_TEST
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
#if defined (__aarch64__) || defined (__x86_64__)
const char *debugSoPath = "/system/lib64/libhidebug.so";
#else
const char *debugSoPath = "/system/lib/libhidebug.so";
#endif
bool isRet = access(debugSoPath, F_OK) != 0;
APPSPAWN_CHECK(!isRet, return, "access failed, errno = %{public}d", errno);
void *handle = dlopen(debugSoPath, RTLD_LAZY);
APPSPAWN_CHECK(handle != NULL, return, "Failed to dlopen libhidebug.so, %{public}s", dlerror());
bool (*initParam)(const char *name);
initParam = (bool (*)(const char *name))dlsym(handle, "InitEnvironmentParam");
APPSPAWN_CHECK(initParam != NULL, dlclose(handle);
return, "Failed to dlsym InitEnvironmentParam, %{public}s", dlerror());
(*initParam)(appProperty->property.processName);
dlclose(handle);
#endif
}
static void ClearEnvironment(AppSpawnContent *content, AppSpawnClient *client)
{
APPSPAWN_LOGI("ClearEnvironment id %{public}d", client->id);
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGTERM);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
// close child fd
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
close(appProperty->fd[0]);
#ifndef ASAN_DETECTOR
SetAsanEnabledEnv(content, client);
#endif
SetGwpAsanEnabled(content, client);
ResetParamSecurityLabel();
return;
}
int SetXpmConfig(struct AppSpawnContent *content, AppSpawnClient *client)
{
#ifdef CODE_SIGNATURE_ENABLE
// nwebspawn no permission set xpm config
if (content->isNweb) {
return 0;
}
int ret = InitXpmRegion();
APPSPAWN_CHECK(ret == 0, return ret, "init xpm region failed: %{public}d", ret);
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
if (appProperty->property.flags & APP_DEBUGGABLE) {
ret = SetXpmOwnerId(PROCESS_OWNERID_DEBUG, NULL);
} else if ((appProperty->property.ownerId[0] == '\0') ||
(strcmp(appProperty->property.ownerId, "NULL") == 0)) {
ret = SetXpmOwnerId(PROCESS_OWNERID_COMPAT, NULL);
} else {
ret = SetXpmOwnerId(PROCESS_OWNERID_APP, appProperty->property.ownerId);
}
APPSPAWN_CHECK(ret == 0, return ret, "set xpm region failed: %{public}d", ret);
#endif
return 0;
}
static int SetUidGid(struct AppSpawnContent *content, AppSpawnClient *client)
{
#ifdef GRAPHIC_PERMISSION_CHECK
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
// set gids
bool isRet = setgroups(appProperty->property.gidCount, (const gid_t *)(&appProperty->property.gidTable[0])) == -1;
APPSPAWN_CHECK(!isRet, return -errno,
"setgroups failed: %{public}d, gids.size=%{public}u", errno, appProperty->property.gidCount);
// set gid
isRet = setresgid(appProperty->property.gid, appProperty->property.gid, appProperty->property.gid) == -1;
APPSPAWN_CHECK(!isRet, return -errno,
"setgid(%{public}u) failed: %{public}d", appProperty->property.gid, errno);
if (content->setSeccompFilter) {
long ret = content->setSeccompFilter(content, client);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to set setSeccompFilter");
}
/* If the effective user ID is changed from 0 to nonzero,
* then all capabilities are cleared from the effective set
*/
isRet = setresuid(appProperty->property.uid, appProperty->property.uid, appProperty->property.uid) == -1;
APPSPAWN_CHECK(!isRet, return -errno,
"setuid(%{public}u) failed: %{public}d", appProperty->property.uid, errno);
#endif
char debugValue[10] = {0};
if ((appProperty->property.flags & APP_DEBUGGABLE) == 0) {
return 0;
}
int ret = GetParameter("const.security.developermode.state", "", debugValue, sizeof(debugValue));
if (!(ret > 0 && (strcmp(debugValue, "true") == 0))) {
return 0;
}
APPSPAWN_LOGV("Debuggable app");
setenv("HAP_DEBUGGABLE", "true", 1);
if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
APPSPAWN_LOGE("Failed to set app dumpable: %{public}s", strerror(errno));
}
return 0;
}
static int32_t SetFileDescriptors(struct AppSpawnContent *content, AppSpawnClient *client)
{
#ifndef APPSPAWN_TEST
// close stdin stdout stderr
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// redirect to /dev/null
int dev_null_fd = open(DEVICE_NULL_STR, O_RDWR);
if (dev_null_fd == -1) {
APPSPAWN_LOGE("open dev_null error: %{public}d", errno);
return (-errno);
}
// stdin
if (dup2(dev_null_fd, STDIN_FILENO) == -1) {
APPSPAWN_LOGE("dup2 STDIN error: %{public}d", errno);
return (-errno);
};
// stdout
if (dup2(dev_null_fd, STDOUT_FILENO) == -1) {
APPSPAWN_LOGE("dup2 STDOUT error: %{public}d", errno);
return (-errno);
};
// stderr
if (dup2(dev_null_fd, STDERR_FILENO) == -1) {
APPSPAWN_LOGE("dup2 STDERR error: %{public}d", errno);
return (-errno);
};
#endif
return 0;
}
static int32_t CheckTraceStatus(void)
{
int fd = open("/proc/self/status", O_RDONLY);
if (fd == -1) {
APPSPAWN_LOGE("open /proc/self/status error: %{public}d", errno);
return (-errno);
}
char data[1024] = { 0 }; // 1024 is data length
ssize_t dataNum = read(fd, data, sizeof(data));
if (close(fd) < 0) {
APPSPAWN_LOGE("close fd error: %{public}d", errno);
return (-errno);
}
if (dataNum <= 0) {
APPSPAWN_LOGE("fail to read data");
return -1;
}
data[1023] = '\0'; // 1023 is data last element
const char* tracerPid = "TracerPid:\t";
char *traceStr = strstr(data, tracerPid);
if (traceStr == NULL) {
APPSPAWN_LOGE("fail to find %{public}s", tracerPid);
return -1;
}
char *separator = strchr(traceStr, '\n');
if (separator == NULL) {
APPSPAWN_LOGE("fail to find line break");
return -1;
}
int len = separator - traceStr - strlen(tracerPid);
char pid = *(traceStr + strlen(tracerPid));
if (len > 1 || pid != '0') {
return 0;
}
return -1;
}
static int32_t WaitForDebugger(AppSpawnClient *client)
{
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
// wait for debugger only debugging is required and process is debuggable
if ((appProperty->property.flags & APP_NATIVEDEBUG) != 0 &&
(appProperty->property.flags & APP_DEBUGGABLE) != 0) {
uint32_t count = 0;
while (CheckTraceStatus() != 0) {
usleep(1000 * 100); // sleep 1000 * 100 microsecond
count++;
// remind users to connect to the debugger every 60 * 10 times
if (count % (10 * 60) == 0) {
count = 0;
APPSPAWN_LOGI("wait for debugger, please attach the process");
}
}
}
return 0;
}
static void Free(char **argv, ExtraInfo *extraInfo)
{
argv[0] = NULL;
for (int i = 0; i < NULL_INDEX; i++) {
if (argv[i] != NULL) {
free(argv[i]);
argv[i] = NULL;
}
}
free(argv);
if (extraInfo != NULL) {
extraInfo->totalLength = 0;
extraInfo->savedLength = 0;
free(extraInfo->data);
extraInfo->data = NULL;
}
}
#ifdef ASAN_DETECTOR
#define WRAP_VALUE_MAX_LENGTH 96
static int GetWrapBundleNameValue(struct AppSpawnContent *content, AppSpawnClient *client)
{
AppParameter *appProperty = &((AppSpawnClientExt *)client)->property;
char wrapBundleNameKey[WRAP_VALUE_MAX_LENGTH] = {0};
char wrapBundleNameValue[WRAP_VALUE_MAX_LENGTH] = {0};
int len = sprintf_s(wrapBundleNameKey, WRAP_VALUE_MAX_LENGTH, "wrap.%s", appProperty->bundleName);
APPSPAWN_CHECK(len > 0 && (len < WRAP_VALUE_MAX_LENGTH), return -1, "Invalid to format wrapBundleNameKey");
int ret = GetParameter(wrapBundleNameKey, "", wrapBundleNameValue, WRAP_VALUE_MAX_LENGTH);
APPSPAWN_CHECK(ret > 0 && (!strcmp(wrapBundleNameValue, "asan_wrapper")), return -1,
"Not wrap %{public}s.", appProperty->bundleName);
APPSPAWN_LOGI("Asan: GetParameter %{public}s the value is %{public}s.", wrapBundleNameKey, wrapBundleNameValue);
return 0;
}
#endif
static int EncodeAppClient(AppSpawnClient *client, char *param, int32_t originLen)
{
AppParameter *appProperty = &((AppSpawnClientExt *)client)->property;
int32_t startLen = 0;
int32_t len = sprintf_s(param + startLen, originLen - startLen, "%u:%u:%u:%u:%u:%u:%u:%u:%u:%u",
client->id, client->flags, client->cloneFlags, appProperty->code,
appProperty->flags, appProperty->uid, appProperty->gid,
appProperty->setAllowInternet, appProperty->allowInternet, appProperty->gidCount);
APPSPAWN_CHECK(len > 0 && (len < (originLen - startLen)), return -1, "Invalid to format");
startLen += len;
for (uint32_t i = 0; i < appProperty->gidCount; i++) {
len = sprintf_s(param + startLen, originLen - startLen, ":%u", appProperty->gidTable[i]);
APPSPAWN_CHECK(len > 0 && (len < (originLen - startLen)), return -1, "Invalid to format gid");
startLen += len;
}
// processName
if (appProperty->soPath[0] == '\0') {
strcpy_s(appProperty->soPath, sizeof(appProperty->soPath), "NULL");
}
// ownerId
if (appProperty->ownerId[0] == '\0') {
strcpy_s(appProperty->ownerId, sizeof(appProperty->ownerId), "NULL");
}
len = sprintf_s(param + startLen, originLen - startLen, ":%s:%s:%s:%u:%s:%s:%s:%u:%" PRIu64 "",
appProperty->processName, appProperty->bundleName, appProperty->soPath,
appProperty->accessTokenId, appProperty->apl, appProperty->renderCmd, appProperty->ownerId,
appProperty->hapFlags, appProperty->accessTokenIdEx);
APPSPAWN_CHECK(len > 0 && (len < (originLen - startLen)), return -1, "Invalid to format processName");
return 0;
}
static int ColdStartApp(struct AppSpawnContent *content, AppSpawnClient *client)
{
AppParameter *appProperty = &((AppSpawnClientExt *)client)->property;
APPSPAWN_LOGI("ColdStartApp::appName %{public}s", appProperty->processName);
char buffer[32] = {0}; // 32 buffer for fd
int len = sprintf_s(buffer, sizeof(buffer), "%d", ((AppSpawnClientExt *)client)->fd[1]);
APPSPAWN_CHECK(len > 0, return -1, "Invalid to format fd");
char **argv = calloc(1, (NULL_INDEX + 1) * sizeof(char *));
APPSPAWN_CHECK(argv != NULL, return -1, "Failed to get argv");
int ret = -1;
do {
const int32_t originLen = sizeof(AppParameter) + PARAM_BUFFER_LEN;
char *param = malloc(originLen + APP_LEN_PROC_NAME);
APPSPAWN_CHECK(param != NULL, break, "Failed to malloc for param");
argv[PARAM_INDEX] = param;
argv[0] = param + originLen;
const char *appSpawnPath = "/system/bin/appspawn";
#ifdef ASAN_DETECTOR
if (GetWrapBundleNameValue(content, client) == 0) {
appSpawnPath = "/system/asan/bin/appspawn";
}
#endif
ret = strcpy_s(argv[0], APP_LEN_PROC_NAME, appSpawnPath);
APPSPAWN_CHECK(ret >= 0, break, "Invalid strcpy");
(content->isNweb) ? (argv[START_INDEX] = strdup(NWEBSPAWN_COLDSTART_KEY)) :
(argv[START_INDEX] = strdup(APPSPAWN_COLDSTART_KEY));
APPSPAWN_CHECK(argv[START_INDEX] != NULL, break, "Invalid strdup");
argv[FD_INDEX] = strdup(buffer);
APPSPAWN_CHECK(argv[FD_INDEX] != NULL, break, "Invalid strdup");
ret = EncodeAppClient(client, param, originLen);
APPSPAWN_CHECK(ret == 0, break, "Failed to encode client");
len = sprintf_s(buffer, sizeof(buffer), "%u", appProperty->extraInfo.totalLength);
APPSPAWN_CHECK(len > 0 && len < (int)sizeof(buffer), break, "Invalid extraInfo.totalLength");
argv[EXTRA_INFO_LEN_INDEX] = strdup(buffer);
argv[EXTRA_INFO_INDEX] = appProperty->extraInfo.data;
ret = 0;
} while (0);
if (ret == 0) {
argv[NULL_INDEX] = NULL;
#ifndef APPSPAWN_TEST
ret = execv(argv[0], argv);
#else
ret = -1;
#endif
APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to execv, errno = %{public}d", errno)
}
argv[0] = NULL;
Free(argv, &appProperty->extraInfo);
return ret;
}
static int GetUInt32FromArg(char *begin, char **end, uint32_t *value)
{
char *start = strtok_r(begin, ":", end);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get uint32 value");
*value = atoi(start);
return 0;
}
static int GetUInt64FromArg(char *begin, char **end, uint64_t *value)
{
char *start = strtok_r(begin, ":", end);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get uint64 value");
APPSPAWN_LOGV("GetUInt64FromArg %{public}s ", start);
*value = atoll(start);
return 0;
}
static int GetStringFromArg(char *begin, char **end, char *value, uint32_t valueLen)
{
char *start = strtok_r(NULL, ":", end);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get string");
if (strcmp(start, "NULL")) {
return strcpy_s(value, valueLen, start);
} else {
value[0] = '\0';
}
return 0;
}
int GetAppSpawnClientFromArg(int argc, char *const argv[], AppSpawnClientExt *client)
{
APPSPAWN_CHECK(argv != NULL && argc > PARAM_INDEX, return -1, "Invalid argv argc %{public}d", argc);
client->fd[1] = atoi(argv[FD_INDEX]);
APPSPAWN_LOGV("GetAppSpawnClientFromArg %{public}s ", argv[PARAM_INDEX]);
// clientid
char *end = NULL;
int ret = GetUInt32FromArg(argv[PARAM_INDEX], &end, &client->client.id);
ret += GetUInt32FromArg(NULL, &end, &client->client.flags);
ret += GetUInt32FromArg(NULL, &end, &client->client.cloneFlags);
ret += GetUInt32FromArg(NULL, &end, &client->property.code);
ret += GetUInt32FromArg(NULL, &end, &client->property.flags);
ret += GetUInt32FromArg(NULL, &end, &client->property.uid);
ret += GetUInt32FromArg(NULL, &end, &client->property.gid);
uint32_t value = 0;
ret += GetUInt32FromArg(NULL, &end, &value);
client->property.setAllowInternet = (uint8_t)value;
ret += GetUInt32FromArg(NULL, &end, &value);
client->property.allowInternet = (uint8_t)value;
ret += GetUInt32FromArg(NULL, &end, &client->property.gidCount);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to get client info");
for (uint32_t i = 0; i < client->property.gidCount; i++) {
ret = GetUInt32FromArg(NULL, &end, &client->property.gidTable[i]);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to get gidTable");
}
// processname
ret = GetStringFromArg(NULL, &end, client->property.processName, sizeof(client->property.processName));
ret += GetStringFromArg(NULL, &end, client->property.bundleName, sizeof(client->property.bundleName));
ret += GetStringFromArg(NULL, &end, client->property.soPath, sizeof(client->property.soPath));
APPSPAWN_CHECK(ret == 0, return -1, "Failed to get process name");
// access token
ret = GetUInt32FromArg(NULL, &end, &client->property.accessTokenId);
ret += GetStringFromArg(NULL, &end, client->property.apl, sizeof(client->property.apl));
ret += GetStringFromArg(NULL, &end, client->property.renderCmd, sizeof(client->property.renderCmd));
ret += GetStringFromArg(NULL, &end, client->property.ownerId, sizeof(client->property.ownerId));
ret += GetUInt32FromArg(NULL, &end, &value);
client->property.hapFlags = value;
ret += GetUInt64FromArg(NULL, &end, &client->property.accessTokenIdEx);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to access token info");
client->property.extraInfo.totalLength = 0;
client->property.extraInfo.data = NULL;
ret = 0;
if (argc > EXTRA_INFO_LEN_INDEX && argv[EXTRA_INFO_LEN_INDEX] != NULL) {
client->property.extraInfo.totalLength = atoi(argv[EXTRA_INFO_LEN_INDEX]);
APPSPAWN_CHECK_ONLY_EXPER(client->property.extraInfo.totalLength != 0, return 0);
APPSPAWN_CHECK(argc > EXTRA_INFO_INDEX && argv[EXTRA_INFO_INDEX] != NULL, return -1, "Invalid extraInfo.data");
client->property.extraInfo.data = malloc(client->property.extraInfo.totalLength);
APPSPAWN_CHECK(client->property.extraInfo.data != NULL, return -1, "Failed to malloc extraInfo.data");
ret = strcpy_s(client->property.extraInfo.data, client->property.extraInfo.totalLength, argv[EXTRA_INFO_INDEX]);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy extraInfo.data");
}
return ret;
}
static pid_t GetPidByName(const char *name)
{
int pid = -1; // initial pid set to -1
DIR *dir = opendir("/proc");
if (dir == NULL) {
return -1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type != DT_DIR) {
continue;
}
long pidNum = strtol(entry->d_name, NULL, 10); // pid will not exceed a 10-digit decimal number
if (pidNum <= 0) {
continue;
}
char path[32]; // path that contains the process name
if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "/proc/%s/comm", entry->d_name) < 0) {
continue;
}
FILE *file = fopen(path, "r");
if (file == NULL) {
continue;
}
char buffer[32]; // read the process name
if (fgets(buffer, sizeof(buffer), file) == NULL) {
(void)fclose(file);
continue;
}
buffer[strcspn(buffer, "\n")] = 0;
if (strcmp(buffer, name) != 0) {
(void)fclose(file);
continue;
}
APPSPAWN_LOGI("get pid of %{public}s success", name);
pid = (int)pidNum;
(void)fclose(file);
break;
}
closedir(dir);
return pid;
}
static int NsInitFunc()
{
setuid(PID_NS_INIT_UID);
setgid(PID_NS_INIT_GID);
setcon("u:r:pid_ns_init:s0");
char* argv[] = {"/system/bin/pid_ns_init", NULL};
execve("/system/bin/pid_ns_init", argv, NULL);
return 0;
}
static int GetNsPidFd(pid_t pid)
{
char nsPath[256]; // filepath of ns pid
int ret = snprintf_s(nsPath, sizeof(nsPath), sizeof(nsPath) - 1, "/proc/%d/ns/pid", pid);
if (ret < 0) {
APPSPAWN_LOGE("SetPidNamespace failed, snprintf_s error:%{public}s", strerror(errno));
return -1;
}
int nsFd = open(nsPath, O_RDONLY);
if (nsFd < 0) {
APPSPAWN_LOGE("open ns pid:%{public}d failed, err:%{public}s", pid, strerror(errno));
return -1;
}
return nsFd;
}
static int EnablePidNs(AppSpawnContent *content)
{
AppSpawnContentExt *appSpawnContent = (AppSpawnContentExt *)content;
if (appSpawnContent->flags & FLAGS_MODE_COLD) {
return 0;
}
if (!(content->sandboxNsFlags & CLONE_NEWPID)) {
return 0;
}
// check if process pid_ns_init exists, this is the init process for pid namespace
pid_t pid = GetPidByName("pid_ns_init");
if (pid == -1) {
APPSPAWN_LOGI("Start Create pid_ns_init");
pid = clone(NsInitFunc, NULL, CLONE_NEWPID, NULL);
if (pid < 0) {
APPSPAWN_LOGE("clone pid ns init failed");
return -1;
}
} else {
APPSPAWN_LOGI("pid_ns_init exists, no need to create");
}
content->nsSelfPidFd = GetNsPidFd(getpid());
if (content->nsSelfPidFd < 0) {
APPSPAWN_LOGE("open ns pid of appspawn fail");
return -1;
}
content->nsInitPidFd = GetNsPidFd(pid);
if (content->nsInitPidFd < 0) {
APPSPAWN_LOGE("open ns pid of pid_ns_init fail");
close(content->nsSelfPidFd);
return -1;
}
APPSPAWN_LOGI("Enable pid namespace success.");
return 0;
}
void SetContentFunction(AppSpawnContent *content)
{
APPSPAWN_LOGI("SetContentFunction");
content->clearEnvironment = ClearEnvironment;
content->initDebugParams = InitDebugParams;
content->setProcessName = SetProcessName;
content->setKeepCapabilities = SetKeepCapabilities;
content->setUidGid = SetUidGid;
content->setXpmConfig = SetXpmConfig;
content->setFileDescriptors = SetFileDescriptors;
content->setEnvInfo = SetEnvInfo;
content->coldStartApp = ColdStartApp;
if (!content->isNweb) {
content->enablePidNs = EnablePidNs;
}
#ifdef ASAN_DETECTOR
content->getWrapBundleNameValue = GetWrapBundleNameValue;
#else
content->getWrapBundleNameValue = NULL;
content->setAsanEnabledEnv = SetAsanEnabledEnv;
#endif
content->setAppSandbox = SetAppSandboxProperty;
content->setCapabilities = SetCapabilities;
content->setUidGidFilter = SetUidGidFilter;
content->setSeccompFilter = SetSeccompFilter;
content->setAppAccessToken = SetAppAccessToken;
content->handleInternetPermission = HandleInternetPermission;
content->waitForDebugger = WaitForDebugger;
}

File diff suppressed because it is too large Load Diff

View File

@ -16,106 +16,51 @@
#ifndef APPSPAWN_SERVICE_H
#define APPSPAWN_SERVICE_H
#include <unistd.h>
#include <limits.h>
#include <stdbool.h>
#include "interfaces/innerkits/include/appspawn_msg.h"
#include "interfaces/innerkits_new/include/appspawn.h"
#include "modules/module_engine/include/appspawn_msg.h"
#include <unistd.h>
#include "appspawn.h"
#include "appspawn_hook.h"
#include "appspawn_msg.h"
#include "appspawn_server.h"
#include "init_hashmap.h"
#include "appspawn_utils.h"
#include "list.h"
#include "loop_event.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef APPSPAWN_TEST
#define APPSPAWN_STATIC
#else
#define APPSPAWN_STATIC static
#endif
extern bool may_init_gwp_asan(bool forceInit);
#define APP_HASH_BUTT 32
#define FLAGS_ON_DEMAND 0x1
#define FLAGS_MODE_COLD 0x2
#define FLAGS_SANDBOX_PRIVATE 0x10
#define FLAGS_SANDBOX_APP 0x20
#define START_INDEX 1
#define FD_INDEX 2
#define PARAM_INDEX 3
#define EXTRA_INFO_LEN_INDEX 4
#define EXTRA_INFO_INDEX 5
#define NULL_INDEX 6
#define PARAM_BUFFER_LEN 128
typedef struct TagAppSpawnMsgNode {
AppSpawnMsg msgHeader;
uint32_t tlvCount;
uint32_t *tlvOffset;
uint8_t *buffer;
} AppSpawnMsgNode;
#define MAX_WAIT_MSG_COMPLETE (5 * 1000) // 5s
#define WAIT_CHILD_RESPONSE_TIMEOUT 3000 //3s
typedef struct TagAppSpawnMsgNode AppSpawnMsgNode;
typedef struct TagAppSpawnMsgReceiverCtx {
uint32_t nextMsgId;
uint32_t msgRecvLen;
AppSpawnMsgNode *incompleteMsg;
uint32_t nextMsgId; // 校验消息id
uint32_t msgRecvLen; // 已经接收的长度
TimerHandle timer; // 测试消息完整
AppSpawnMsgNode *incompleteMsg; // 保存不完整的消息,额外保存消息头信息
} AppSpawnMsgReceiverCtx;
typedef struct {
AppSpawnClient client;
typedef struct TagAppSpawnConnection {
uint32_t connectionId;
TaskHandle stream;
int32_t fd[2]; // 2 fd count
AppSpawnMsgReceiverCtx receiverCtx;
AppParameter property;
pid_t pid;
} AppSpawnClientExt;
} AppSpawnConnection;
typedef struct AppInfo {
HashNode node;
pid_t pid;
AppOperateType code;
uid_t uid;
char name[0];
} AppInfo, AppSpawnAppInfo;
typedef struct TagAppSpawnStartArg {
RunMode mode;
uint32_t moduleType;
const char *socketName;
const char *serviceName;
uint32_t initArg : 1;
} AppSpawnStartArg;
typedef struct AppSpawnContentExt {
AppSpawnContent content;
uint32_t flags;
TaskHandle server;
SignalHandle sigHandler;
TimerHandle timer;
HashMapHandle appMap; // save app pid and name
} AppSpawnContentExt;
AppInfo *GetAppInfo(pid_t pid);
void SetContentFunction(AppSpawnContent *content);
void AppSpawnColdRun(AppSpawnContent *content, int argc, char *const argv[]);
void AddNwebInfo(pid_t pid, const char *processName);
int GetAppSpawnClientFromArg(int argc, char *const argv[], AppSpawnClientExt *client);
#define SHOW_CLIENT(info, clientExt) \
do { \
APPSPAWN_LOGI("Info %{public}s id %{public}d code %{public}d ", \
info, (clientExt)->client.id, (clientExt)->property.code); \
APPSPAWN_LOGI("processname %{public}s flags 0x%{public}x", \
(clientExt)->property.processName, (clientExt)->property.flags); \
APPSPAWN_LOGI("flags 0x%{public}x cloneFlags 0x%{public}x hapFlags 0x%{public}x", \
(clientExt)->client.flags, (clientExt)->client.cloneFlags, (clientExt)->property.hapFlags); \
APPSPAWN_LOGI("bundleName %{public}s soPath %{public}s", \
(clientExt)->property.bundleName, (clientExt)->property.soPath); \
APPSPAWN_LOGI("Access token apl %{public}s renderCmd %{public}s ownerId %{public}s", \
(clientExt)->property.apl, (clientExt)->property.renderCmd, (clientExt)->property.ownerId); \
APPSPAWN_LOGI("uid %{public}u %{public}u gid count %{public}u", \
(clientExt)->property.uid, (clientExt)->property.gid, (clientExt)->property.gidCount); \
APPSPAWN_LOGI("setAllowInternet %{public}d allowInternet %{public}d ", \
(clientExt)->property.setAllowInternet, (clientExt)->property.allowInternet); \
} while (0)
int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder);
int ChangeAppSpawnMsg2Property(AppSpawnMsgNode *message, AppSpawnClientExt *appProperty);
void DeleteAppSpawnMsg(AppSpawnMsgNode *msgNode);
pid_t NWebSpawnLaunch(void);
void NWebSpawnInit(void);
AppSpawnContent *StartSpawnService(const AppSpawnStartArg *arg, uint32_t argvSize, int argc, char *const argv[]);
void AppSpawnDestroyContent(AppSpawnContent *content);
#ifdef __cplusplus
}

View File

@ -1,102 +0,0 @@
/*
* Copyright (c) 2021-2022 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.
*/
#include <signal.h>
#include <stdbool.h>
#include "appspawn_adapter.h"
#include "appspawn_server.h"
#include "appspawn_service.h"
#include "securec.h"
#include "init_param.h"
#include "syspara/parameter.h"
#include "nwebspawn_lancher.h"
#define APPSPAWN_PRELOAD "libappspawn_helper.z.so"
static void CheckPreload(char *const argv[])
{
char *preload = getenv("LD_PRELOAD");
if (preload && strstr(preload, APPSPAWN_PRELOAD)) {
return;
}
char buf[128] = APPSPAWN_PRELOAD; // 128 is enough in most cases
if (preload && preload[0]) {
int len = sprintf_s(buf, sizeof(buf), "%s:" APPSPAWN_PRELOAD, preload);
APPSPAWN_CHECK(len > 0, return, "preload too long: %{public}s", preload);
}
int ret = setenv("LD_PRELOAD", buf, true);
APPSPAWN_CHECK(ret == 0, return, "setenv fail: %{public}s", buf);
ssize_t nread = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
APPSPAWN_CHECK(nread != -1, return, "readlink fail: /proc/self/exe: %{public}d", errno);
buf[nread] = 0;
ret = execv(buf, argv);
APPSPAWN_LOGE("execv fail: %{public}s: %{public}d: %{public}d", buf, errno, ret);
}
int main(int argc, char *const argv[])
{
if (argc <= 0) {
return 0;
}
CheckPreload(argv);
(void)signal(SIGPIPE, SIG_IGN);
uint32_t argvSize = 0;
int isRet;
int mode = 0;
pid_t pid = 1;
if ((argc > PARAM_INDEX) && (strstr(argv[START_INDEX], APPSPAWN_COLDSTART_KEY) != NULL)) {
argvSize = APP_LEN_PROC_NAME;
mode = 1;
} else {
// calculate child process long name size
uintptr_t start = (uintptr_t)argv[0];
uintptr_t end = (uintptr_t)strchr(argv[argc - 1], 0);
if (end == 0) {
return -1;
}
argvSize = end - start;
if (argvSize > APP_MSG_MAX_SIZE) {
return -1;
}
pid = NwebSpawnLanch();
isRet = memset_s(argv[0], argvSize, 0, (size_t)argvSize) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset argv[0]");
if (pid == 0) {
isRet = strncpy_s(argv[0], argvSize, NWEBSPAWN_SERVER_NAME, strlen(NWEBSPAWN_SERVER_NAME)) != EOK;
} else {
isRet = strncpy_s(argv[0], argvSize, APPSPAWN_SERVER_NAME, strlen(APPSPAWN_SERVER_NAME)) != EOK;
}
APPSPAWN_CHECK(!isRet, return -EINVAL, "strncpy_s appspawn server name error: %{public}d", errno);
}
char *socketName = APPSPAWN_SOCKET_NAME;
if (pid == 0 || strcmp(NWEBSPAWN_COLDSTART_KEY, argv[START_INDEX]) == 0) {
socketName = NWEBSPAWN_SOCKET_NAME;
}
APPSPAWN_LOGI("%s createContent argc %{public}d mode %{public}d %{public}u", socketName, argc, mode, argvSize);
AppSpawnContent *content = AppSpawnCreateContent(socketName, argv[0], argvSize, mode);
APPSPAWN_CHECK(content != NULL, return -1, "Invalid content for nwebspawn");
APPSPAWN_CHECK(content->initAppSpawn != NULL, return -1, "Invalid content for nwebspawn");
APPSPAWN_CHECK(content->runAppSpawn != NULL, return -1, "Invalid content for nwebspawn");
isRet = content->initAppSpawn(content);
APPSPAWN_CHECK(!isRet, return -1, "Init %s failed", socketName);
if (mode == 0) {
AddNwebInfo(pid, NWEBSPAWN_SERVER_NAME);
SystemSetParameter("bootevent.appspawn.started", "true");
}
content->runAppSpawn(content, argc, argv);
return 0;
}

91
standard/nwebspawn_launcher.c Executable file
View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2024 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.
*/
#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include "appspawn.h"
#include "appspawn_modulemgr.h"
#include "appspawn_msg.h"
#include "appspawn_server.h"
#include "appspawn_service.h"
#include "appspawn_utils.h"
#include "parameter.h"
#include "securec.h"
#ifdef CODE_SIGNATURE_ENABLE
#include "code_sign_attr_utils.h"
#endif
#ifdef WITH_SELINUX
#include "selinux/selinux.h"
#endif
#define NWEB_UID 3081
#define NWEB_GID 3081
#define NWEB_NAME "nwebspawn"
#define CAP_NUM 2
#define BITLEN32 32
void NWebSpawnInit(void)
{
APPSPAWN_LOGI("NWebSpawnInit");
#ifdef CODE_SIGNATURE_ENABLE
// ownerId must been set before setcon & setuid
(void)SetXpmOwnerId(PROCESS_OWNERID_EXTEND, NULL);
#endif
setcon("u:r:nwebspawn:s0");
pid_t pid = getpid();
setpriority(PRIO_PROCESS, pid, 0);
struct __user_cap_header_struct capHeader;
capHeader.version = _LINUX_CAPABILITY_VERSION_3;
capHeader.pid = 0;
const uint64_t inheriTable = 0x2000c0;
const uint64_t permitted = 0x2000c0;
const uint64_t effective = 0x2000c0;
struct __user_cap_data_struct capData[CAP_NUM] = {};
for (int j = 0; j < CAP_NUM; ++j) {
capData[0].inheritable = (__u32)(inheriTable);
capData[1].inheritable = (__u32)(inheriTable >> BITLEN32);
capData[0].permitted = (__u32)(permitted);
capData[1].permitted = (__u32)(permitted >> BITLEN32);
capData[0].effective = (__u32)(effective);
capData[1].effective = (__u32)(effective >> BITLEN32);
}
capset(&capHeader, capData);
for (int i = 0; i <= CAP_LAST_CAP; ++i) {
prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0);
}
#ifndef APPSPAWN_TEST
(void)prctl(PR_SET_NAME, NWEB_NAME);
#endif
setuid(NWEB_UID);
setgid(NWEB_GID);
}
pid_t NWebSpawnLaunch(void)
{
pid_t ret = fork();
if (ret == 0) {
NWebSpawnInit();
}
APPSPAWN_LOGI("nwebspawn fork success pid: %{public}d", ret);
return ret;
}

View File

@ -25,8 +25,8 @@ group("unittest") {
if (!defined(ohos_lite)) {
testonly = true
deps = [
"unittest:AppSpawn_ut",
"unittest/app_spawn_client_test:AppSpawn_client_ut",
"unittest/app_spawn_standard_test:AppSpawn_ut",
]
deps += [ "unittest/hnp_test:HnpTest" ]
} else {

View File

@ -129,7 +129,7 @@ int GetParameter(const char *key, const char *def, char *value, uint32_t len)
return strcpy_s(value, len, "true") == 0 ? strlen("true") : -1;
}
if (strcmp(key, "persist.appspawn.reqMgr.timeout") == 0) {
return strcpy_s(value, len, "2") == 0 ? 1 : -1;
return strcpy_s(value, len, "5") == 0 ? 1 : -1;
}
if (strcmp(key, "const.security.developermode.state") == 0) {
return g_developerMode ? (strcpy_s(value, len, "true") == 0 ? strlen("true") : -1) : -1;

View File

@ -55,6 +55,7 @@ AppSpawnSandboxCfg *CreateAppSpawnSandbox(void);
void AddDefaultVariable(void);
int AppSpawnChild(AppSpawnContent *content, AppSpawnClient *client);
int WriteMsgToChild(AppSpawningCtx *property);
int WriteToFile(const char *path, int truncated, pid_t pids[], uint32_t count);
int GetCgroupPath(const AppSpawnedProcess *appInfo, char *buffer, uint32_t buffLen);

View File

@ -18,7 +18,6 @@ ohos_executable("AppSpawnTest") {
sources = [
"${appspawn_path}/test/moduletest/appspawn_test_cmder.cpp",
"${appspawn_path}/test/moduletest/appspawn_test_main.cpp",
"${appspawn_path}/util/src/appspawn_utils.c",
]
include_dirs = [
@ -29,21 +28,20 @@ ohos_executable("AppSpawnTest") {
"${appspawn_path}/modules/ace_adapter",
"${appspawn_path}/modules/common",
"${appspawn_path}/modules/sandbox",
"${appspawn_path}/modules//module_engine//include",
"${appspawn_path}/test/moduletest/threadpool",
"${appspawn_innerkits_path}/include",
"${appspawn_innerkits_path}/client",
"${appspawn_innerkits_path}/permission",
"${appspawn_innerkits_path}/module_engine/include",
"${appspawn_path}/modules/module_engine/include",
"${appspawn_path}/test/mock",
"${appspawn_path}/test/unittest",
"${appspawn_path}/util/include",
"${appspawn_path}/modules/module_engine/include",
]
deps = [
"${appspawn_innerkits_path}/client:appspawn_client",
"${appspawn_path}/test/moduletest/threadpool:libappspawn_threadpool",
"${appspawn_path}/util:libappspawn_util",
]
external_deps = [
@ -65,7 +63,6 @@ ohos_moduletest("AppSpawnModuleTest") {
"${appspawn_path}/test/moduletest/appspawn_client_test.cpp",
"${appspawn_path}/test/moduletest/appspawn_module_test.cpp",
"${appspawn_path}/test/moduletest/appspawn_test_cmder.cpp",
"${appspawn_path}/util/src/appspawn_utils.c",
]
include_dirs = [
@ -80,15 +77,15 @@ ohos_moduletest("AppSpawnModuleTest") {
"${appspawn_innerkits_path}/include",
"${appspawn_innerkits_path}/client",
"${appspawn_innerkits_path}/permission",
"${appspawn_innerkits_path}/module_engine/include",
"${appspawn_path}/modules/module_engine/include",
"${appspawn_path}/test/mock",
"${appspawn_path}/test/unittest",
"${appspawn_path}/util/include",
"${appspawn_path}/modules/module_engine/include",
]
deps = [
"${appspawn_innerkits_path}/client:appspawn_client",
"${appspawn_path}/util:libappspawn_util",
"//third_party/googletest:gtest_main",
]
@ -108,6 +105,7 @@ group("moduletest") {
deps = [
":AppSpawnModuleTest",
":AppSpawnTest",
"plugin-sample:appspawn_plugin_sample",
]
deps += [ "hnp_sample:hnpsample" ]
}

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,9 @@
#include "appspawn.h"
#include "appspawn_msg.h"
#include "appspawn_utils.h"
#include "command_lexer.h"
#include "cJSON.h"
#include "command_lexer.h"
#include "json_utils.h"
#include "securec.h"
#include "thread_manager.h"
@ -41,7 +42,7 @@
namespace OHOS {
namespace AppSpawnModuleTest {
static const std::string g_defaultAppInfo = "{ \
\"msg-type\": 0, \
\"msg-type\": \"MSG_APP_SPAWN\", \
\"msg-flags\": [1, 2 ], \
\"process-name\" : \"com.example.myapplication\", \
\"dac-info\" : { \
@ -170,39 +171,41 @@ int AppSpawnTestCommander::AddBundleInfoFromJson(const cJSON *appInfoConfig, App
return 0;
}
int AppSpawnTestCommander::GetDacInfoFromJson(const cJSON *appInfoConfig, AppDacInfo &info)
int AppSpawnTestCommander::AddDacInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
{
cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "dac-info");
APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
AppDacInfo info = {};
info.uid = GetIntValueFromJsonObj(config, "uid", 0);
info.gid = GetIntValueFromJsonObj(config, "gid", 0);
info.gidCount = GetUint32ArrayFromJson(config, "gid-table", info.gidTable, APP_MAX_GIDS);
char *userName = GetStringFromJsonObj(config, "user-name");
if (userName != nullptr) {
return strcpy_s(info.userName, sizeof(info.userName), userName);
int ret = strcpy_s(info.userName, sizeof(info.userName), userName);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to add userName info req %{public}s", userName);
}
return 0;
return AppSpawnReqMsgSetAppDacInfo(reqHandle, &info);
}
int AppSpawnTestCommander::GetInternetPermissionInfoFromJson(
const cJSON *appInfoConfig, AppSpawnMsgInternetInfo &info)
int AppSpawnTestCommander::AddInternetPermissionInfoFromJson(
const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
{
cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "internet-permission");
APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
info.setAllowInternet = GetIntValueFromJsonObj(config, "set-allow-internet", 0);
info.allowInternet = GetIntValueFromJsonObj(config, "allow-internet", 0);
return 0;
uint8_t setAllowInternet = GetIntValueFromJsonObj(config, "set-allow-internet", 0);
uint8_t allowInternet = GetIntValueFromJsonObj(config, "allow-internet", 0);
return AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, allowInternet, setAllowInternet);
}
int AppSpawnTestCommander::GetAccessTokenFromJson(const cJSON *appInfoConfig, AppSpawnMsgAccessToken &info)
int AppSpawnTestCommander::AddAccessTokenFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
{
cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "access-token");
APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
info.accessTokenIdEx = GetIntValueFromJsonObj(config, "accessTokenIdEx", 0);
return 0;
uint64_t accessTokenIdEx = GetIntValueFromJsonObj(config, "accessTokenIdEx", 0);
return AppSpawnReqMsgSetAppAccessToken(reqHandle, accessTokenIdEx);
}
int AppSpawnTestCommander::AddDomainInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
@ -220,7 +223,7 @@ int AppSpawnTestCommander::AddDomainInfoFromJson(const cJSON *appInfoConfig, App
int AppSpawnTestCommander::AddExtTlv(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
{
cJSON *configs = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "ext-info");
APPSPAWN_CHECK_ONLY_EXPER(configs, return 0);
APPSPAWN_CHECK_ONLY_EXPER(configs != nullptr, return 0);
int ret = 0;
uint32_t count = cJSON_GetArraySize(configs);
@ -241,7 +244,8 @@ int AppSpawnTestCommander::AddExtTlv(const cJSON *appInfoConfig, AppSpawnReqMsgH
dacInfo.gidTable[0] = 101; // 101 test data
dacInfo.gidCount = 1;
(void)strcpy_s(dacInfo.userName, sizeof(dacInfo.userName), processName_.c_str());
ret = AppSpawnReqMsgAddExtInfo(reqHandle, "app-dac-info", reinterpret_cast<uint8_t *>(&dacInfo), sizeof(dacInfo));
ret = AppSpawnReqMsgAddExtInfo(reqHandle,
"app-dac-info", reinterpret_cast<uint8_t *>(&dacInfo), sizeof(dacInfo));
APPSPAWN_CHECK(ret == 0, return ret, "Failed to add ext name app-info");
return ret;
}
@ -254,16 +258,10 @@ int AppSpawnTestCommander::BuildMsgFromJson(const cJSON *appInfoConfig, AppSpawn
ret = AddDomainInfoFromJson(appInfoConfig, reqHandle);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str());
AppDacInfo dacInfo = {};
ret = GetDacInfoFromJson(appInfoConfig, dacInfo);
APPSPAWN_LOGE("*************, %d", dacInfo.gidCount);
APPSPAWN_LOGE("*************, %d", dacInfo.uid);
ret = AppSpawnReqMsgSetAppDacInfo(reqHandle, &dacInfo);
ret = AddDacInfoFromJson(appInfoConfig, reqHandle);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str());
AppSpawnMsgAccessToken token = {};
ret = GetAccessTokenFromJson(appInfoConfig, token);
ret = AppSpawnReqMsgSetAppAccessToken(reqHandle, token.accessTokenIdEx);
ret = AddAccessTokenFromJson(appInfoConfig, reqHandle);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to add access token %{public}s", processName_.c_str());
cJSON *obj = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "permission");
@ -277,10 +275,7 @@ int AppSpawnTestCommander::BuildMsgFromJson(const cJSON *appInfoConfig, AppSpawn
}
}
AppSpawnMsgInternetInfo internetInfo = {};
ret = GetInternetPermissionInfoFromJson(appInfoConfig, internetInfo);
ret = AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle,
internetInfo.allowInternet, internetInfo.setAllowInternet);
ret = AddInternetPermissionInfoFromJson(appInfoConfig, reqHandle);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to internet info %{public}s", processName_.c_str());
std::string ownerId = GetStringFromJsonObj(appInfoConfig, "owner-id");
@ -312,13 +307,31 @@ int AppSpawnTestCommander::CreateOtherMsg(AppSpawnReqMsgHandle &reqHandle, pid_t
return 0;
}
int AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle, const char *defaultConfig)
static uint32_t GetMsgTypeFromJson(const cJSON *json)
{
const char *msgType = GetStringFromJsonObj(json, "msg-type");
if (msgType == nullptr) {
return MSG_APP_SPAWN;
}
if (strcmp(msgType, "MSG_SPAWN_NATIVE_PROCESS") == 0) {
return MSG_SPAWN_NATIVE_PROCESS;
}
if (strcmp(msgType, "MSG_GET_RENDER_TERMINATION_STATUS") == 0) {
return MSG_GET_RENDER_TERMINATION_STATUS;
}
if (strcmp(msgType, "MSG_DUMP") == 0) {
return MSG_DUMP;
}
return MSG_APP_SPAWN;
}
int AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle,
const char *defaultConfig, uint32_t defMsgType)
{
int ret = APPSPAWN_SYSTEM_ERROR;
if (clientHandle_ == NULL) {
const char *name = appSpawn_ ? APPSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME;
ret = AppSpawnClientInit(name, &clientHandle_);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}s", name);
ret = AppSpawnClientInit(appSpawn_ ? APPSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME, &clientHandle_);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}d", appSpawn_);
}
reqHandle = INVALID_REQ_HANDLE;
if (appInfoConfig_) {
@ -342,9 +355,8 @@ int AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle, const char
if (processName_.empty()) {
processName_ = "com.example.myapplication";
}
if (msgType_ == MAX_TYPE_INVALID) {
msgType_ = GetIntValueFromJsonObj(appInfoConfig_, "msg-type", MSG_APP_SPAWN);
}
msgType_ = (msgType_ == MAX_TYPE_INVALID) ? GetMsgTypeFromJson(appInfoConfig_) : msgType_;
msgType_ = (defMsgType != MAX_TYPE_INVALID) ? defMsgType : msgType_;
if (msgType_ == MSG_DUMP) {
return CreateOtherMsg(reqHandle, 0);
} else if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) {
@ -354,11 +366,12 @@ int AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle, const char
ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType_), processName_.c_str(), &reqHandle);
APPSPAWN_CHECK(ret == 0, return ret, "Failed to create req %{public}s", processName_.c_str());
uint32_t msgFlags[64] = {};
uint32_t msgFlags[64] = {}; // 64
uint32_t count = GetUint32ArrayFromJson(appInfoConfig_, "msg-flags", msgFlags, ARRAY_LENGTH(msgFlags));
for (uint32_t j = 0; j < count; j++) {
(void)AppSpawnReqMsgSetAppFlag(reqHandle, static_cast<AppFlagsIndex>(msgFlags[j]));
}
(void)AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NO_SANDBOX);
ret = BuildMsgFromJson(appInfoConfig_, reqHandle);
APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
return ret, "Failed to build req %{public}s", processName_.c_str());
@ -401,7 +414,8 @@ int AppSpawnTestCommander::SendMsg()
}
break;
case MSG_GET_RENDER_TERMINATION_STATUS:
printf("Terminate app %s success, pid %d status 0x%x \n", processName_.c_str(), result.pid, result.result);
printf("Terminate app %s success, pid %d status 0x%x \n",
processName_.c_str(), result.pid, result.result);
break;
default:
printf("Dump server %s result %d \n", server, ret);

View File

@ -25,40 +25,13 @@
#include "appspawn_msg.h"
#include "appspawn_utils.h"
#include "cJSON.h"
#include "json_utils.h"
#include "securec.h"
#include "thread_manager.h"
typedef struct TagThreadContext {
} ThreadContext;
__attribute__((always_inline)) inline char *GetStringFromJsonObj(const cJSON *json, const char *key)
{
APPSPAWN_CHECK_ONLY_EXPER(key != NULL && json != NULL, NULL);
APPSPAWN_CHECK(cJSON_IsObject(json), return NULL, "json is not object %{public}s %s", key, cJSON_Print(json));
cJSON *obj = cJSON_GetObjectItemCaseSensitive(json, key);
APPSPAWN_CHECK_ONLY_EXPER(obj != NULL, return NULL);
APPSPAWN_CHECK(cJSON_IsString(obj), return NULL, "json is not string %{public}s %s", key, cJSON_Print(obj));
return cJSON_GetStringValue(obj);
}
__attribute__((always_inline)) inline bool GetBoolValueFromJsonObj(const cJSON *json, const char *key, bool def)
{
char *value = GetStringFromJsonObj(json, key);
APPSPAWN_CHECK_ONLY_EXPER(value != NULL, return def);
if (strcmp(value, "true") == 0 || strcmp(value, "ON") == 0 || strcmp(value, "True") == 0) {
return true;
}
return false;
}
__attribute__((always_inline)) inline uint32_t GetIntValueFromJsonObj(const cJSON *json, const char *key, uint32_t def)
{
APPSPAWN_CHECK(json != NULL, return def, "Invalid json");
APPSPAWN_CHECK(cJSON_IsObject(json), return def, "json is not object.");
return cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(json, key));
}
namespace OHOS {
namespace AppSpawnModuleTest {
class AppSpawnTestCommander : public ThreadContext {
@ -68,7 +41,14 @@ public:
exit_ = 0;
appSpawn_ = 1;
dumpFlags = 0;
msgType_ = 0;
msgType_ = MAX_TYPE_INVALID;
}
AppSpawnTestCommander(int serverType)
{
exit_ = 0;
appSpawn_ = serverType;
dumpFlags = 0;
msgType_ = MAX_TYPE_INVALID;
}
~AppSpawnTestCommander()
{
@ -86,10 +66,15 @@ public:
int Run();
int CreateOtherMsg(AppSpawnReqMsgHandle &reqHandle, pid_t pid);
int CreateMsg(AppSpawnReqMsgHandle &reqHandle, const char *defaultConfig);
int CreateMsg(AppSpawnReqMsgHandle &reqHandle, const char *defaultConfig,
uint32_t defMsgType = MAX_TYPE_INVALID);
int StartSendMsg();
int SendMsg();
AppSpawnClientHandle GetClientHandle() { return clientHandle_; }
AppSpawnClientHandle GetClientHandle()
{
return clientHandle_;
}
private:
std::vector<std::string> split(const std::string &str, const std::string &pattern);
int InitPtyInterface();
@ -97,9 +82,9 @@ private:
int AddExtTlv(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
int BuildMsgFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
int AddBundleInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
int GetDacInfoFromJson(const cJSON *appInfoConfig, AppDacInfo &info);
int GetInternetPermissionInfoFromJson(const cJSON *appInfoConfig, AppSpawnMsgInternetInfo &info);
int GetAccessTokenFromJson(const cJSON *appInfoConfig, AppSpawnMsgAccessToken &info);
int AddDacInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
int AddInternetPermissionInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
int AddAccessTokenFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
int AddDomainInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle);
uint32_t GetUint32ArrayFromJson(const cJSON *json, const char *name, uint32_t dataArray[], uint32_t maxCount);
static AppSpawnTestCommander *ConvertTo(const ThreadContext *context)
@ -121,7 +106,7 @@ private:
std::string ptyName_{};
std::string testFileName_{};
std::string processName_{};
cJSON *appInfoConfig_ { nullptr};
cJSON *appInfoConfig_{nullptr};
AppSpawnClientHandle clientHandle_{nullptr};
ThreadMgr threadMgr_{nullptr};
ThreadTaskHandle inputHandle_{0};

View File

@ -29,6 +29,7 @@
#include "appspawn_utils.h"
#include "appspawn_test_cmder.h"
#include "command_lexer.h"
#include "json_utils.h"
#include "cJSON.h"
#include "securec.h"
#include "thread_manager.h"

View File

@ -19,71 +19,79 @@
static int TestPluginReportProcessExit(const AppSpawnMgr *content, const AppSpawnedProcess *appInfo)
{
APPSPAWN_LOGV("Process %{public}s exit", appInfo->name);
APPSPAWN_LOGI("Process %{public}s exit", appInfo->name);
return 0;
}
static int TestPluginReportProcessAdd(const AppSpawnMgr *content, const AppSpawnedProcess *appInfo)
{
APPSPAWN_LOGV("Process %{public}s add", appInfo->name);
APPSPAWN_LOGI("Process %{public}s add", appInfo->name);
return 0;
}
static int TestPluginPreload(AppSpawnMgr *content)
{
APPSPAWN_LOGV("TestPlugin preload");
APPSPAWN_LOGI("TestPlugin preload");
return 0;
}
static int TestPluginExit(AppSpawnMgr *content)
{
APPSPAWN_LOGI("TestPlugin exit");
return 0;
}
static int TestPluginPreFork(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin pre fork for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin pre fork for %{public}s ", GetProcessName(property));
return 0;
}
static int TestPluginPreReply(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin pre reply to client for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin pre reply to client for %{public}s ", GetProcessName(property));
return 0;
}
static int TestPluginPostReply(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin post reply to client for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin post reply to client for %{public}s ", GetProcessName(property));
return 0;
}
static int ChildPreColdBoot(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin pre cold boot for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin pre cold boot for %{public}s ", GetProcessName(property));
return 0;
}
static int ChildExecute(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin set app property for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin set app property for %{public}s ", GetProcessName(property));
return 0;
}
static int ChildPreRely(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin pre reply to parent for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin pre reply to parent for %{public}s ", GetProcessName(property));
return 0;
}
static int ChildPostRely(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin post reply to parent for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin post reply to parent for %{public}s ", GetProcessName(property));
return 0;
}
static int ChildPreRun(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("TestPlugin pre child run for %{public}s ", GetProcessName(property));
APPSPAWN_LOGI("TestPlugin pre child run for %{public}s ", GetProcessName(property));
return 0;
}
MODULE_CONSTRUCTOR(void)
{
APPSPAWN_LOGV("Load test plugin module ...");
APPSPAWN_LOGI("Load test plugin module ...");
AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, TestPluginReportProcessExit);
AddProcessMgrHook(STAGE_SERVER_APP_ADD, 0, TestPluginReportProcessAdd);
AddServerStageHook(STAGE_SERVER_EXIT, 0, TestPluginExit);
AddPreloadHook(HOOK_PRIO_LOWEST - 1, TestPluginPreload);
AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_COMMON - 1, TestPluginPreFork);
AddAppSpawnHook(STAGE_PARENT_POST_RELY, HOOK_PRIO_COMMON - 1, TestPluginPostReply);

View File

@ -108,8 +108,8 @@ static int AddExecutor(ThreadManager *mgr, const TaskNode *task)
ListNode *node = task->executorList.next;
while (node != &task->executorList) {
TaskExecuteNode *executor = ListEntry(node, TaskExecuteNode, node);
APPSPAWN_LOGV("AddExecutor task: %{public}u executorCount: %{public}u executor: %{public}p %{public}u",
task->taskId, mgr->executorCount, executor, executor->task->taskId);
APPSPAWN_LOGV("AddExecutor task: %{public}u executorCount: %{public}u executor: %{public}u",
task->taskId, mgr->executorCount, executor->task->taskId);
// 插入尾部执行
pthread_mutex_lock(&mgr->mutex);
@ -131,7 +131,7 @@ static void RunExecutor(ThreadManager *mgr, ThreadNode *threadNode, uint32_t max
TaskExecuteNode *executor = PopTaskExecutor(mgr);
uint32_t count = 0;
while (executor != NULL && !threadNode->threadExit) {
APPSPAWN_LOGV("RunExecutor task: %{public}u executor: %{public}p", executor->task->taskId, executor);
APPSPAWN_LOGV("RunExecutor task: %{public}u", executor->task->taskId);
atomic_fetch_add(&executor->task->finishTaskCount, 1);
executor->executor(executor->task->taskId, executor->context);
count++;

View File

@ -1,155 +0,0 @@
# Copyright (c) 2022 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.
import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni")
config("utest_config") {
cflags = [
"-Wno-implicit-fallthrough",
"-Wno-unused-function",
"-Dprivate=public",
"-Dprotected=public",
]
cflags_cc = [
"-Wno-implicit-fallthrough",
"-fexceptions",
]
if (build_selinux) {
cflags += [ "-DWITH_SELINUX" ]
}
if (build_seccomp) {
cflags += [ "-DWITH_SECCOMP" ]
}
include_dirs = [
"${appspawn_path}",
"${appspawn_path}/test/unittest",
"${appspawn_path}/test/mock/include",
"${appspawn_path}/common",
"${appspawn_path}/standard",
"${appspawn_path}/adapter",
"${appspawn_path}/adapter/sysevent",
"${appspawn_path}/modules/sandbox",
"${appspawn_path}/interfaces/innerkits/include",
"${appspawn_path}/interfaces/innerkits_new/include",
"${appspawn_path}/util/include",
"//commonlibrary/c_utils/base/include",
"ability_runtime_kits_path/appkit/native/app/include",
"${ability_runtime_path}/interfaces/innerkits/app_manager/include/appmgr",
"${ability_runtime_path}/interfaces/innerkits/ability_manager/include",
"ability_runtime_kits_path/ability/native/include",
"${ability_runtime_path}/services/abilitymgr/include",
"//base/global/resource_management/interfaces/inner_api/include",
"//base/security/access_token/interfaces/innerkits/token_setproc/include",
"//base/security/selinux_adapter/interfaces/policycoreutils/include",
"//base/startup/init/services/log",
"//base/startup/init/services/loopevent/include",
"//base/startup/init/services/loopevent/task",
"//base/startup/init/services/loopevent/utils",
"//third_party/json/include",
"//third_party/selinux/libselinux/include",
]
}
if (!defined(ohos_lite)) {
ohos_unittest("AppSpawn_ut") {
module_out_path = "${module_output_path}"
deps = []
defines = [
"clone=CloneStub",
"bind=BindStub",
"listen=ListenStub",
"lchown=LchownStub",
"lchmod=LchmodStub",
"getsockopt=GetsockoptStub",
"setgroups=SetgroupsStub",
"setresuid=SetresuidStub",
"setresgid=SetresgidStub",
"capset=CapsetStub",
"dlopen=DlopenStub",
"dlsym=DlsymStub",
"dlclose=DlcloseStub",
"waitpid=WaitpidStub",
"HapContext=HapContextStub",
"APPSPAWN_TEST",
"OHOS_DEBUG",
"GRAPHIC_PERMISSION_CHECK",
]
sources = [
"${appspawn_path}/adapter/appspawn_ace.cpp",
"${appspawn_path}/adapter/appspawn_adapter.cpp",
"${appspawn_path}/adapter/appspawn_cgroup.c",
"${appspawn_path}/adapter/appspawn_nweb.cpp",
"${appspawn_path}/adapter/appspawn_sandbox.cpp",
"${appspawn_path}/adapter/nwebspawn_lancher.cpp",
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/interfaces/innerkits/client/appspawn_socket.cpp",
"${appspawn_path}/interfaces/innerkits/client/client_socket.cpp",
"${appspawn_path}/interfaces/innerkits/src/appspawn_mount_permission.cpp",
"${appspawn_path}/standard/appspawn_msgmgr.c",
"${appspawn_path}/standard/appspawn_process.c",
"${appspawn_path}/standard/appspawn_service.c",
"${appspawn_path}/util/src/command_lexer.cpp",
"${appspawn_path}/util/src/env_utils.cpp",
"${appspawn_path}/util/src/json_utils.cpp",
"${appspawn_path}/util/src/param_helper.c",
"${appspawn_path}/util/src/sandbox_utils.cpp",
]
sources += [
"${appspawn_path}/test/unittest/app_spawn_socket_test/app_spawn_socket_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_command_lexer_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_standard_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_stub.cpp",
"${appspawn_path}/test/unittest/client_socket_test/client_socket_test.cpp",
]
configs = [ "//base/startup/appspawn/test/unittest:utest_config" ]
deps += [ "//third_party/selinux:libselinux" ]
external_deps = [
"ability_base:want",
"ability_runtime:app_manager",
"ability_runtime:appkit_native",
"ability_runtime:runtime",
"access_token:libtoken_setproc",
"access_token:libtokenid_sdk",
"ace_engine:ace_forward_compatibility",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"cJSON:cjson",
"c_utils:utils",
"config_policy:configpolicy_util",
"eventhandler:libeventhandler",
"hilog:libhilog",
"hitrace:hitrace_meter",
"init:libbegetutil",
"init:seccomp",
"ipc:ipc_core",
"napi:ace_napi",
"os_account:os_account_innerkits",
"resource_management:global_resmgr",
]
if (appspawn_report_event) {
defines += [ "REPORT_EVENT" ]
external_deps += [ "hisysevent:libhisysevent" ]
sources += [ "${appspawn_path}/adapter/sysevent/event_reporter.cpp" ]
}
}
}

View File

@ -18,61 +18,69 @@ ohos_unittest("AppSpawn_client_ut") {
module_out_path = "${module_output_path}"
deps = []
defines = [
"clone=CloneStub",
"bind=BindStub",
"listen=ListenStub",
"lchown=LchownStub",
"lchmod=LchmodStub",
"getsockopt=GetsockoptStub",
"setgroups=SetgroupsStub",
"setresuid=SetresuidStub",
"setresgid=SetresgidStub",
"capset=CapsetStub",
"dlopen=DlopenStub",
"dlsym=DlsymStub",
"dlclose=DlcloseStub",
"waitpid=WaitpidStub",
"HapContext=HapContextStub",
"APPSPAWN_TEST",
"APPSPAWN_CLIENT",
"OHOS_DEBUG",
"GRAPHIC_PERMISSION_CHECK",
]
include_dirs = [
"${appspawn_path}",
"${appspawn_path}/test/unittest",
"${appspawn_path}/common",
"${appspawn_path}/standard",
"${appspawn_path}/adapter",
"${appspawn_path}/adapter/sysevent",
"${appspawn_path}/modules/modulemgr",
"${appspawn_path}/modules/ace_adapter",
"${appspawn_path}/modules/common",
"${appspawn_path}/modules/sandbox",
"${appspawn_path}/modules//module_engine//include",
"${appspawn_path}/interfaces/innerkits_new/include",
"${appspawn_path}/interfaces/innerkits_new/client",
"${appspawn_path}/interfaces/innerkits_new/permission",
"${appspawn_path}/util/include",
"${appspawn_path}/interfaces/innerkits_new/module_engine/include",
"${appspawn_path}/modules/module_engine/include",
"//third_party/json/include",
"${appspawn_innerkits_path}/client",
"${appspawn_innerkits_path}/include",
"${appspawn_innerkits_path}/permission",
"${appspawn_path}/util/include",
"${appspawn_path}/test/unittest",
"${appspawn_path}/test/mock",
]
# client
sources = [
"${appspawn_path}/interfaces/innerkits_new/client/appspawn_client.c",
"${appspawn_path}/interfaces/innerkits_new/client/appspawn_msg.c",
"${appspawn_path}/interfaces/innerkits_new/permission/appspawn_mount_permission.c",
"${appspawn_innerkits_path}/client/appspawn_client.c",
"${appspawn_innerkits_path}/client/appspawn_msg.c",
"${appspawn_innerkits_path}/permission/appspawn_mount_permission.c",
"${appspawn_path}/modules/sandbox/appspawn_permission.c",
]
# server
sources += [
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/modules/modulemgr/appspawn_modulemgr.c",
"${appspawn_path}/standard/appspawn_appmgr.c",
"${appspawn_path}/standard/appspawn_msgmgr.c",
"${appspawn_path}/standard/appspawn_service.c",
"${appspawn_path}/standard/nwebspawn_launcher.c",
"${appspawn_path}/util/src/appspawn_utils.c",
]
sources += [ "${appspawn_path}/test/unittest/app_spawn_client_test/app_spawn_interface_test.cpp" ]
deps += [
"//third_party/cJSON:cjson",
"//third_party/selinux:libselinux",
sources += [
"${appspawn_path}/test/unittest/app_spawn_client_test/app_spawn_client_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_client_test/app_spawn_interface_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_test_helper.cpp",
]
if (asan_detector || is_asan) {
defines += [ "ASAN_DETECTOR" ]
}
external_deps = [
"cJSON:cjson",
"c_utils:utils",
"config_policy:configpolicy_util",
"hilog:libhilog",
"init:libbegetutil",
]
if (build_selinux) {
defines += [ "WITH_SELINUX" ]
external_deps += [
"selinux:libselinux",
"selinux_adapter:libhap_restorecon",
]
}
}

View File

@ -27,6 +27,7 @@ if (defined(ohos_lite)) {
"//base/startup/appspawn/interfaces/innerkits/include",
"//base/startup/appspawn/common/",
"//base/startup/appspawn/lite/",
"//base/startup/appspawn/util/include",
"//base/startup/init/interfaces/innerkits/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/innerkits/hilog",
"//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr",

View File

@ -394,11 +394,9 @@ HWTEST_F(AppSpawnLiteTest, SetContentFunctionTest_001, TestSize.Level0)
int ret = SplitMessage(validStr.c_str(), validStr.length(), &liteClient->message);
EXPECT_EQ(ret, 0);
EXPECT_EQ(content->setProcessName(content, &liteClient->client, (char*)longProcName.c_str(),
longProcNameLen), 0);
EXPECT_EQ(content->setKeepCapabilities(content, &liteClient->client), 0);
EXPECT_EQ(content->setUidGid(content, &liteClient->client), 0);
EXPECT_EQ(content->setCapabilities(content, &liteClient->client), 0);
ret = AppSpawnExecuteSpawningHook(content, &liteClient->client);
EXPECT_EQ(ret, 0);
content->runChildProcessor(content, &liteClient->client);
free(liteClient);
GTEST_LOG_(INFO) << "SetContentFunctionTest_001 end";

View File

@ -70,7 +70,6 @@ ohos_unittest("AppSpawn_ut") {
"${appspawn_path}/standard/appspawn_msgmgr.c",
"${appspawn_path}/standard/appspawn_service.c",
"${appspawn_path}/standard/nwebspawn_launcher.c",
"${appspawn_path}/util/src/appspawn_base64.c",
"${appspawn_path}/util/src/appspawn_utils.c",
]
@ -110,14 +109,24 @@ ohos_unittest("AppSpawn_ut") {
include_dirs += [ "${appspawn_path}/test/unittest" ]
sources += [
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_cgroup_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_child_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_cold_run_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_command_lexer_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_module_interface_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/nweb_spawn_service_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_test_helper.cpp",
]
if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) {
sources += [ "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandbox_new_test.cpp" ]
} else {
sources += [
"${appspawn_path}/modules/sandbox/sandbox_utils.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp",
]
}
configs = [ "${appspawn_path}:appspawn_config" ]
external_deps = [
"ability_base:want",
@ -150,8 +159,10 @@ ohos_unittest("AppSpawn_ut") {
if (build_selinux) {
defines += [ "WITH_SELINUX" ]
deps += [ "//third_party/selinux:libselinux" ]
external_deps += [ "selinux_adapter:libhap_restorecon" ]
external_deps += [
"selinux:libselinux",
"selinux_adapter:libhap_restorecon",
]
}
if (appspawn_report_event) {

View File

@ -0,0 +1,467 @@
/*
* Copyright (c) 2024 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.
*/
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <unistd.h>
#include <gtest/gtest.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "appspawn_modulemgr.h"
#include "appspawn_server.h"
#include "appspawn_manager.h"
#include "json_utils.h"
#include "parameter.h"
#include "securec.h"
#include "app_spawn_stub.h"
#include "app_spawn_test_helper.h"
using namespace testing;
using namespace testing::ext;
using namespace OHOS;
namespace OHOS {
static AppSpawnTestHelper g_testHelper;
class AppSpawnChildTest : public testing::Test {
public:
static void SetUpTestCase() {}
static void TearDownTestCase() {}
void SetUp() {}
void TearDown() {}
};
HWTEST(AppSpawnChildTest, App_Spawn_Child_001, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
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);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content); // 预加载解析sandbox
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, App_Spawn_Child_002, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
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);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, App_Spawn_Child_003, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, App_Spawn_Child_004, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and no render cmd
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, App_Spawn_Child_005, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and render
g_testHelper.SetTestUid(10010029); // 10010029
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);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
ASSERT_EQ(ret, 0);
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, App_Spawn_Child_006, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and no render cmd
g_testHelper.SetTestUid(10010029); // 10010029
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);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
const char *appEnv = "{\"test.name1\": \"test.value1\", \"test.name2\": \"test.value2\"}";
ret = AppSpawnReqMsgAddExtInfo(reqHandle, "AppEnv",
reinterpret_cast<uint8_t *>(const_cast<char *>(appEnv)), strlen(appEnv) + 1);
APPSPAWN_CHECK(ret == 0, break, "Failed to add ext tlv %{public}s", appEnv);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
ASSERT_EQ(ret, 0);
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, NWeb_Spawn_Child_001, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req ");
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content); // 预加载解析sandbox
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, NWeb_Spawn_Child_002, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req");
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content); // 预加载解析sandbox
ret = APPSPAWN_ARG_INVALID;
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ASANENABLED);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, NWeb_Spawn_Child_004, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and no render cmd
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req");
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnChildTest, NWeb_Spawn_Child_005, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and render
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req");
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
} // namespace OHOS

View File

@ -182,15 +182,16 @@ HWTEST(AppSpawnColdRunTest, App_Spawn_Cold_Run_002, TestSize.Level0)
static std::string GetColdRunArgs(AppSpawningCtx *property, const char *arg)
{
std::string argStr = arg;
const uint32_t memSize = (property->message->msgHeader.msgLen % 1024 + 1) * 1024; // 1024
property->forkCtx.shmId = shmget(IPC_PRIVATE, memSize, 0600); // 0600 mask
APPSPAWN_CHECK(property->forkCtx.shmId >= 0, return nullptr,
int ret = WriteMsgToChild(property);
APPSPAWN_CHECK(ret == 0, return nullptr,
"Failed to get shm for %{public}s errno %{public}d", GetProcessName(property), errno);
property->forkCtx.memSize = memSize;
SendAppSpawnMsgToChild(property, property->message);
argStr += "null";
argStr += " -fd -1 0 ";
argStr += std::to_string(property->forkCtx.shmId);
argStr += std::to_string(property->forkCtx.msgSize);
argStr += " -param ";
argStr += GetProcessName(property);
argStr += " ";
argStr += std::to_string(property->client.id);
return argStr;
}
@ -214,7 +215,7 @@ HWTEST(AppSpawnColdRunTest, App_Spawn_Cold_Run_003, TestSize.Level0)
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
std::string cmd = GetColdRunArgs(property, "appspawn -mode app_cold -param ");
std::string cmd = GetColdRunArgs(property, "appspawn -mode app_cold ");
content = AppSpawnTestHelper::StartSpawnServer(cmd, args);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
@ -252,7 +253,7 @@ HWTEST(AppSpawnColdRunTest, App_Spawn_Cold_Run_004, TestSize.Level0)
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
std::string cmd = GetColdRunArgs(property, "appspawn -mode nweb_cold -param ");
std::string cmd = GetColdRunArgs(property, "appspawn -mode nweb_cold ");
content = AppSpawnTestHelper::StartSpawnServer(cmd, args);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ASSERT_EQ(content->mode, MODE_FOR_NWEB_COLD_RUN);
@ -297,7 +298,7 @@ HWTEST(AppSpawnColdRunTest, App_Spawn_Cold_Run_005, TestSize.Level0)
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
std::string cmd = GetColdRunArgs(property, "appspawn -mode app_cold -param ");
std::string cmd = GetColdRunArgs(property, "appspawn -mode app_cold ");
content = AppSpawnTestHelper::StartSpawnServer(cmd, args);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ASSERT_EQ(content->mode, MODE_FOR_APP_COLD_RUN);
@ -342,7 +343,7 @@ HWTEST(AppSpawnColdRunTest, App_Spawn_Cold_Run_006, TestSize.Level0)
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
std::string cmd = GetColdRunArgs(property, "appspawn -mode app_cold -param ");
std::string cmd = GetColdRunArgs(property, "appspawn -mode app_cold ");
content = AppSpawnTestHelper::StartSpawnServer(cmd, args);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ASSERT_EQ(content->mode, MODE_FOR_APP_COLD_RUN);
@ -439,155 +440,4 @@ HWTEST(AppSpawnColdRunTest, App_Spawn_Cold_Run_009, TestSize.Level0)
ASSERT_EQ(ret, 0);
}
static int TestBase64(const char *data)
{
uint32_t outLen = 0;
uint32_t inLen = strlen(data);
char *encodeData = nullptr;
uint8_t *result = nullptr;
int ret = -1;
do {
encodeData = Base64Encode(reinterpret_cast<const uint8_t *>(data), inLen);
APPSPAWN_CHECK(encodeData != nullptr, break, "Failed encode %{public}s", data);
result = Base64Decode(encodeData, strlen(encodeData), &outLen);
APPSPAWN_CHECK(result != nullptr, break, "Failed decode %{public}s", data);
APPSPAWN_CHECK(outLen == inLen, break, "Failed len %{public}s %{public}d %{public}d", data, outLen, inLen);
APPSPAWN_CHECK(memcmp(reinterpret_cast<char *>(result), data, outLen) == 0,
break, "result %{public}s %{public}s", data, result);
ret = 0;
} while (0);
if (encodeData) {
free(encodeData);
}
if (result) {
free(result);
}
return ret;
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_001, TestSize.Level0)
{
const char *data = "a";
int ret = TestBase64(data);
ASSERT_EQ(ret, 0);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_002, TestSize.Level0)
{
const char *data = "ab";
int ret = TestBase64(data);
ASSERT_EQ(ret, 0);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_003, TestSize.Level0)
{
const char *data = "abc";
int ret = TestBase64(data);
ASSERT_EQ(ret, 0);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_004, TestSize.Level0)
{
const char *data = "abcd";
int ret = TestBase64(data);
ASSERT_EQ(ret, 0);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_005, TestSize.Level0)
{
const char *data = "abcde";
int ret = TestBase64(data);
ASSERT_EQ(ret, 0);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_006, TestSize.Level0)
{
const char *data = "abcdedf";
int ret = TestBase64(data);
ASSERT_EQ(ret, 0);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_007, TestSize.Level0)
{
const char *data = "abcdedf";
uint32_t outLen = 0;
uint8_t *result = Base64Decode(data, strlen(data), &outLen);
ASSERT_EQ(result == nullptr, 1);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_008, TestSize.Level0)
{
const char *data = "abcdedf";
uint32_t outLen = 0;
uint8_t *result = Base64Decode(data, strlen(data) + 1, &outLen);
ASSERT_EQ(result == nullptr, 1);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_009, TestSize.Level0)
{
const char *data = "abcdedf{";
uint32_t outLen = 0;
uint8_t *result = Base64Decode(data, strlen(data), &outLen);
ASSERT_EQ(result == nullptr, 1);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_010, TestSize.Level0)
{
const char *data = "*abcdedf{";
uint32_t outLen = 0;
uint8_t *result = Base64Decode(data, strlen(data), &outLen);
ASSERT_EQ(result == nullptr, 1);
}
/**
* @brief base64
*
*/
HWTEST(AppSpawnColdRunTest, App_Spawn_Base64_011, TestSize.Level0)
{
const char *data = "a.bcdedf";
uint32_t outLen = 0;
uint8_t *result = Base64Decode(data, strlen(data), &outLen);
ASSERT_EQ(result == nullptr, 1);
}
} // namespace OHOS

View File

@ -0,0 +1,779 @@
/*
* Copyright (c) 2024-2024 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.
*/
#include <gtest/gtest.h>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "appspawn.h"
#include "appspawn_hook.h"
#include "appspawn_manager.h"
#include "appspawn_modulemgr.h"
#include "appspawn_permission.h"
#include "appspawn_sandbox.h"
#include "appspawn_utils.h"
#include "securec.h"
#include "app_spawn_stub.h"
#include "app_spawn_test_helper.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
class AppSpawnModuleInterfaceTest : public testing::Test {
public:
static void SetUpTestCase() {}
static void TearDownTestCase() {}
void SetUp() {}
void TearDown() {}
};
/**
* @brief test for appspawn_manager.h
*
*/
/**
* @brief IsNWebSpawnMode
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_IsNWebSpawnMode_001, TestSize.Level0)
{
int ret = IsNWebSpawnMode(nullptr);
EXPECT_EQ(0, ret); // false
AppSpawnMgr content;
content.content.mode = MODE_FOR_NWEB_SPAWN;
ret = IsNWebSpawnMode(&content);
EXPECT_EQ(1, ret); // true
content.content.mode = MODE_INVALID;
ret = IsNWebSpawnMode(&content);
EXPECT_EQ(0, ret); // true
}
/**
* @brief IsColdRunMode
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_IsColdRunMode_001, TestSize.Level0)
{
int ret = IsColdRunMode(nullptr);
EXPECT_EQ(0, ret); // false
AppSpawnMgr content;
content.content.mode = MODE_FOR_APP_COLD_RUN;
ret = IsColdRunMode(&content);
EXPECT_EQ(1, ret); // true
content.content.mode = MODE_FOR_NWEB_COLD_RUN;
ret = IsColdRunMode(&content);
EXPECT_EQ(1, ret); // true
content.content.mode = MODE_INVALID;
ret = IsColdRunMode(&content);
EXPECT_EQ(0, ret); // true
}
/**
* @brief GetAppSpawnMsgType
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetAppSpawnMsgType_001, TestSize.Level0)
{
int ret = GetAppSpawnMsgType(nullptr);
EXPECT_EQ(MAX_TYPE_INVALID, ret);
AppSpawningCtx content = {};
AppSpawnMsgNode node = {};
content.message = &node;
ret = GetAppSpawnMsgType(&content);
EXPECT_NE(MAX_TYPE_INVALID, ret);
content.message->msgHeader.msgType = MODE_INVALID;
ret = GetAppSpawnMsgType(&content);
EXPECT_EQ(MAX_TYPE_INVALID, ret);
}
/**
* @brief GetBundleName
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetBundleName_001, TestSize.Level0)
{
const char *bundleName = GetBundleName(nullptr);
EXPECT_EQ(nullptr, bundleName);
}
/**
* @brief GetAppProperty
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetAppProperty_001, TestSize.Level0)
{
void *ret = GetAppProperty(nullptr, 8);
EXPECT_EQ(nullptr, ret); // false
AppSpawningCtx content = {};
AppSpawnMsgNode node = {};
content.message = &node;
ret = GetAppProperty(&content, 8);
EXPECT_EQ(nullptr, ret); // true
ret = GetAppProperty(&content, 9);
EXPECT_EQ(nullptr, ret); // true
ret = GetAppProperty(&content, 10);
EXPECT_EQ(nullptr, ret); // true
}
/**
* @brief GetProcessName
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetProcessName_001, TestSize.Level0)
{
const char *ret = GetProcessName(nullptr);
EXPECT_EQ(nullptr, ret); // false
AppSpawningCtx content = {};
AppSpawnMsgNode node = {};
content.message = &node;
const char *processName = "com.example.myapplication";
int isRst = strncpy_s(content.message->msgHeader.processName, sizeof(content.message->msgHeader.processName) - 1,
processName, strlen(processName));
EXPECT_EQ(0, isRst);
ret = GetProcessName(&content);
EXPECT_NE(nullptr, ret); // true
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_IsDeveloperModeOn_001, TestSize.Level0)
{
int ret = IsDeveloperModeOn(nullptr);
EXPECT_EQ(0, ret); // false
AppSpawningCtx content = {};
content.client.flags = APP_DEVELOPER_MODE;
ret = IsDeveloperModeOn(&content);
EXPECT_EQ(1, ret);
content.client.flags = APP_COLD_START;
ret = IsDeveloperModeOn(&content);
EXPECT_EQ(0, ret);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetAppPropertyExt_001, TestSize.Level0)
{
uint32_t size = strlen("xxx");
void *ret = GetAppPropertyExt(nullptr, "xxx", &size);
EXPECT_EQ(nullptr, ret); // false
AppSpawningCtx context;
ret = GetAppPropertyExt(&context, nullptr, &size);
EXPECT_EQ(nullptr, ret); // false
context.message = nullptr;
ret = GetAppPropertyExt(&context, "name", &size);
EXPECT_EQ(nullptr, ret); // false
}
/**
* @brief test interface in appspawn_modulemgr.h
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_AppSpawnModuleMgrInstall_001, TestSize.Level1)
{
int ret = AppSpawnModuleMgrInstall(nullptr);
EXPECT_NE(0, ret);
ret = AppSpawnLoadAutoRunModules(MODULE_MAX);
EXPECT_NE(0, ret);
ret = AppSpawnLoadAutoRunModules(MODULE_MAX);
EXPECT_NE(0, ret);
ret = AppSpawnModuleMgrInstall("/");
EXPECT_EQ(0, ret);
ret = AppSpawnModuleMgrInstall("");
EXPECT_EQ(0, ret);
ret = AppSpawnModuleMgrInstall("libappspawn_asan");
EXPECT_EQ(0, ret);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_AppSpawnLoadAutoRunModules_001, TestSize.Level1)
{
int ret = AppSpawnLoadAutoRunModules(MODULE_DEFAULT);
EXPECT_EQ(0, ret);
ret = AppSpawnLoadAutoRunModules(MODULE_APPSPAWN);
EXPECT_EQ(0, ret);
ret = AppSpawnLoadAutoRunModules(MODULE_NWEBSPAWN);
EXPECT_EQ(0, ret);
ret = AppSpawnLoadAutoRunModules(MODULE_COMMON);
EXPECT_EQ(0, ret);
ret = AppSpawnLoadAutoRunModules(MODULE_MAX);
EXPECT_NE(0, ret);
ret = AppSpawnLoadAutoRunModules(100);
EXPECT_NE(0, ret);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_AppSpawnModuleMgrUnInstall_001, TestSize.Level1)
{
AppSpawnModuleMgrUnInstall(MODULE_DEFAULT);
AppSpawnModuleMgrUnInstall(MODULE_APPSPAWN);
AppSpawnModuleMgrUnInstall(MODULE_NWEBSPAWN);
AppSpawnModuleMgrUnInstall(MODULE_COMMON);
AppSpawnModuleMgrUnInstall(MODULE_MAX);
AppSpawnModuleMgrUnInstall(100);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_DeleteAppSpawnHookMgr_001, TestSize.Level1)
{
DeleteAppSpawnHookMgr();
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_ServerStageHookExecute_001, TestSize.Level1)
{
int ret = ServerStageHookExecute(static_cast<AppSpawnHookStage>(0), nullptr);
EXPECT_NE(0, ret);
AppSpawnContent content;
content.longProcName = nullptr;
content.longProcNameLen = 256;
content.coldStartApp = nullptr;
content.runAppSpawn = nullptr;
ret = ServerStageHookExecute(static_cast<AppSpawnHookStage>(0), &content);
EXPECT_NE(0, ret);
}
/**
* @brief int ProcessMgrHookExecute(AppSpawnHookStage stage, const AppSpawnContent *content,
* const AppSpawnedProcess *appInfo);
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_ProcessMgrHookExecute_001, TestSize.Level1)
{
TagAppSpawnedProcess appInfo;
appInfo.pid = 33; // 33
appInfo.uid = 200000 * 200 + 21; // 200000 200 21
appInfo.max = 0;
appInfo.exitStatus = 0;
AppSpawnContent content;
content.longProcName = nullptr;
content.longProcNameLen = 256;
content.coldStartApp = nullptr;
content.runAppSpawn = nullptr;
int ret = ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, &content, &appInfo);
EXPECT_EQ(0, ret);
ret = ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, &content, &appInfo);
EXPECT_EQ(0, ret);
ret = ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, nullptr, nullptr);
EXPECT_NE(0, ret);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_AppSpawnHookExecute_001, TestSize.Level1)
{
int ret = AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, nullptr, nullptr);
EXPECT_NE(0, ret);
}
/**
* @brief AddPreloadHook
*
*/
static int TestAppPreload(AppSpawnMgr *content)
{
return 0;
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Add_Preload_Hook_001, TestSize.Level0)
{
int ret = AddPreloadHook(HOOK_PRIO_HIGHEST, TestAppPreload);
EXPECT_EQ(0, ret);
ret = AddPreloadHook(-1, TestAppPreload);
EXPECT_EQ(0, ret);
ret = AddPreloadHook(1001, TestAppPreload);
EXPECT_EQ(0, ret);
ret = AddPreloadHook(8000, TestAppPreload); // 8000 正常
EXPECT_EQ(0, ret);
ret = AddPreloadHook(8000, nullptr); // 影响功能测试
EXPECT_NE(0, ret);
}
/**
* @brief AddAppSpawnHook
*
*/
static int TestAppSpawn(AppSpawnMgr *content, AppSpawningCtx *property)
{
return 0;
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Add_App_Spawn_Hook_001, TestSize.Level0)
{
int ret = AddAppSpawnHook(STAGE_CHILD_POST_RELY, HOOK_PRIO_HIGHEST, TestAppSpawn);
EXPECT_EQ(0, ret);
ret = AddAppSpawnHook(static_cast<AppSpawnHookStage>(-1), HOOK_PRIO_HIGHEST, TestAppSpawn);
EXPECT_NE(0, ret);
ret = AddAppSpawnHook(static_cast<AppSpawnHookStage>(1), HOOK_PRIO_HIGHEST, TestAppSpawn);
EXPECT_NE(0, ret);
ret = AddAppSpawnHook(static_cast<AppSpawnHookStage>(11), HOOK_PRIO_HIGHEST, TestAppSpawn);
EXPECT_NE(0, ret);
ret = AddAppSpawnHook(static_cast<AppSpawnHookStage>(53), HOOK_PRIO_HIGHEST, TestAppSpawn);
EXPECT_NE(0, ret);
ret = AddAppSpawnHook(STAGE_CHILD_POST_RELY, -1, TestAppSpawn);
EXPECT_EQ(0, ret);
ret = AddAppSpawnHook(STAGE_CHILD_POST_RELY, 1001, TestAppSpawn);
EXPECT_EQ(0, ret);
ret = AddAppSpawnHook(STAGE_CHILD_POST_RELY, 8000, TestAppSpawn); // 8000 正常
EXPECT_EQ(0, ret);
ret = AddAppSpawnHook(STAGE_CHILD_POST_RELY, 8000, nullptr); // 影响功能测试
EXPECT_NE(0, ret);
}
/**
* @brief AddProcessMgrHook
*
*/
static int ReportProcessExitInfo(const AppSpawnMgr *content, const AppSpawnedProcess *appInfo)
{
return 0;
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Add_App_Change_Hook_001, TestSize.Level0)
{
int ret = AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, ReportProcessExitInfo);
EXPECT_EQ(0, ret);
ret = AddProcessMgrHook(static_cast<AppSpawnHookStage>(-1), 0, ReportProcessExitInfo);
EXPECT_NE(0, ret);
ret = AddProcessMgrHook(static_cast<AppSpawnHookStage>(1), 0, ReportProcessExitInfo);
EXPECT_NE(0, ret);
ret = AddProcessMgrHook(static_cast<AppSpawnHookStage>(11), 0, ReportProcessExitInfo);
EXPECT_NE(0, ret);
ret = AddProcessMgrHook(static_cast<AppSpawnHookStage>(53), 0, ReportProcessExitInfo);
EXPECT_NE(0, ret);
ret = AddProcessMgrHook(STAGE_SERVER_APP_DIED, -1, ReportProcessExitInfo);
EXPECT_EQ(0, ret);
ret = AddProcessMgrHook(STAGE_SERVER_APP_DIED, 1001, ReportProcessExitInfo);
EXPECT_EQ(0, ret);
ret = AddProcessMgrHook(STAGE_SERVER_APP_DIED, 8000, ReportProcessExitInfo); // 8000 正常
EXPECT_EQ(0, ret);
ret = AddProcessMgrHook(STAGE_SERVER_APP_ADD, 0, nullptr); // 影响功能测试
EXPECT_NE(0, ret);
}
/**
* @brief RegChildLooper
*
*/
static int TestChildLoop(AppSpawnContent *content, AppSpawnClient *client)
{
return 0;
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Add_App_RegChildLooper_001, TestSize.Level0)
{
RegChildLooper(nullptr, TestChildLoop);
AppSpawnContent content;
content.longProcName = nullptr;
content.longProcNameLen = 256;
content.coldStartApp = nullptr;
content.runAppSpawn = nullptr;
RegChildLooper(&content, nullptr);
RegChildLooper(&content, TestChildLoop);
}
/**
* @brief MakeDirRec
* int MakeDirRec(const char *path, mode_t mode, int lastPath);
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Add_App_MakeDirRec_001, TestSize.Level0)
{
int ret = MakeDirRec(nullptr, 0, -1);
EXPECT_EQ(ret, -1);
ret = MakeDirRec("/data/appspawn/", 0, -1);
EXPECT_NE(ret, -1);
}
/**
* @brief SandboxMountPath
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Add_App_SandboxMountPath_001, TestSize.Level0)
{
MountArg arg = {};
arg.originPath = "/data/";
arg.destinationPath = "/data/appspawn/test";
arg.mountSharedFlag = 1;
int ret = SandboxMountPath(&arg);
EXPECT_EQ(ret, 0);
ret = SandboxMountPath(&arg);
EXPECT_EQ(ret, 0);
ret = SandboxMountPath(nullptr);
EXPECT_NE(ret, 0);
arg.mountSharedFlag = -1;
ret = SandboxMountPath(&arg);
EXPECT_EQ(ret, 0);
}
/**
* @brief AddVariableReplaceHandler
*
*/
static int TestReplaceVarHandler(const SandboxContext *context, const char *buffer, uint32_t bufferLen,
uint32_t *realLen, const VarExtraData *extraData)
{
return 0;
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_AddVariableReplaceHandler_001, TestSize.Level0)
{
int ret = AddVariableReplaceHandler(nullptr, nullptr);
EXPECT_EQ(ret, APPSPAWN_ARG_INVALID);
ret = AddVariableReplaceHandler("xxx", nullptr);
EXPECT_EQ(ret, APPSPAWN_ARG_INVALID);
ret = AddVariableReplaceHandler(nullptr, TestReplaceVarHandler);
EXPECT_EQ(ret, APPSPAWN_ARG_INVALID);
ret = AddVariableReplaceHandler("global", TestReplaceVarHandler);
EXPECT_EQ(ret, 0);
ret = AddVariableReplaceHandler("<Test-Var-001>", TestReplaceVarHandler);
EXPECT_EQ(ret, 0);
}
/**
* @brief RegisterExpandSandboxCfgHandler
*
*/
static int TestProcessExpandSandboxCfg(const SandboxContext *context, const AppSpawnSandboxCfg *appSandBox,
const char *name)
{
return 0;
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_RegisterExpandSandboxCfgHandler_001, TestSize.Level0)
{
int ret = RegisterExpandSandboxCfgHandler(nullptr, 0, nullptr);
EXPECT_EQ(ret, APPSPAWN_ARG_INVALID);
ret = RegisterExpandSandboxCfgHandler("test", 0, nullptr);
EXPECT_EQ(ret, APPSPAWN_ARG_INVALID);
ret = RegisterExpandSandboxCfgHandler(nullptr, 0, TestProcessExpandSandboxCfg);
EXPECT_EQ(ret, APPSPAWN_ARG_INVALID);
#ifdef APPSPAWN_SANDBOX_NEW
ret = RegisterExpandSandboxCfgHandler("HspList", 0, TestProcessExpandSandboxCfg);
EXPECT_EQ(ret, APPSPAWN_NODE_EXIST);
#else
ret = RegisterExpandSandboxCfgHandler("HspList", 0, TestProcessExpandSandboxCfg);
EXPECT_EQ(ret, 0);
#endif
ret = RegisterExpandSandboxCfgHandler("HspList", -1, TestProcessExpandSandboxCfg);
EXPECT_EQ(ret, APPSPAWN_NODE_EXIST);
}
/**
* @brief AddSandboxPermissionNode
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_AddSandboxPermissionNode_001, TestSize.Level1)
{
int ret = AddSandboxPermissionNode(nullptr, nullptr);
EXPECT_NE(0, ret);
ret = AddSandboxPermissionNode("xxx", nullptr);
EXPECT_NE(0, ret);
SandboxQueue queue;
OH_ListInit(&queue.front);
EXPECT_NE(nullptr, &queue.front);
ret = AddSandboxPermissionNode(nullptr, &queue);
EXPECT_NE(0, ret);
ret = AddSandboxPermissionNode("xxx", &queue);
EXPECT_EQ(0, ret);
}
/**
* @brief GetPermissionIndexInQueue
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetPermissionIndexInQueue_001, TestSize.Level1)
{
int ret = GetPermissionIndexInQueue(nullptr, nullptr);
EXPECT_NE(0, ret);
ret = GetPermissionIndexInQueue(nullptr, "xxx");
EXPECT_NE(0, ret);
SandboxQueue queue;
OH_ListInit(&queue.front);
ret = GetPermissionIndexInQueue(&queue, nullptr);
EXPECT_NE(0, ret);
ret = AddSandboxPermissionNode("test", &queue);
EXPECT_EQ(0, ret);
ret = GetPermissionIndexInQueue(&queue, "test1");
EXPECT_NE(0, ret);
ret = GetPermissionIndexInQueue(&queue, "xxx");
EXPECT_NE(0, ret);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetPermissionNodeInQueue_001, TestSize.Level1)
{
EXPECT_EQ(nullptr, GetPermissionNodeInQueue(nullptr, nullptr));
EXPECT_EQ(nullptr, GetPermissionNodeInQueue(nullptr, "xxx"));
SandboxQueue queue;
OH_ListInit(&queue.front);
EXPECT_EQ(nullptr, GetPermissionNodeInQueue(&queue, nullptr));
EXPECT_EQ(nullptr, GetPermissionNodeInQueue(&queue, "xxxxx"));
EXPECT_EQ(nullptr, GetPermissionNodeInQueue(&queue, "xxx"));
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetPermissionNodeInQueueByIndex_001, TestSize.Level1)
{
const SandboxPermissionNode *node = GetPermissionNodeInQueueByIndex(nullptr, 0);
EXPECT_EQ(nullptr, node);
node = GetPermissionNodeInQueueByIndex(nullptr, 0);
EXPECT_EQ(nullptr, node);
SandboxQueue queue;
OH_ListInit(&queue.front);
int ret = AddSandboxPermissionNode("xxx", &queue);
EXPECT_EQ(0, ret);
node = GetPermissionNodeInQueueByIndex(&queue, 0);
EXPECT_NE(nullptr, node);
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_PermissionRenumber_001, TestSize.Level1)
{
int ret = PermissionRenumber(nullptr);
EXPECT_NE(0, ret);
SandboxQueue queue;
OH_ListInit(&queue.front);
ret = PermissionRenumber(&queue);
EXPECT_EQ(0, ret);
}
/**
* @brief AppSpawnSandboxCfg op
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetAppSpawnSandbox_001, TestSize.Level1)
{
AppSpawnSandboxCfg *cfg = CreateAppSpawnSandbox();
EXPECT_NE(nullptr, cfg);
AppSpawnSandboxCfg *sandboxCfg = GetAppSpawnSandbox(nullptr);
EXPECT_EQ(nullptr, sandboxCfg);
AppSpawnMgr content;
OH_ListInit(&content.extData);
sandboxCfg = GetAppSpawnSandbox(&content);
EXPECT_NE(nullptr, cfg);
int ret = LoadAppSandboxConfig(nullptr, 0);
EXPECT_EQ(APPSPAWN_ARG_INVALID, ret);
DumpAppSpawnSandboxCfg(nullptr);
DumpAppSpawnSandboxCfg(cfg);
DeleteAppSpawnSandbox(cfg);
DeleteAppSpawnSandbox(nullptr);
}
/**
* @brief SandboxSection op
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_CreateSandboxSection_001, TestSize.Level1)
{
EXPECT_EQ(nullptr, CreateSandboxSection(nullptr, 0, 0));
EXPECT_EQ(nullptr, CreateSandboxSection("xxx", 99999, 0));
EXPECT_EQ(nullptr, CreateSandboxSection("xxx", 0, 0));
EXPECT_EQ(nullptr, CreateSandboxSection("xxx", 111, 0));
SandboxQueue queue;
OH_ListInit(&queue.front);
EXPECT_EQ(nullptr, GetSandboxSection(nullptr, nullptr));
EXPECT_EQ(nullptr, GetSandboxSection(nullptr, "xxx"));
EXPECT_EQ(nullptr, GetSandboxSection(&queue, nullptr));
EXPECT_EQ(nullptr, GetSandboxSection(&queue, ""));
EXPECT_EQ(nullptr, GetSandboxSection(&queue, "xxx"));
SandboxSection node;
OH_ListInit(&node.front);
OH_ListInit(&node.sandboxNode.node);
SandboxMountNode *mountNode = (SandboxMountNode *)malloc(sizeof(SandboxMountNode));
OH_ListInit(&mountNode->node);
node.nameGroups = &mountNode;
AddSandboxSection(nullptr, nullptr);
AddSandboxSection(nullptr, &queue);
AddSandboxSection(&node, nullptr);
AddSandboxSection(&node, &queue);
EXPECT_EQ(SANDBOX_TAG_INVALID, GetSectionType(nullptr));
EXPECT_NE(SANDBOX_TAG_INVALID, GetSectionType(&node));
DeleteSandboxSection(nullptr);
}
/**
* @brief SandboxMountNode op
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_CreateAppSpawnSandbox_001, TestSize.Level1)
{
EXPECT_EQ(nullptr, CreateSandboxMountNode(0, 0));
EXPECT_EQ(nullptr, CreateSandboxMountNode(sizeof(SandboxMountNode) - 1, 0));
EXPECT_EQ(nullptr, CreateSandboxMountNode(sizeof(PathMountNode) + 1, 0));
SandboxMountNode *node = CreateSandboxMountNode(sizeof(PathMountNode), 0);
EXPECT_NE(nullptr, node);
OH_ListInit(&node->node);
SandboxSection *section = CreateSandboxSection("xxx", sizeof(SandboxSection), 0);
OH_ListInit(&section->front);
ListNode item;
OH_ListInit(&item);
OH_ListAddTail(&section->front, &item);
EXPECT_EQ(nullptr, GetFirstSandboxMountNode(nullptr));
EXPECT_NE(nullptr, GetFirstSandboxMountNode(section));
SandboxSection section1;
OH_ListInit(&section1.front);
EXPECT_EQ(nullptr, GetFirstSandboxMountNode(&section1));
OH_ListInit(&section->front);
OH_ListInit(&section->sandboxNode.node);
AddSandboxMountNode(node, section);
AddSandboxMountNode(nullptr, nullptr);
AddSandboxMountNode(node, nullptr);
AddSandboxMountNode(nullptr, section);
DeleteSandboxMountNode(nullptr);
DeleteSandboxMountNode(node);
SandboxMountNode *node1 = CreateSandboxMountNode(sizeof(PathMountNode), 0);
EXPECT_NE(nullptr, node1);
OH_ListInit(&node1->node);
node1->type = SANDBOX_TAG_INVALID;
DeleteSandboxMountNode(node1);
}
/**
* @brief sandbox mount interface
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_MountSandboxConfigs_001, TestSize.Level1)
{
AppSpawnSandboxCfg *sandbox = CreateAppSpawnSandbox();
AppSpawnClientHandle clientHandle;
int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
EXPECT_EQ(0, ret);
AppSpawnReqMsgHandle reqHandle;
ret = AppSpawnReqMsgCreate(MSG_APP_SPAWN, "com.ohos.myapplication", &reqHandle);
AppSpawningCtx property;
OH_ListInit(&property.node);
EXPECT_NE(0, MountSandboxConfigs(nullptr, nullptr, 0));
EXPECT_NE(0, MountSandboxConfigs(sandbox, nullptr, 0));
EXPECT_NE(0, StagedMountSystemConst(nullptr, nullptr, 0));
EXPECT_NE(0, StagedMountSystemConst(sandbox, nullptr, 0));
SandboxContext content;
EXPECT_EQ(0, StagedMountPreUnShare(&content, sandbox));
EXPECT_NE(0, StagedMountPreUnShare(nullptr, nullptr));
EXPECT_NE(0, StagedMountPreUnShare(&content, nullptr));
EXPECT_NE(0, StagedMountPreUnShare(nullptr, sandbox));
EXPECT_NE(0, UnmountSandboxConfigs(sandbox, 0, nullptr));
EXPECT_NE(0, UnmountSandboxConfigs(nullptr, 0, nullptr));
}
/**
* @brief Variable op
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_GetSandboxRealVar_001, TestSize.Level1)
{
AddDefaultVariable();
const char *var = GetSandboxRealVar(nullptr, 0, "", "", nullptr);
EXPECT_EQ(nullptr, var);
SandboxContext content;
var = GetSandboxRealVar(&content, 4, "", "", nullptr);
EXPECT_EQ(nullptr, var);
ClearVariable();
}
/**
* @brief expand config
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_expand_config_001, TestSize.Level1)
{
SandboxContext content;
AppSpawnSandboxCfg *cfg = CreateAppSpawnSandbox();
EXPECT_EQ(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(nullptr, nullptr, nullptr));
EXPECT_EQ(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(nullptr, cfg, nullptr));
EXPECT_EQ(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(nullptr, cfg, "name"));
EXPECT_EQ(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(&content, nullptr, nullptr));
EXPECT_EQ(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(&content, cfg, nullptr));
EXPECT_NE(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(&content, cfg, "test"));
EXPECT_EQ(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(&content, cfg, nullptr));
EXPECT_NE(APPSPAWN_ARG_INVALID, ProcessExpandAppSandboxConfig(&content, cfg, "test"));
AddDefaultExpandAppSandboxConfigHandle();
ClearExpandAppSandboxConfigHandle();
}
/**
* @brief Sandbox Context op
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Sandbox_Content_Op_001, TestSize.Level1)
{
SandboxContext *sandboxContent = GetSandboxContext();
EXPECT_NE(nullptr, sandboxContent);
DeleteSandboxContext(nullptr);
DeleteSandboxContext(sandboxContent);
}
/**
* @brief Sandbox Context op
*
*/
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Sandbox_Op_001, TestSize.Level1)
{
EXPECT_EQ(MOUNT_TMP_DEFAULT, GetMountCategory(""));
EXPECT_EQ(MOUNT_TMP_DEFAULT, GetMountCategory(nullptr));
EXPECT_EQ(MOUNT_TMP_DEFAULT, GetMountCategory("name"));
}
HWTEST(AppSpawnModuleInterfaceTest, App_Spawn_Sandbox_Op_002, TestSize.Level1)
{
PathMountNode pathNode;
pathNode.category = 123456;
DumpMountPathMountNode(&pathNode);
EXPECT_EQ(0, GetPathMode("test"));
EXPECT_EQ(0, GetPathMode(nullptr));
EXPECT_EQ(nullptr, GetSandboxFlagInfo(nullptr, nullptr, 0));
EXPECT_EQ(nullptr, GetSandboxFlagInfo("key", nullptr, 0));
EXPECT_EQ(nullptr, GetMountArgTemplate(123456));
}
} // namespace OHOS

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,9 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "appspawn_manager.h"
#include "appspawn_modulemgr.h"
#include "appspawn_server.h"
#include "appspawn_manager.h"
#include "json_utils.h"
#include "parameter.h"
#include "securec.h"
@ -38,7 +38,7 @@ using namespace testing::ext;
using namespace OHOS;
namespace OHOS {
static AppSpawnTestHelper g_testHelper;
static OHOS::AppSpawnTestServer *g_testServer = nullptr;
class AppSpawnServiceTest : public testing::Test {
public:
static void SetUpTestCase() {}
@ -53,15 +53,19 @@ public:
*/
HWTEST(AppSpawnServiceTest, App_Spawn_001, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
g_testServer = new OHOS::AppSpawnTestServer("appspawn -mode appspawn");
ASSERT_EQ(g_testServer != nullptr, 1);
g_testServer->Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
APPSPAWN_LOGV("App_Spawn_001 start");
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NO_SANDBOX);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
@ -69,13 +73,14 @@ HWTEST(AppSpawnServiceTest, App_Spawn_001, TestSize.Level0)
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("App_Spawn_001 recv result %{public}d %{public}d", result.result, result.pid);
APPSPAWN_CHECK(ret == 0, break, "Failed to send msg %{public}d", ret);
if (ret == 0 && result.pid > 0) {
APPSPAWN_LOGI("App_Spawn_Msg_001 Kill pid %{public}d ", result.pid);
kill(result.pid, SIGKILL);
}
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
@ -86,23 +91,21 @@ HWTEST(AppSpawnServiceTest, App_Spawn_001, TestSize.Level0)
*/
HWTEST(AppSpawnServiceTest, App_Spawn_002, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
APPSPAWN_LOGV("App_Spawn_002 start");
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("App_Spawn_002 recv result %{public}d", ret);
APPSPAWN_LOGV("App_Spawn_002 recv result %{public}d %{public}d", result.result, result.pid);
if (ret != 0 || result.pid == 0) {
ret = -1;
break;
}
// stop child and termination
APPSPAWN_LOGI("App_Spawn_002 Kill pid %{public}d ", result.pid);
kill(result.pid, SIGKILL);
// MSG_GET_RENDER_TERMINATION_STATUS
ret = AppSpawnTerminateMsgCreate(result.pid, &reqHandle);
@ -110,7 +113,7 @@ HWTEST(AppSpawnServiceTest, App_Spawn_002, TestSize.Level0)
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("Send MSG_GET_RENDER_TERMINATION_STATUS %{public}d", ret);
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
@ -121,17 +124,15 @@ HWTEST(AppSpawnServiceTest, App_Spawn_002, TestSize.Level0)
*/
HWTEST(AppSpawnServiceTest, App_Spawn_003, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("App_Spawn_003 recv result %{public}d", ret);
APPSPAWN_LOGV("App_Spawn_003 recv result %{public}d %{public}d", result.result, result.pid);
if (ret != 0 || result.pid == 0) {
ret = -1;
break;
@ -142,7 +143,7 @@ HWTEST(AppSpawnServiceTest, App_Spawn_003, TestSize.Level0)
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("Send MSG_GET_RENDER_TERMINATION_STATUS %{public}d", ret);
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
@ -153,19 +154,17 @@ HWTEST(AppSpawnServiceTest, App_Spawn_003, TestSize.Level0)
*/
HWTEST(AppSpawnServiceTest, App_Spawn_004, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_DUMP, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_DUMP, 0);
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_CHECK(ret == 0, break, "Failed to send msg %{public}d", ret);
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
@ -176,14 +175,12 @@ HWTEST(AppSpawnServiceTest, App_Spawn_004, TestSize.Level0)
*/
HWTEST(AppSpawnServiceTest, App_Spawn_005, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
@ -198,29 +195,27 @@ HWTEST(AppSpawnServiceTest, App_Spawn_005, TestSize.Level0)
kill(result.pid, SIGKILL);
}
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_002, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_001, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int ret = -1;
int socketId = -1;
// 没有tlv的消息返回错误
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
std::vector<uint8_t> buffer(sizeof(AppSpawnResponseMsg));
uint32_t msgLen = 0;
ret = testServer.CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
int len = write(socketId, buffer.data(), msgLen);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// recv
APPSPAWN_LOGV("Start recv ... ");
len = read(socketId, buffer.data(), buffer.size());
@ -233,7 +228,6 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_002, TestSize.Level0)
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_NE(ret, 0);
}
@ -243,24 +237,22 @@ static int RecvMsg(int socketId, uint8_t *buffer, uint32_t buffSize)
return static_cast<int>(rLen);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_003, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_002, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int ret = -1;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
// 消息不完整,断开连接
std::vector<uint8_t> buffer(sizeof(AppSpawnResponseMsg));
uint32_t msgLen = 0;
ret = testServer.CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
int len = write(socketId, buffer.data(), msgLen - 10); // 10
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// recv timeout
len = RecvMsg(socketId, buffer.data(), buffer.size());
APPSPAWN_CHECK(len == 0, ret = -1;
@ -269,28 +261,25 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_003, TestSize.Level0)
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_EQ(ret, 0);
ASSERT_NE(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_004, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_003, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int ret = -1;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
// 测试异常tlv
std::vector<uint8_t> buffer(sizeof(AppSpawnResponseMsg));
uint32_t msgLen = 0;
ret = testServer.CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
int len = write(socketId, buffer.data(), msgLen);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// recv
len = RecvMsg(socketId, buffer.data(), buffer.size());
APPSPAWN_CHECK(len >= static_cast<int>(sizeof(AppSpawnResponseMsg)), ret = -1;
@ -302,7 +291,6 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_004, TestSize.Level0)
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_NE(ret, 0);
}
@ -310,21 +298,19 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_004, TestSize.Level0)
* @brief 2033
*
*/
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_005, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_004, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int ret = -1;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
// 测试小包发送
std::vector<uint8_t> buffer(1024, 0); // 1024 1k
uint32_t msgLen = 0;
ret = testServer.CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// 分片发送
uint32_t sendStep = OHOS::AppSpawnTestHelper::GenRandom() % 70; // 70 一次发送的字节数
@ -337,14 +323,14 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_005, TestSize.Level0)
break;
}
len = write(socketId, buffer.data() + currIndex, sendStep);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send %{public}s", g_testServer->GetDefaultTestAppBundleName());
usleep(2000); // wait recv
currIndex += sendStep;
} while (1);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send %{public}s", g_testServer->GetDefaultTestAppBundleName());
if (msgLen > currIndex) {
len = write(socketId, buffer.data() + currIndex, msgLen - currIndex);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send %{public}s", g_testServer->GetDefaultTestAppBundleName());
}
// recv
@ -352,13 +338,13 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_005, TestSize.Level0)
APPSPAWN_CHECK(len >= static_cast<int>(sizeof(AppSpawnResponseMsg)), ret = -1;
break, "Failed to recv msg %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnResponseMsg *respMsg = reinterpret_cast<AppSpawnResponseMsg *>(buffer.data());
APPSPAWN_LOGV("Recv msg %{public}s result: %{public}d", respMsg->msgHdr.processName, respMsg->result.result);
APPSPAWN_LOGV("App_Spawn_Msg_005 recv msg %{public}s result: %{public}d",
respMsg->msgHdr.processName, respMsg->result.result);
ret = respMsg->result.result;
} while (0);
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_EQ(ret, 0);
}
@ -366,41 +352,39 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_005, TestSize.Level0)
* @brief 2
*
*/
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_006, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_005, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int ret = -1;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
std::vector<uint8_t> buffer1(1024); // 1024
std::vector<uint8_t> buffer2(1024); // 1024
uint32_t msgLen1 = 0;
uint32_t msgLen2 = 0;
ret = testServer.CreateSendMsg(buffer1, MSG_APP_SPAWN, msgLen1, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = testServer.CreateSendMsg(buffer2, MSG_APP_SPAWN, msgLen2, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer1, MSG_APP_SPAWN, msgLen1, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer2, MSG_APP_SPAWN, msgLen2, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
buffer1.insert(buffer1.begin() + msgLen1, buffer2.begin(), buffer2.end());
int len = write(socketId, buffer1.data(), msgLen1 + msgLen2);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// recv
len = RecvMsg(socketId, buffer2.data(), buffer2.size());
APPSPAWN_CHECK(len >= static_cast<int>(sizeof(AppSpawnResponseMsg)), ret = -1;
break, "Failed to recv msg %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnResponseMsg *respMsg = reinterpret_cast<AppSpawnResponseMsg *>(buffer2.data());
APPSPAWN_LOGV("Recv msg %{public}s result: %{public}d", respMsg->msgHdr.processName, respMsg->result.result);
APPSPAWN_LOGV("App_Spawn_Msg_006 Recv msg %{public}s result: %{public}d",
respMsg->msgHdr.processName, respMsg->result.result);
ret = respMsg->result.result;
(void)RecvMsg(socketId, buffer2.data(), buffer2.size());
} while (0);
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_EQ(ret, 0);
}
@ -408,28 +392,26 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_006, TestSize.Level0)
* @brief 2spawn和dump
*
*/
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_007, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_006, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr, 5000); // 5000 5s
int ret = 0;
int ret = -1;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
std::vector<uint8_t> buffer1(1024); // 1024
std::vector<uint8_t> buffer2(1024); // 1024
uint32_t msgLen1 = 0;
uint32_t msgLen2 = 0;
ret = testServer.CreateSendMsg(buffer1, MSG_APP_SPAWN, msgLen1, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = testServer.CreateSendMsg(buffer2, MSG_DUMP, msgLen2, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer1, MSG_APP_SPAWN, msgLen1, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer2, MSG_DUMP, msgLen2, {});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
buffer1.insert(buffer1.begin() + msgLen1, buffer2.begin(), buffer2.end());
int len = write(socketId, buffer1.data(), msgLen1 + msgLen2);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// recv
len = RecvMsg(socketId, buffer2.data(), buffer2.size());
APPSPAWN_CHECK(len >= static_cast<int>(sizeof(AppSpawnResponseMsg)), ret = -1;
@ -443,7 +425,6 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_007, TestSize.Level0)
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_EQ(ret, 0);
}
@ -451,22 +432,20 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_007, TestSize.Level0)
* @brief
*
*/
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_008, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_007, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int ret = -1;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
std::vector<uint8_t> buffer(1024, 0); // 1024 1k
uint32_t msgLen = 0;
ret = testServer.CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
int len = write(socketId, buffer.data(), msgLen);
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
// close socket
APPSPAWN_LOGV("CloseClientSocket");
CloseClientSocket(socketId);
@ -476,7 +455,7 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_008, TestSize.Level0)
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_EQ(ret, 0);
}
@ -484,21 +463,19 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_008, TestSize.Level0)
* @brief
*
*/
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_009, TestSize.Level0)
HWTEST(AppSpawnServiceTest, App_Spawn_Msg_008, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
int socketId = -1;
do {
socketId = testServer.CreateSocket();
socketId = g_testServer->CreateSocket();
APPSPAWN_CHECK(socketId >= 0, break, "Failed to create socket %{public}s", APPSPAWN_SERVER_NAME);
std::vector<uint8_t> buffer(1024, 0); // 1024 1k
uint32_t msgLen = 0;
ret = testServer.CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", testServer.GetDefaultTestAppBundleName());
ret = g_testServer->CreateSendMsg(buffer, MSG_APP_SPAWN, msgLen, {AppSpawnTestHelper::AddBaseTlv});
APPSPAWN_CHECK(ret == 0, break, "Failed to create msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
int len = write(socketId, buffer.data(), msgLen - 20); // 20 test
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", testServer.GetDefaultTestAppBundleName());
APPSPAWN_CHECK(len > 0, break, "Failed to send msg %{public}s", g_testServer->GetDefaultTestAppBundleName());
usleep(500000); // 500000 need to wait server timeout
// recv
len = read(socketId, buffer.data(), buffer.size()); // timeout EAGAIN
@ -507,253 +484,7 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Msg_009, TestSize.Level0)
if (socketId >= 0) {
CloseClientSocket(socketId);
}
testServer.Stop();
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Child_001, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
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, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content); // 预加载解析sandbox
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Child_002, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
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);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Child_003, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Child_004, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and no render cmd
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Child_005, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and render
g_testHelper.SetTestUid(10010029); // 10010029
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);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
ASSERT_EQ(ret, 0);
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(AppSpawnServiceTest, App_Spawn_Child_006, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and no render cmd
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
const char *appEnv = "{\"test.name1\": \"test.value1\", \"test.name2\": \"test.value2\"}";
ret = AppSpawnReqMsgAddExtInfo(reqHandle, "AppEnv",
reinterpret_cast<uint8_t *>(const_cast<char *>(appEnv)), strlen(appEnv) + 1);
APPSPAWN_CHECK(ret == 0, break, "Failed to add ext tlv %{public}s", appEnv);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
reqHandle = nullptr;
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
ASSERT_EQ(ret, 0);
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnReqMsgFree(reqHandle);
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
@ -763,25 +494,23 @@ HWTEST(AppSpawnServiceTest, App_Spawn_Child_006, TestSize.Level0)
*/
HWTEST(AppSpawnServiceTest, App_Spawn_NWebSpawn_001, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode appspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
usleep(2000);
ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_CHECK(ret == 0, break, "Failed to send msg %{public}d", ret);
// kill nwebspawn
APPSPAWN_LOGV("App_Spawn_NWebSpawn_001 Kill nwebspawn");
usleep(20000); // 20000 20ms
testServer.KillNWebSpawnServer();
usleep(20000); // 20000 20ms
g_testServer->KillNWebSpawnServer();
} while (0);
AppSpawnClientDestroy(clientHandle);
testServer.Stop();
ASSERT_EQ(ret, 0);
g_testServer->Stop();
delete g_testServer;
}
} // namespace OHOS

View File

@ -24,9 +24,9 @@
#include <sys/types.h>
#include "appspawn_client.h"
#include "appspawn_manager.h"
#include "appspawn_modulemgr.h"
#include "appspawn_server.h"
#include "appspawn_manager.h"
#include "json_utils.h"
#include "parameter.h"
#include "securec.h"
@ -39,7 +39,7 @@ using namespace testing::ext;
using namespace OHOS;
namespace OHOS {
static AppSpawnTestHelper g_testHelper;
static OHOS::AppSpawnTestServer *g_testServer = nullptr;
using AddTlvFunction = std::function<int(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount)>;
class NWebSpawnServiceTest : public testing::Test {
public:
@ -55,14 +55,17 @@ public:
*/
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_001, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode nwebspawn");
testServer.Start(nullptr);
g_testServer = new OHOS::AppSpawnTestServer("appspawn -mode nwebspawn");
ASSERT_EQ(g_testServer != nullptr, 1);
g_testServer->Start(nullptr);
usleep(2000); // 2000
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", NWEBSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("NWeb_Spawn_001 recv result %{public}d", ret);
@ -83,22 +86,20 @@ HWTEST(NWebSpawnServiceTest, NWeb_Spawn_001, TestSize.Level0)
APPSPAWN_LOGV("Send MSG_GET_RENDER_TERMINATION_STATUS %{public}d", ret);
ret = 0;
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_002, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode nwebspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
// 发送消息到nweb spawn
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", NWEBSPAWN_SERVER_NAME);
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_APP_SPAWN, 0);
AppSpawnResult result = {};
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("NWeb_Spawn_002 recv result %{public}d %{public}d", ret, result.pid);
@ -114,15 +115,13 @@ HWTEST(NWebSpawnServiceTest, NWeb_Spawn_002, TestSize.Level0)
APPSPAWN_LOGV("Send MSG_GET_RENDER_TERMINATION_STATUS %{public}d", ret);
ret = 0; // ut can not get result
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_004, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode nwebspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
@ -130,19 +129,17 @@ HWTEST(NWebSpawnServiceTest, NWeb_Spawn_004, TestSize.Level0)
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", NWEBSPAWN_SERVER_NAME);
// MSG_DUMP
AppSpawnResult result = {};
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MSG_DUMP, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MSG_DUMP, 0);
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("Send MSG_DUMP %{public}d", ret);
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_EQ(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_005, TestSize.Level0)
{
OHOS::AppSpawnTestServer testServer("appspawn -mode nwebspawn");
testServer.Start(nullptr);
int ret = 0;
AppSpawnClientHandle clientHandle = nullptr;
do {
@ -150,184 +147,14 @@ HWTEST(NWebSpawnServiceTest, NWeb_Spawn_005, TestSize.Level0)
APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", NWEBSPAWN_SERVER_NAME);
// MAX_TYPE_INVALID
AppSpawnResult result = {};
AppSpawnReqMsgHandle reqHandle = testServer.CreateMsg(clientHandle, MAX_TYPE_INVALID, 0);
AppSpawnReqMsgHandle reqHandle = g_testServer->CreateMsg(clientHandle, MAX_TYPE_INVALID, 0);
ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
APPSPAWN_LOGV("Send MAX_TYPE_INVALID %{public}d", ret);
} while (0);
testServer.Stop();
AppSpawnClientDestroy(clientHandle);
ASSERT_NE(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_Child_001, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req ");
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content); // 预加载解析sandbox
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_Child_002, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req");
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content); // 预加载解析sandbox
ret = APPSPAWN_ARG_INVALID;
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ASANENABLED);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_Child_004, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and no render cmd
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 1);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req");
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST(NWebSpawnServiceTest, NWeb_Spawn_Child_005, TestSize.Level0)
{
AppSpawnClientHandle clientHandle = nullptr;
AppSpawnReqMsgHandle reqHandle = 0;
AppSpawningCtx *property = nullptr;
AppSpawnContent *content = nullptr;
int ret = -1;
do {
ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle);
APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME);
// MSG_SPAWN_NATIVE_PROCESS and render
g_testHelper.SetTestUid(10010029); // 10010029
reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0);
APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, "Failed to create req");
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR);
AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_GWP_ENABLED_NORMAL);
char path[PATH_MAX] = {};
content = AppSpawnCreateContent(NWEBSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_NWEB_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ServerStageHookExecute(STAGE_SERVER_PRELOAD, content);
ret = APPSPAWN_ARG_INVALID;
property = g_testHelper.GetAppProperty(clientHandle, reqHandle);
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break);
// spawn prepare process
AppSpawnHookExecute(STAGE_PARENT_PRE_FORK, 0, content, &property->client);
// spawn
ret = AppSpawnChild(content, &property->client);
property = nullptr;
content = nullptr;
} while (0);
DeleteAppSpawningCtx(property);
AppSpawnClientDestroy(clientHandle);
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
g_testServer->Stop();
delete g_testServer;
}
} // namespace OHOS

View File

@ -1,256 +0,0 @@
/*
* Copyright (c) 2022 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.
*/
#include "app_spawn_stub.h"
#include <fcntl.h>
#include <pthread.h>
#include <cstdarg>
#include <cstdbool>
#include <cstdlib>
#include <cerrno>
#include <unistd.h>
#include <csignal>
#include <ctime>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/capability.h>
#include "appspawn_server.h"
#include "beget_ext.h"
#include "securec.h"
HapContextStub::HapContextStub() {}
HapContextStub::~HapContextStub() {}
static int g_testHapDomainSetcontext = 0;
int HapContextStub::HapDomainSetcontext(HapDomainInfo& hapDomainInfo)
{
if (g_testHapDomainSetcontext == 0) {
return 0;
} else if (g_testHapDomainSetcontext == 1) {
sleep(2); // 2 is sleep wait time
}
return g_testHapDomainSetcontext;
}
#ifdef __cplusplus
extern "C" {
#endif
void SetHapDomainSetcontextResult(int result)
{
g_testHapDomainSetcontext = result;
}
void *DlopenStub(const char *pathname, int mode)
{
UNUSED(pathname);
UNUSED(mode);
static size_t index = 0;
return &index;
}
bool InitEnvironmentParamStub(const char *name)
{
UNUSED(name);
return true;
}
void *DlsymStub(void *handle, const char *symbol)
{
UNUSED(handle);
if (strcmp(symbol, "InitEnvironmentParam") == 0) {
return reinterpret_cast<void *>(InitEnvironmentParamStub);
}
return nullptr;
}
int DlcloseStub(void *handle)
{
UNUSED(handle);
return 0;
}
pid_t WaitpidStub(pid_t *pid, int *status, int opt)
{
UNUSED(pid);
UNUSED(opt);
static int count = 0;
static int statusCount = 0;
*status = (statusCount % 2 == 0) ? 0x0e007f : 0; // 2 is to judge whether it is even
count++;
printf("waitpid stub %d\n", GetTestPid());
if ((count % 2) == 1) { // 2 is to judge whether it is odd
statusCount++;
return GetTestPid();
}
return -1;
}
void DisallowInternet(void)
{
}
int BindStub(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
UNUSED(sockfd);
UNUSED(addr);
UNUSED(addrlen);
return 0;
}
int ListenStub(int fd, int backlog)
{
UNUSED(fd);
UNUSED(backlog);
return 0;
}
int LchownStub(const char *pathname, uid_t owner, gid_t group)
{
UNUSED(pathname);
UNUSED(owner);
UNUSED(group);
return 0;
}
int LchmodStub(const char *pathname, mode_t mode)
{
UNUSED(pathname);
UNUSED(mode);
return 0;
}
int GetsockoptStub(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
{
UNUSED(sockfd);
UNUSED(level);
UNUSED(optlen);
if (optval == nullptr) {
return -1;
}
if (optname == SO_PEERCRED) {
struct ucred *cred = reinterpret_cast<struct ucred *>(optval);
cred->uid = 0;
}
return 0;
}
int SetgroupsStub(size_t size, const gid_t *list)
{
UNUSED(size);
UNUSED(list);
return 0;
}
int SetresuidStub(uid_t ruid, uid_t euid, uid_t suid)
{
UNUSED(ruid);
UNUSED(euid);
UNUSED(suid);
return 0;
}
int SetresgidStub(gid_t rgid, gid_t egid, gid_t sgid)
{
UNUSED(rgid);
UNUSED(egid);
UNUSED(sgid);
return 0;
}
int CapsetStub(cap_user_header_t hdrp, const cap_user_data_t datap)
{
UNUSED(hdrp);
UNUSED(datap);
return 0;
}
struct ForkArgs {
int (*childFunc)(void *arg);
void *args;
};
static void *ThreadFunc(void *arg)
{
struct ForkArgs *forkArg = reinterpret_cast<struct ForkArgs *>(arg);
forkArg->childFunc(forkArg->args);
free(forkArg);
return nullptr;
}
static pid_t g_pid = 1000;
pid_t AppSpawnFork(int (*childFunc)(void *arg), void *args)
{
static pthread_t thread = 0;
struct ForkArgs *forkArg = reinterpret_cast<struct ForkArgs *>(malloc(sizeof(struct ForkArgs)));
if (forkArg == nullptr) {
return -1;
}
forkArg->childFunc = childFunc;
forkArg->args = args;
int ret = pthread_create(&thread, nullptr, ThreadFunc, forkArg);
if (ret != 0) {
printf("Failed to create thread %d \n", errno);
return -1;
}
g_pid++;
return g_pid;
}
pid_t GetTestPid(void)
{
return g_pid;
}
int CloneStub(int (*fn)(void *), void *stack, int flags, void *arg, ...)
{
static int testResult = 0;
testResult++;
return testResult == 1 ? AppSpawnFork(fn, arg) : -1;
}
void StartupLog_stub(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...)
{
char tmpFmt[1024] = {0};
va_list vargs;
va_start(vargs, fmt);
if (vsnprintf_s(tmpFmt, sizeof(tmpFmt), sizeof(tmpFmt) - 1, fmt, vargs) == -1) {
tmpFmt[sizeof(tmpFmt) - 2] = '\n'; // 2 add \n to tail
tmpFmt[sizeof(tmpFmt) - 1] = '\0';
}
va_end(vargs);
struct timespec curr;
(void)clock_gettime(CLOCK_REALTIME, &curr);
struct tm t;
char dateTime[80] = {"00-00-00 00:00:00"}; // 80 data time
if (localtime_r(&curr.tv_sec, &t) != nullptr) {
strftime(dateTime, sizeof(dateTime), "%Y-%m-%d %H:%M:%S", &t);
}
(void)fprintf(stdout, "[%s.%ld][pid=%d %d][%s]%s \n", dateTime, curr.tv_nsec, getpid(), gettid(), tag, tmpFmt);
(void)fflush(stdout);
}
bool SetSeccompPolicyWithName(SeccompFilterType filter, const char *filterName)
{
static int result = 0;
result++;
return (result % 3) == 0; // 3 is test data
}
#ifdef __cplusplus
}
#endif

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 2022 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_TEST_STUB_H
#define APPSPAWN_TEST_STUB_H
#include <iostream>
struct HapDomainInfo {
std::string apl;
std::string packageName;
unsigned int hapFlags = 1;
};
class HapContextStub {
public:
HapContextStub();
~HapContextStub();
int HapDomainSetcontext(HapDomainInfo& hapDomainInfo);
};
enum SeccompFilterType: int {
SYSTEM_SA, // system service process
SYSTEM_OTHERS, // HDF process and daemon process
APP,
INDIVIDUAL // process which need enable individual policy
};
#ifdef __cplusplus
extern "C" {
#endif
pid_t GetTestPid(void);
void SetHapDomainSetcontextResult(int result);
#ifdef __cplusplus
}
#endif
#endif // APPSPAWN_TEST_STUB_H

View File

@ -15,12 +15,12 @@
#include "app_spawn_test_helper.h"
#include <csignal>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <pthread.h>
#include <csignal>
#include <string>
#include <sys/eventfd.h>
#include <sys/wait.h>
@ -46,7 +46,21 @@ typedef struct {
char bundleName[APP_LEN_BUNDLE_NAME]; // process name
} AppBundleInfo;
typedef struct {
uint32_t hapFlags;
char apl[APP_APL_MAX_LEN];
} AppDomainInfo;
const uint32_t AppSpawnTestServer::defaultProtectTime = 60000; // 60000 60s
uint32_t AppSpawnTestServer::serverId = 0;
static int TestChildLoopRun(AppSpawnContent *content, AppSpawnClient *client)
{
APPSPAWN_LOGV("ChildLoopRun ...");
sleep(1);
return 0;
}
AppSpawnTestServer::~AppSpawnTestServer()
{
if (localServer_) {
@ -106,6 +120,8 @@ void *AppSpawnTestServer::ServiceThread(void *arg)
APPSPAWN_LOGV("Save nwebspawn pid: %{public}d %{public}d", info->pid, server->serverId_);
server->appPid_.store(info->pid);
}
// register
RegChildLooper(&content->content, TestChildLoopRun);
}
server->content_->runAppSpawn(server->content_, args->argc, args->argv);
if (pid != getpid()) { // 子进程退出
@ -318,7 +334,7 @@ uint32_t AppSpawnTestHelper::GenRandom(void)
CmdArgs *AppSpawnTestHelper::ToCmdList(const char *cmd)
{
const uint32_t maxArgc = 10;
const uint32_t maxArgc = 20;
const uint32_t length = sizeof(CmdArgs) + maxArgc * sizeof(char *) + strlen(cmd) + APP_LEN_PROC_NAME + 1 + 2;
char *buffer = static_cast<char *>(malloc(length));
CmdArgs *args = reinterpret_cast<CmdArgs *>(buffer);
@ -384,6 +400,9 @@ AppSpawnReqMsgHandle AppSpawnTestHelper::CreateMsg(AppSpawnClientHandle handle,
ret = AppSpawnReqMsgSetAppAccessToken(reqHandle, 12345678); // 12345678
APPSPAWN_CHECK(ret == 0, break, "Failed to add access token %{public}s", processName_.c_str());
if (defaultMsgFlags_ != 0) {
(void)AppSpawnReqMsgSetFlags(reqHandle, TLV_MSG_FLAGS, defaultMsgFlags_);
}
if (base) {
return reqHandle;
}
@ -406,7 +425,7 @@ AppSpawnReqMsgHandle AppSpawnTestHelper::CreateMsg(AppSpawnClientHandle handle,
ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD,
reinterpret_cast<const uint8_t *>(renderCmd), strlen(renderCmd));
APPSPAWN_CHECK(ret == 0, break, "Failed to render cmd %{public}s", processName_.c_str());
ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, 1, "system_core");
ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, 1, defaultApl_.c_str());
APPSPAWN_CHECK(ret == 0, break, "Failed to domain info %{public}s", processName_.c_str());
return reqHandle;
} while (0);
@ -473,6 +492,7 @@ AppSpawningCtx *AppSpawnTestHelper::GetAppProperty(AppSpawnClientHandle handle,
APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, DeleteAppSpawnMsg(msgNode);
return nullptr);
property->message = msgNode;
SetDefaultTestData();
return property;
}
@ -483,6 +503,8 @@ void AppSpawnTestHelper::SetDefaultTestData()
defaultTestGid_ = 20010029; // 20010029 test
defaultTestGidGroup_ = 20010029; // 20010029 test
defaultTestBundleIndex_ = 100; // 100 test
defaultApl_ = std::string("system_core");
defaultMsgFlags_ = 0;
}
int AppSpawnTestHelper::CreateSocket(void)
@ -543,6 +565,17 @@ static int inline AddOneTlv(uint8_t *buffer, uint32_t bufferLen, const AppSpawnT
return 0;
}
#define ADD_TLV(type, value, currLen, tlvCount) \
do { \
AppSpawnTlv d_tlv = {}; \
d_tlv.tlvType = (type); \
d_tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(value); \
ret = AddOneTlv(buffer + (currLen), bufferLen - (currLen), d_tlv, (uint8_t *)&(value)); \
APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", d_tlv.tlvType); \
(currLen) += d_tlv.tlvLen; \
(tlvCount)++; \
} while (0)
int AppSpawnTestHelper::AddBaseTlv(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount)
{
// add app flage
@ -563,38 +596,29 @@ int AppSpawnTestHelper::AddBaseTlv(uint8_t *buffer, uint32_t bufferLen, uint32_t
currLen += tlv.tlvLen;
tlvCount++;
AppDomainInfo domainInfo = {0, "normal"};
ADD_TLV(TLV_DOMAIN_INFO, domainInfo, currLen, tlvCount);
AppSpawnMsgAccessToken token = {12345678}; // 12345678
tlv.tlvType = TLV_ACCESS_TOKEN_INFO;
tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(token);
ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)&token);
APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType);
currLen += tlv.tlvLen;
tlvCount++;
ADD_TLV(TLV_ACCESS_TOKEN_INFO, token, currLen, tlvCount);
AppSpawnMsgInternetInfo internetInfo = {0, 1};
ADD_TLV(TLV_INTERNET_INFO, internetInfo, currLen, tlvCount);
// add bundle info
AppBundleInfo info = {};
(void)strcpy_s(info.bundleName, sizeof(info.bundleName), "test-bundleName");
info.bundleIndex = 100; // 100 test index
tlv.tlvType = TLV_BUNDLE_INFO;
tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(AppBundleInfo);
ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)&info);
APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType);
currLen += tlv.tlvLen;
tlvCount++;
ADD_TLV(TLV_BUNDLE_INFO, info, currLen, tlvCount);
// add dac
AppDacInfo dacInfo = {};
dacInfo.uid = 20010029; // 20010029
dacInfo.gid = 20010029; // 20010029
dacInfo.gidCount = 2; // 2 count
dacInfo.gidTable[0] = 20010029; // 20010029
dacInfo.gidTable[1] = 20010029 + 1; // 20010029
tlv.tlvType = TLV_DAC_INFO;
tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(dacInfo);
ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)&dacInfo);
APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType);
currLen += tlv.tlvLen;
tlvCount++;
AppDacInfo dacInfo = {};
dacInfo.uid = 20010029; // 20010029 test uid
dacInfo.gid = 20010029; // 20010029 test gid
dacInfo.gidCount = 2; // 2 count
dacInfo.gidTable[0] = 20010029; // 20010029 test gid
dacInfo.gidTable[1] = 20010030; // 20010030 test gid
ADD_TLV(TLV_DAC_INFO, dacInfo, currLen, tlvCount);
realLen = currLen;
return 0;
}
@ -613,12 +637,12 @@ AppSpawnContent *AppSpawnTestHelper::StartSpawnServer(std::string &cmd, CmdArgs
if (args->argc <= MODE_VALUE_INDEX) { // appspawn start
startRrg.mode = MODE_FOR_APP_SPAWN;
} else if (strcmp(args->argv[MODE_VALUE_INDEX], "app_cold") == 0) { // cold start
APPSPAWN_CHECK(args->argc > PARAM_VALUE_INDEX, free(args);
APPSPAWN_CHECK(args->argc >= ARG_NULL, free(args);
return NULL, "Invalid arg for cold start %{public}d", args->argc);
startRrg.mode = MODE_FOR_APP_COLD_RUN;
startRrg.initArg = 0;
} else if (strcmp(args->argv[MODE_VALUE_INDEX], "nweb_cold") == 0) { // cold start
APPSPAWN_CHECK(args->argc > PARAM_VALUE_INDEX, free(args);
APPSPAWN_CHECK(args->argc >= ARG_NULL, free(args);
return NULL, "Invalid arg for cold start %{public}d", args->argc);
startRrg.mode = MODE_FOR_NWEB_COLD_RUN;
startRrg.serviceName = NWEBSPAWN_SERVER_NAME;
@ -638,22 +662,3 @@ AppSpawnContent *AppSpawnTestHelper::StartSpawnServer(std::string &cmd, CmdArgs
}
} // namespace OHOS
static int TestChildLoopRun(AppSpawnContent *content, AppSpawnClient *client)
{
APPSPAWN_LOGV("ChildLoopRun ...");
sleep(1);
return 0;
}
static int TestPreLoad(AppSpawnMgr *content)
{
// register
RegChildLooper(&content->content, TestChildLoopRun);
return 0;
}
MODULE_CONSTRUCTOR(void)
{
APPSPAWN_LOGV("Load test module ...");
AddPreloadHook(HOOK_PRIO_LOWEST, TestPreLoad);
}

View File

@ -29,6 +29,7 @@
#include <vector>
#include "appspawn.h"
#include "appspawn_client.h"
#include "appspawn_hook.h"
#include "appspawn_server.h"
#include "appspawn_service.h"
@ -80,10 +81,22 @@ public:
return defaultTestBundleIndex_;
}
void SetTestMsgFlags(uint32_t flags)
{
defaultMsgFlags_ = flags;
}
void SetTestApl(const char *apl)
{
defaultApl_ = std::string(apl);
}
void SetTestUid(uid_t uid)
{
defaultTestUid_ = uid;
}
void SetTestGid(gid_t gid)
{
defaultTestGid_ = gid;
}
void SetProcessName(const char *name)
{
processName_ = std::string(name);
@ -104,14 +117,28 @@ public:
static uint32_t GenRandom(void);
static CmdArgs *ToCmdList(const char *cmd);
static AppSpawnContent *StartSpawnServer(std::string &cmd, CmdArgs *&args);
int AppSpawnReqMsgSetFlags(AppSpawnReqMsgHandle reqHandle, uint32_t tlv, uint32_t flags)
{
AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
APPSPAWN_CHECK_ONLY_EXPER(reqNode != NULL, return APPSPAWN_ARG_INVALID);
if (tlv == TLV_MSG_FLAGS) {
*(uint32_t *)reqNode->msgFlags->flags = flags;
} else if (tlv == TLV_PERMISSION) {
*(uint32_t *)reqNode->permissionFlags->flags = flags;
}
return 0;
}
private:
AppSpawnMsgNode *CreateAppSpawnMsg(AppSpawnMsg *msg);
std::string processName_ = {};
std::string defaultApl_ = "system_core";
uid_t defaultTestUid_;
gid_t defaultTestGid_;
gid_t defaultTestGidGroup_;
int32_t defaultTestBundleIndex_;
uint32_t defaultMsgFlags_ = 0;
std::vector<const char *> permissions_ = {
const_cast<char *>("ohos.permission.READ_IMAGEVIDEO"),
const_cast<char *>("ohos.permission.FILE_CROSS_APP"),
@ -126,14 +153,14 @@ private:
class AppSpawnTestServer : public AppSpawnTestHelper {
public:
explicit AppSpawnTestServer(const char *cmd, bool testServer)
: AppSpawnTestHelper(), serviceCmd_(cmd), testServer_(testServer), protectTime_(2000) // 2000 2s
: AppSpawnTestHelper(), serviceCmd_(cmd), testServer_(testServer), protectTime_(defaultProtectTime)
{
serverId_ = AppSpawnTestServer::serverId;
AppSpawnTestServer::serverId++;
}
explicit AppSpawnTestServer(const char *cmd)
: AppSpawnTestHelper(), serviceCmd_(cmd), testServer_(true), protectTime_(2000) // 2000 2s
: AppSpawnTestHelper(), serviceCmd_(cmd), testServer_(true), protectTime_(defaultProtectTime)
{
serverId_ = AppSpawnTestServer::serverId;
AppSpawnTestServer::serverId++;
@ -141,10 +168,11 @@ public:
~AppSpawnTestServer();
void Start(void);
void Start(RecvMsgProcess process, uint32_t time = 2000); // 2000 default 2s
void Start(RecvMsgProcess process, uint32_t time = defaultProtectTime);
void Stop();
void KillNWebSpawnServer();
static const uint32_t defaultProtectTime;
private:
void CloseCheckHandler(void);
void StartCheckHandler(void);

29
util/BUILD.gn Executable file
View File

@ -0,0 +1,29 @@
# Copyright (c) 2021-2022 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.
import("//base/startup/appspawn/appspawn.gni")
import("//build/ohos.gni")
ohos_static_library("libappspawn_util") {
sources = [ "src/appspawn_utils.c" ]
external_deps = [
"cJSON:cjson",
"config_policy:configpolicy_util",
"hilog:libhilog",
"init:libbegetutil",
]
public_configs = [ "${appspawn_path}:appspawn_config" ]
subsystem_name = "${subsystem_name}"
part_name = "${part_name}"
}

View File

@ -28,7 +28,7 @@
#include <unistd.h>
#include <sys/types.h>
#include "appspawn_server.h"
#include "hilog/log.h"
#ifdef __cplusplus
extern "C" {
@ -45,8 +45,10 @@ extern "C" {
#endif
#if defined(__MUSL__)
#define APPSPAWN_SOCKET_DIR APPSPAWN_BASE_DIR "/dev/unix/socket/"
#define APPSPAWN_MSG_DIR APPSPAWN_BASE_DIR "/mnt/startup/"
#else
#define APPSPAWN_SOCKET_DIR APPSPAWN_BASE_DIR "/dev/socket/"
#define APPSPAWN_MSG_DIR APPSPAWN_BASE_DIR "/mnt/startup/"
#endif
#define APPSPAWN_CHECK_EXIT "AppSpawnCheckUnexpectedExitCall"
@ -67,8 +69,6 @@ extern "C" {
#define APPSPAWN_USEC_TO_NSEC 1000
#define APPSPAWN_SEC_TO_MSEC 1000
#define MAX_JSON_FILE_LEN 102400
#define CHECK_FLAGS_BY_INDEX(flags, index) ((((flags) >> (index)) & 0x1) == 0x1)
#ifndef ARRAY_LENGTH
#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0]))
@ -87,9 +87,9 @@ typedef enum {
APPSPAWN_SANDBOX_NONE,
APPSPAWN_SANDBOX_LOAD_FAIL,
APPSPAWN_SANDBOX_INVALID,
APPSPAWN_SANDBOX_MOUNT_FAIL,
APPSPAWN_SPAWN_TIMEOUT,
APPSPAWN_CHILD_CRASH,
APPSPAWN_SANDBOX_MOUNT_FAIL, // 0xD00000a
APPSPAWN_SPAWN_TIMEOUT, // 0xD00000a
APPSPAWN_CHILD_CRASH, // 0xD00000b
APPSPAWN_NATIVE_NOT_SUPPORT,
APPSPAWN_ACCESS_TOKEN_INVALID,
APPSPAWN_PERMISSION_NOT_SUPPORT,
@ -99,21 +99,79 @@ typedef enum {
APPSPAWN_NODE_EXIST,
} AppSpawnErrorCode;
typedef struct cJSON cJSON;
typedef struct TagParseJsonContext ParseJsonContext;
typedef int (*ParseConfig)(const cJSON *root, ParseJsonContext *context);
int ParseJsonConfig(const char *path, const char *fileName, ParseConfig parseConfig, ParseJsonContext *context);
cJSON *GetJsonObjFromFile(const char *jsonPath);
uint8_t *Base64Decode(const char *data, uint32_t dataLen, uint32_t *outLen);
char *Base64Encode(const uint8_t *data, uint32_t len);
uint64_t DiffTime(const struct timespec *startTime, const struct timespec *endTime);
void AppSpawnDump(const char *fmt, ...);
void SetDumpToStream(FILE *stream);
typedef int (*SplitStringHandle)(const char *str, void *context);
int32_t StringSplit(const char *str, const char *separator, void *context, SplitStringHandle handle);
char *GetLastStr(const char *str, const char *dst);
void DumpCurrentDir(char *buffer, uint32_t bufferLen, const char *dirPath);
#ifndef APP_FILE_NAME
#define APP_FILE_NAME (strrchr((__FILE__), '/') ? strrchr((__FILE__), '/') + 1 : (__FILE__))
#endif
#ifndef OHOS_LITE
#define APPSPAWN_DOMAIN (0xD002C00 + 0x11)
#ifndef APPSPAWN_LABEL
#define APPSPAWN_LABEL "APPSPAWN"
#endif
#undef LOG_TAG
#define LOG_TAG APPSPAWN_LABEL
#undef LOG_DOMAIN
#define LOG_DOMAIN APPSPAWN_DOMAIN
#define APPSPAWN_LOGI(fmt, ...) \
HILOG_INFO(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGE(fmt, ...) \
HILOG_ERROR(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGV(fmt, ...) \
HILOG_DEBUG(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGW(fmt, ...) \
HILOG_WARN(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGF(fmt, ...) \
HILOG_FATAL(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAPWN_DUMP(fmt, ...) \
do { \
HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__); \
AppSpawnDump(fmt "\n", ##__VA_ARGS__); \
} while (0)
#else
#define APPSPAWN_LOGI(fmt, ...) \
HILOG_INFO(HILOG_MODULE_HIVIEW, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGE(fmt, ...) \
HILOG_ERROR(HILOG_MODULE_HIVIEW, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGV(fmt, ...) \
HILOG_DEBUG(HILOG_MODULE_HIVIEW, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#define APPSPAWN_LOGW(fmt, ...) \
HILOG_FATAL(HILOG_MODULE_HIVIEW, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__)
#endif
#define APPSPAWN_CHECK(retCode, exper, fmt, ...) \
if (!(retCode)) { \
APPSPAWN_LOGE(fmt, ##__VA_ARGS__); \
exper; \
}
#define APPSPAWN_CHECK_ONLY_EXPER(retCode, exper) \
if (!(retCode)) { \
exper; \
} \
#define APPSPAWN_ONLY_EXPER(retCode, exper) \
if ((retCode)) { \
exper; \
}
#define APPSPAWN_CHECK_ONLY_LOG(retCode, fmt, ...) \
if (!(retCode)) { \
APPSPAWN_LOGE(fmt, ##__VA_ARGS__); \
}
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2023 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 COMMAND_LEXER_H
#define COMMAND_LEXER_H
#include <string>
#include <vector>
namespace OHOS {
namespace AppSpawn {
class CommandLexer {
public:
explicit CommandLexer(const std::string &str) : str_(str) {}
// Disable copy and move semantics to avoid extension of the lifecyle of the
// resource not owned by this class.
CommandLexer(const CommandLexer &other) = delete;
CommandLexer(CommandLexer &&other) = delete;
CommandLexer &operator=(const CommandLexer &other) = delete;
CommandLexer &operator=(CommandLexer &&other) = delete;
// Return true, and args will be populated with all argument. Otherwise,
// false is returned, and args will be cleared.
bool GetAllArguments(std::vector<std::string> &args);
private:
const std::string &str_;
};
} // namespace AppSpawn
} // namespace OHOS
#endif // COMMAND_LEXER_H

View File

@ -1,33 +0,0 @@
/*
* Copyright (C) 2024 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 ENV_UTILS_H
#define ENV_UTILS_H
#include <stdint.h>
#include "appspawn_server.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
int32_t SetEnvInfo(struct AppSpawnContent *content, AppSpawnClient *client);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // ENV_UTILS_H

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Copyright (C) 2024 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
@ -16,22 +16,50 @@
#ifndef JSON_UTILS_H
#define JSON_UTILS_H
#include <string>
#include <vector>
#include "nlohmann/json.hpp"
#include <stdbool.h>
namespace OHOS {
namespace AppSpawn {
class JsonUtils {
public:
static bool GetJsonObjFromJson(nlohmann::json& jsonObj, const std::string& jsonPath);
static bool GetStringFromJson(const nlohmann::json& json, const std::string& key, std::string& value);
static bool GetIntFromJson(const nlohmann::json& json, const std::string& key, int& value);
static bool GetStringVecFromJson(
const nlohmann::json& json, const std::string& key, std::vector<std::string>& value);
static bool ParseObjVecFromJson(
const nlohmann::json& json, const std::string& key, std::vector<nlohmann::json>& value);
};
} // namespace AppSpawn
} // namespace OHOS
#include "appspawn_utils.h"
#include "cJSON.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define MAX_JSON_FILE_LEN 102400
typedef struct TagParseJsonContext ParseJsonContext;
typedef int (*ParseConfig)(const cJSON *root, ParseJsonContext *context);
int ParseJsonConfig(const char *path, const char *fileName, ParseConfig parseConfig, ParseJsonContext *context);
cJSON *GetJsonObjFromFile(const char *jsonPath);
__attribute__((always_inline)) inline char *GetStringFromJsonObj(const cJSON *json, const char *key)
{
APPSPAWN_CHECK_ONLY_EXPER(key != NULL && json != NULL, NULL);
APPSPAWN_CHECK(cJSON_IsObject(json), return NULL, "json is not object %{public}s %s", key, cJSON_Print(json));
cJSON *obj = cJSON_GetObjectItemCaseSensitive(json, key);
APPSPAWN_CHECK_ONLY_EXPER(obj != NULL, return NULL);
APPSPAWN_CHECK(cJSON_IsString(obj), return NULL, "json is not string %{public}s %s", key, cJSON_Print(obj));
return cJSON_GetStringValue(obj);
}
__attribute__((always_inline)) inline bool GetBoolValueFromJsonObj(const cJSON *json, const char *key, bool def)
{
char *value = GetStringFromJsonObj(json, key);
APPSPAWN_CHECK_ONLY_EXPER(value != NULL, return def);
if (strcmp(value, "true") == 0 || strcmp(value, "ON") == 0 || strcmp(value, "True") == 0) {
return true;
}
return false;
}
__attribute__((always_inline)) inline uint32_t GetIntValueFromJsonObj(const cJSON *json, const char *key, uint32_t def)
{
APPSPAWN_CHECK(json != NULL, return def, "Invalid json");
APPSPAWN_CHECK(cJSON_IsObject(json), return def, "json is not object.");
return cJSON_GetNumberValue(cJSON_GetObjectItemCaseSensitive(json, key));
}
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // JSON_UTILS_H

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2023 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 PARAM_HELPER_H
#define PARAM_HELPER_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Return 1 if the device is in the developer mode, otherwise 0 is returned.
int IsDeveloperModeOn();
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // PARAM_HELPER_H

View File

@ -16,6 +16,7 @@
#include "appspawn_utils.h"
#include <ctype.h>
#include <dirent.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -27,9 +28,21 @@
#include "appspawn_hook.h"
#include "cJSON.h"
#include "config_policy_utils.h"
#include "json_utils.h"
#include "parameter.h"
#include "securec.h"
uint64_t DiffTime(const struct timespec *startTime, const struct timespec *endTime)
{
uint64_t diff = (uint64_t)((endTime->tv_sec - startTime->tv_sec) * 1000000); // 1000000 s-us
if (endTime->tv_nsec > startTime->tv_nsec) {
diff += (endTime->tv_nsec - startTime->tv_nsec) / 1000; // 1000 ns - us
} else {
diff -= (startTime->tv_nsec - endTime->tv_nsec) / 1000; // 1000 ns - us
}
return diff;
}
int MakeDirRec(const char *path, mode_t mode, int lastPath)
{
if (path == NULL || *path == '\0') {
@ -122,7 +135,7 @@ char *GetLastStr(const char *str, const char *dst)
char *end = (char *)str + strlen(str);
size_t len = strlen(dst);
while (end != str) {
if (isspace(*end)) { // clear space
if (isspace(*end)) { // clear space
*end = '\0';
end--;
continue;
@ -149,7 +162,7 @@ static char *ReadFile(const char *fileName)
fd = fopen(fileName, "r");
APPSPAWN_CHECK(fd != NULL, break, "Failed to open file %{public}s", fileName);
buffer = (char*)malloc((size_t)(fileStat.st_size + 1));
buffer = (char *)malloc((size_t)(fileStat.st_size + 1));
APPSPAWN_CHECK(buffer != NULL, break, "Failed to alloc mem %{public}s", fileName);
int ret = fread(buffer, fileStat.st_size, 1, fd);
@ -174,7 +187,9 @@ cJSON *GetJsonObjFromFile(const char *jsonPath)
APPSPAWN_CHECK_ONLY_EXPER(jsonPath != NULL && *jsonPath != '\0', NULL);
char *buffer = ReadFile(jsonPath);
APPSPAWN_CHECK_ONLY_EXPER(buffer != NULL, NULL);
return cJSON_Parse(buffer);
cJSON *json = cJSON_Parse(buffer);
free(buffer);
return json;
}
int ParseJsonConfig(const char *basePath, const char *fileName, ParseConfig parseConfig, ParseJsonContext *context)
@ -206,8 +221,90 @@ int ParseJsonConfig(const char *basePath, const char *fileName, ParseConfig pars
return ret;
}
void DumpCurrentDir(char *buffer, uint32_t bufferLen, const char *dirPath)
{
char tmp[32] = {0}; // 32 max
int ret = GetParameter("startup.appspawn.cold.boot", "", tmp, sizeof(tmp));
if (ret <= 0 || strcmp(tmp, "1") != 0) {
return;
}
struct stat st = {};
if (stat(dirPath, &st) == 0 && S_ISREG(st.st_mode)) {
APPSPAWN_LOGW("file %{public}s", dirPath);
if (access(dirPath, F_OK) != 0) {
APPSPAWN_LOGW("file %{public}s not exist", dirPath);
}
return;
}
DIR *pDir = opendir(dirPath);
APPSPAWN_CHECK(pDir != NULL, return, "Read dir :%{public}s failed.%{public}d", dirPath, errno);
struct dirent *dp;
while ((dp = readdir(pDir)) != NULL) {
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) {
continue;
}
if (dp->d_type == DT_DIR) {
APPSPAWN_LOGW(" Current path %{public}s/%{public}s ", dirPath, dp->d_name);
ret = snprintf_s(buffer, bufferLen, bufferLen - 1, "%s/%s", dirPath, dp->d_name);
APPSPAWN_CHECK(ret > 0, break, "Failed to snprintf_s errno: %{public}d", errno);
char *path = strdup(buffer);
DumpCurrentDir(buffer, bufferLen, path);
free(path);
}
}
closedir(pDir);
return;
}
static FILE *g_dumpToStream = NULL;
void SetDumpToStream(FILE *stream)
{
g_dumpToStream = stream;
}
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wvarargs"
#elif defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wvarargs"
#elif defined(_MSC_VER)
# pragma warning(push)
#endif
void AppSpawnDump(const char *fmt, ...)
{
if (g_dumpToStream == NULL) {
return;
}
char format[128] = {0}; // 128 max buffer for format
uint32_t size = strlen(fmt);
int curr = 0;
for (uint32_t index = 0; index < size; index++) {
if (curr >= (int)sizeof(format)) {
format[curr - 1] = '\0';
}
if (fmt[index] == '%' && (strncmp(&fmt[index + 1], "{public}", strlen("{public}")) == 0)) {
format[curr++] = fmt[index];
index += strlen("{public}");
continue;
}
format[curr++] = fmt[index];
}
va_list vargs;
va_start(vargs, format);
(void)vfprintf(g_dumpToStream, format, vargs);
va_end(vargs);
(void)fflush(g_dumpToStream);
}
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
#include "appspawn_server.h"
#include "command_lexer.h"
using namespace OHOS::AppSpawn;
enum class ParsingState {
INIT,
IN_WHITESPACE,
IN_ARGUMENT,
IN_SINGLE_QUOTE,
IN_DOUBLE_QUOTE,
};
bool CommandLexer::GetAllArguments(std::vector<std::string> &args)
{
constexpr char singleQuote = '\'';
constexpr char doubleQuote = '"';
ParsingState state = ParsingState::INIT;
std::string lastArg;
for (size_t i = 0; i < str_.size(); i++) {
switch (state) {
case ParsingState::INIT:
if (isspace(str_[i])) {
state = ParsingState::IN_WHITESPACE;
} else if (str_[i] == singleQuote) {
state = ParsingState::IN_SINGLE_QUOTE;
} else if (str_[i] == doubleQuote) {
state = ParsingState::IN_DOUBLE_QUOTE;
} else {
state = ParsingState::IN_ARGUMENT;
lastArg += str_[i];
}
break;
case ParsingState::IN_WHITESPACE:
if (str_[i] == singleQuote) {
state = ParsingState::IN_SINGLE_QUOTE;
} else if (str_[i] == doubleQuote) {
state = ParsingState::IN_DOUBLE_QUOTE;
} else if (!isspace(str_[i])) {
state = ParsingState::IN_ARGUMENT;
lastArg += str_[i];
}
break;
case ParsingState::IN_ARGUMENT:
if (isspace(str_[i])) {
args.push_back(std::move(lastArg));
// Whether a moved string is empty depends on the
// implementation of C++ std library, so clear() is called.
lastArg.clear();
state = ParsingState::IN_WHITESPACE;
} else if (str_[i] == singleQuote) {
state = ParsingState::IN_SINGLE_QUOTE;
} else if (str_[i] == doubleQuote) {
state = ParsingState::IN_DOUBLE_QUOTE;
} else {
lastArg += str_[i];
}
break;
case ParsingState::IN_SINGLE_QUOTE:
if (str_[i] == singleQuote) {
state = ParsingState::IN_ARGUMENT;
} else {
lastArg += str_[i];
}
break;
case ParsingState::IN_DOUBLE_QUOTE:
if (str_[i] == doubleQuote) {
state = ParsingState::IN_ARGUMENT;
} else {
lastArg += str_[i];
}
break;
}
}
if (state == ParsingState::IN_ARGUMENT) {
args.push_back(std::move(lastArg));
} else if (state == ParsingState::IN_SINGLE_QUOTE ||
state == ParsingState::IN_DOUBLE_QUOTE) {
APPSPAWN_LOGE("Parsing arguments failed: missing terminated quote");
args.clear();
return false;
}
return true;
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2024 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.
*/
#include "env_utils.h"
#include "appspawn_service.h"
#include "sandbox_utils.h"
#include "nlohmann/json.hpp"
const std::string APPENVLIST_TYPE = "|AppEnv|";
int32_t SetEnvInfo(struct AppSpawnContent *content, AppSpawnClient *client)
{
int ret = 0;
OHOS::AppSpawn::ClientSocket::AppProperty *appProperty = &reinterpret_cast<AppSpawnClientExt *>(client)->property;
std::string appEnvInfo = OHOS::AppSpawn::SandboxUtils::GetExtraInfoByType(appProperty, APPENVLIST_TYPE);
APPSPAWN_LOGW("SetEnvInfo: %{public}s", appEnvInfo.c_str());
if (appEnvInfo.length() == 0) {
return ret;
}
nlohmann::json envs = nlohmann::json::parse(appEnvInfo.c_str(), nullptr, false);
APPSPAWN_CHECK(!envs.is_discarded(), return -1, "SetEnvInfo: json parse failed");
for (nlohmann::json::iterator it = envs.begin(); it != envs.end(); ++it) {
APPSPAWN_CHECK(it.value().is_string(), return -1, "SetEnvInfo: element type error");
std::string name = it.key();
std::string value = it.value();
ret = setenv(name.c_str(), value.c_str(), 1);
APPSPAWN_CHECK(ret == 0, return ret, "setenv failed, errno is %{public}d", errno);
}
APPSPAWN_LOGI("SetEnvInfo success");
return ret;
}

View File

@ -1,112 +0,0 @@
/*
* Copyright (C) 2022 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.
*/
#include <cerrno>
#include <sstream>
#include <fstream>
#include "appspawn_server.h"
#include "cJSON.h"
#include "config_policy_utils.h"
#include "json_utils.h"
#include "appspawn_utils.h"
using namespace std;
using namespace OHOS;
namespace OHOS {
namespace AppSpawn {
bool JsonUtils::GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath)
{
APPSPAWN_CHECK(jsonPath.length() <= PATH_MAX, return false, "jsonPath is too long");
std::ifstream jsonFileStream;
jsonFileStream.open(jsonPath.c_str(), std::ios::in);
APPSPAWN_CHECK_ONLY_EXPER(jsonFileStream.is_open(), return false);
std::ostringstream buf;
char ch;
while (buf && jsonFileStream.get(ch)) {
buf.put(ch);
}
jsonFileStream.close();
jsonObj = nlohmann::json::parse(buf.str(), nullptr, false);
APPSPAWN_CHECK(jsonObj.is_structured(), return false, "Parse json file into jsonObj failed.");
return true;
}
bool JsonUtils::GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value)
{
APPSPAWN_CHECK(json.is_object(), return false, "json is not object.");
bool isRet = json.find(key) != json.end() && json.at(key).is_string();
if (isRet) {
value = json.at(key).get<std::string>();
APPSPAWN_LOGV("Find key[%{public}s] : %{public}s successful.", key.c_str(), value.c_str());
return true;
} else {
return false;
}
}
} // namespace AppSpawn
} // namespace OHOS
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
cJSON *GetJsonObjFromFile(const char *jsonPath)
{
std::ifstream jsonFileStream;
jsonFileStream.open(jsonPath, std::ios::in);
APPSPAWN_CHECK_ONLY_EXPER(jsonFileStream.is_open(), return nullptr);
std::ostringstream buf;
char ch;
while (buf && jsonFileStream.get(ch)) {
buf.put(ch);
}
jsonFileStream.close();
return cJSON_Parse(buf.str().c_str());
}
int ParseJsonConfig(const char *basePath, const char *fileName, ParseConfig parseConfig, ParseJsonContext *context)
{
// load sandbox config
CfgFiles *files = GetCfgFiles(basePath);
if (files == nullptr) {
return APPSPAWN_SANDBOX_NONE;
}
int ret = 0;
for (int i = 0; i < MAX_CFG_POLICY_DIRS_CNT; ++i) {
if (files->paths[i] == nullptr) {
continue;
}
std::string path = files->paths[i];
path += fileName;
APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", path.c_str());
cJSON *root = GetJsonObjFromFile(path.c_str());
APPSPAWN_CHECK(root != nullptr, ret = APPSPAWN_SANDBOX_INVALID;
continue, "Failed to load app data sandbox config %{public}s", path.c_str());
int rc = parseConfig(root, context);
if (rc != 0) {
ret = rc;
}
cJSON_Delete(root);
}
FreeCfgFiles(files);
return ret;
}
#ifdef __cplusplus
}
#endif // __cplusplus

View File

@ -1,32 +0,0 @@
/*
* Copyright (C) 2023 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.
*/
#include "param_helper.h"
#include <string.h>
#include "parameter.h"
#define DEVEVELOPER_MODE_KEY "const.security.developermode.state"
#define DEVEVELOPER_MODE_VALUE_ON "true"
#define DEVEVELOPER_MODE_VALUE_DEFAULT ""
int IsDeveloperModeOn()
{
char value[10] = {0};
int ret = GetParameter(DEVEVELOPER_MODE_KEY, DEVEVELOPER_MODE_VALUE_DEFAULT,
value, sizeof(value));
return ret > 0 && strncmp(value, DEVEVELOPER_MODE_VALUE_ON, sizeof(value)) == 0;
}