From 56668d8bd1e738e565e4b3ea545c79b80757c1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B5=A9?= Date: Mon, 4 Aug 2025 19:33:45 +0800 Subject: [PATCH] clear mmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 杨浩 --- standard/appspawn_service.c | 40 +++-- test/BUILD.gn | 1 + .../single_test/appspawn_service/BUILD.gn | 62 +++++++ .../include/appspawn_service_single_test.h | 31 ++++ .../src/appspawn_service_single_test.cpp | 153 ++++++++++++++++++ .../hnp_installer/src/hnp_installer_test.cpp | 12 +- 6 files changed, 283 insertions(+), 16 deletions(-) create mode 100644 test/unittest/single_test/appspawn_service/BUILD.gn create mode 100644 test/unittest/single_test/appspawn_service/include/appspawn_service_single_test.h create mode 100644 test/unittest/single_test/appspawn_service/src/appspawn_service_single_test.cpp diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 31d6cf9c..94df1bdf 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -520,7 +520,8 @@ static char *GetMapMem(uint32_t clientId, const char *processName, uint32_t size int fd = open(path, mode, S_IRWXU); APPSPAWN_CHECK(fd >= 0, return NULL, "Failed to open errno %{public}d path %{public}s", errno, path); if (!readOnly) { - ftruncate(fd, size); + APPSPAWN_CHECK(fallocate(fd, 0, 0, size) == 0, close(fd); + return NULL, "failed fallocate %{public}s %{public}d", processName, errno); } void *areaAddr = (void *)mmap(NULL, size, prot, MAP_SHARED, fd, 0); close(fd); @@ -695,21 +696,41 @@ static bool IsSupportRunHnp() return false; } -static void ClearMMAP(int clientId, uint32_t memSize) +APPSPAWN_STATIC void ClearMMAP(int clientId, uint32_t memSize) { + AppSpawnContent *content = GetAppSpawnContent(); + if (content != NULL && content->propertyBuffer != NULL) { + int ret = munmap(content->propertyBuffer, memSize); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "munmap failed %{public}d %{public}d", ret, errno); + content->propertyBuffer = NULL; + } + char path[PATH_MAX] = {0}; int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, APPSPAWN_MSG_DIR "appspawn/prefork_%d", clientId); APPSPAWN_CHECK_ONLY_LOG(ret > 0, "snprintf failed with %{public}d %{public}d", ret, errno); if (ret > 0 && access(path, F_OK) == 0) { - ret = unlink(path); + ret = unlink(path); APPSPAWN_CHECK_ONLY_LOG(ret == 0, "prefork unlink result %{public}d %{public}d", ret, errno); } +} - AppSpawnContent *content = GetAppSpawnContent(); - if (content != NULL && content->propertyBuffer != NULL) { - ret = munmap(content->propertyBuffer, memSize); +APPSPAWN_STATIC void ClearPreforkInfo(AppSpawningCtx *property) +{ + APPSPAWN_CHECK(property != NULL, return, "invalid property"); + + if (property->forkCtx.childMsg != NULL) { + int ret = munmap(property->forkCtx.childMsg, property->forkCtx.msgSize); APPSPAWN_CHECK_ONLY_LOG(ret == 0, "munmap failed %{public}d %{public}d", ret, errno); - content->propertyBuffer = NULL; + property->forkCtx.childMsg = NULL; + } + + char path[PATH_MAX] = {0}; + int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, APPSPAWN_MSG_DIR "appspawn/prefork_%d", + property->client.id); + APPSPAWN_CHECK_ONLY_LOG(ret > 0, "snprintf failed with %{public}d %{public}d", ret, errno); + if (ret > 0 && access(path, F_OK) == 0) { + ret = unlink(path); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "prefork unlink result %{public}d %{public}d", ret, errno); } } @@ -831,12 +852,12 @@ static void ProcessPreFork(AppSpawnContent *content, AppSpawningCtx *property) const uint32_t memSize = (preforkMsg.msgLen / MAX_MSG_BLOCK_LEN + 1) * MAX_MSG_BLOCK_LEN; if (GetAppSpawnMsg(property, memSize) == -1) { APPSPAWN_LOGE("prefork child read GetAppSpawnMsg failed"); - ClearMMAP(property->client.id, memSize); + ClearPreforkInfo(property); content->notifyResToParent(content, &property->client, APPSPAWN_MSG_INVALID); ProcessExit(0); return; } - ClearMMAP(property->client.id, memSize); + ClearPreforkInfo(property); // Inherit the error level of the original process (void)fdsan_set_error_level(errorLevel); ProcessExit(AppSpawnChild(content, &property->client)); @@ -1392,7 +1413,6 @@ AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcNam AppSpawnContent *StartSpawnService(const AppSpawnStartArg *startArg, uint32_t argvSize, int argc, char *const argv[]) { APPSPAWN_CHECK(startArg != NULL && argv != NULL, return NULL, "Invalid start arg"); - pid_t pid = 0; AppSpawnStartArg *arg = (AppSpawnStartArg *)startArg; APPSPAWN_LOGV("Start appspawn argvSize %{public}d mode %{public}d service %{public}s", argvSize, arg->mode, arg->serviceName); diff --git a/test/BUILD.gn b/test/BUILD.gn index bfb189b8..11cb2f9e 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -32,6 +32,7 @@ group("unittest") { } deps += [ "unittest/hnp_test:HnpTest" ] deps += [ "unittest/single_test/hnp_installer:hnp_installer_test" ] + deps += [ "unittest/single_test/appspawn_service:appspawn_service_single_test" ] deps += [ "unittest/devicedebug_test:DevicedebugTest" ] deps += [ "unittest/app_spawn_hisysevent_test:AppSpawn_HisysEvent_ut" ] } else { diff --git a/test/unittest/single_test/appspawn_service/BUILD.gn b/test/unittest/single_test/appspawn_service/BUILD.gn new file mode 100644 index 00000000..34027967 --- /dev/null +++ b/test/unittest/single_test/appspawn_service/BUILD.gn @@ -0,0 +1,62 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/startup/appspawn/appspawn.gni") +import("//build/test.gni") + +if (!defined(ohos_lite)) { + ohos_unittest("appspawn_service_single_test") { + module_out_path = "appspawn/appspawn" + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-unused-function", + "-Wno-unused-variable", + "-Dprivate=public", + "-Dprotected=public", + ] + + cflags_cc = [ + "-Wno-implicit-fallthrough", + "-fexceptions", + ] + + include_dirs = [ + "include", + "${appspawn_path}/standard", + "${appspawn_path}/common", + "${appspawn_path}/modules/modulemgr", + "${appspawn_path}/modules/common" + ] + + sources = [ + "src/appspawn_service_single_test.cpp", + "${appspawn_path}/standard/appspawn_service.c", + "${appspawn_path}/standard/appspawn_appmgr.c", + "${appspawn_path}/standard/appspawn_msgmgr.c" + ] + + defines = [ + "APPSPAWN_TEST", + "APPSPAWN_BASE_DIR=\"/data/appspawn_ut\"", + ] + + deps = [ "${appspawn_path}/util:libappspawn_util" ] + + external_deps = [ + "bounds_checking_function:libsec_shared", + "cJSON:cjson", + "hilog:libhilog", + "init:libbegetutil", + ] + + } +} diff --git a/test/unittest/single_test/appspawn_service/include/appspawn_service_single_test.h b/test/unittest/single_test/appspawn_service/include/appspawn_service_single_test.h new file mode 100644 index 00000000..b10d960e --- /dev/null +++ b/test/unittest/single_test/appspawn_service/include/appspawn_service_single_test.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef APPSPAWN_SERVICE_SINGLETEST_H +#define APPSPAWN_SERVICE_SINGLETEST_H + +#include "appspawn_manager.h" +#ifdef __cplusplus +extern "C" { +#endif + +void ClearMMAP(int clientId, uint32_t memSize); + +void ClearPreforkInfo(AppSpawningCtx *property); + + +#ifdef __cplusplus +} +#endif +#endif // APPSPAWN_SERVICE_SINGLETEST_H diff --git a/test/unittest/single_test/appspawn_service/src/appspawn_service_single_test.cpp b/test/unittest/single_test/appspawn_service/src/appspawn_service_single_test.cpp new file mode 100644 index 00000000..d29a2d8a --- /dev/null +++ b/test/unittest/single_test/appspawn_service/src/appspawn_service_single_test.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "appspawn_service_single_test.h" +#include +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "appspawn_utils.h" + +#define MEMSIZE 4096 + +using namespace testing; +using namespace testing::ext; + +const static int CLIENT_ID = 10000; + +#ifdef __cplusplus +extern "C" { +#endif + + +static void CreateTestFile(const char *fileName, const char *data) +{ + FILE *tmpFile = fopen(fileName, "wr"); + if (tmpFile != nullptr) { + fprintf(tmpFile, "%s", data); + (void)fflush(tmpFile); + fclose(tmpFile); + } +} + + +#ifdef __cplusplus +} +#endif + +namespace OHOS { +class AppspawnServiceSingleTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void AppspawnServiceSingleTest::SetUpTestCase() +{ + GTEST_LOG_(INFO) << "AppspawnServiceSingleTest SetUpTestCase"; +} + +void AppspawnServiceSingleTest::TearDownTestCase() +{ + GTEST_LOG_(INFO) << "AppspawnServiceSingleTest TearDownTestCase"; +} + +void AppspawnServiceSingleTest::SetUp() +{ + GTEST_LOG_(INFO) << "AppspawnServiceSingleTest SetUp"; +} + +void AppspawnServiceSingleTest::TearDown() +{ + GTEST_LOG_(INFO) << "AppspawnServiceSingleTest TearDown"; +} + + +HWTEST_F(AppspawnServiceSingleTest, ClearMmap_001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "ClearMmap_001 start"; + char perforkFile[PATH_MAX] = {0}; + size_t bytes = snprintf_s(perforkFile, PATH_MAX, PATH_MAX - 1, APPSPAWN_MSG_DIR"appspawn/prefork_%d", CLIENT_ID); + EXPECT_NE(bytes, 0); + + AppSpawnMgr *mgr = CreateAppSpawnMgr(0); + EXPECT_TRUE(mgr != nullptr); + MakeDirRec(APPSPAWN_MSG_DIR"appspawn", 0711, 1); + + CreateTestFile(perforkFile, ""); + int fd = open(perforkFile, O_RDONLY, S_IRWXU); + + EXPECT_TRUE(fd > 0); + void *areaAddr = mmap(nullptr, MEMSIZE, PROT_READ, MAP_SHARED, fd, 0); + EXPECT_TRUE(areaAddr != nullptr); + mgr->content.propertyBuffer = (char *)areaAddr; + ClearMMAP(CLIENT_ID, MEMSIZE); + EXPECT_TRUE(mgr->content.propertyBuffer == nullptr); + EXPECT_TRUE(access(perforkFile, F_OK) != 0); + DeleteAppSpawnMgr(mgr); + GTEST_LOG_(INFO) << "ClearMmap_001 end"; +} + +HWTEST_F(AppspawnServiceSingleTest, ClearMmap_002, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "ClearMmap_002 start"; + char perforkFile[PATH_MAX] = {0}; + size_t bytes = snprintf_s(perforkFile, PATH_MAX, PATH_MAX - 1, APPSPAWN_MSG_DIR"appspawn/prefork_%d", CLIENT_ID); + EXPECT_NE(bytes, 0); + + ClearMMAP(CLIENT_ID, MEMSIZE); + EXPECT_NE(access(perforkFile, F_OK), 0); + GTEST_LOG_(INFO) << "ClearMmap_002 end"; +} + +HWTEST_F(AppspawnServiceSingleTest, ClearPreforkInfo_001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "ClearPreforkInfo_001 start"; + AppSpawningCtx *ctx = CreateAppSpawningCtx(); + EXPECT_TRUE(ctx != nullptr); + char perforkFile[PATH_MAX] = {0}; + size_t bytes = snprintf_s(perforkFile, PATH_MAX, PATH_MAX - 1, APPSPAWN_MSG_DIR"appspawn/prefork_%d", CLIENT_ID); + EXPECT_NE(bytes, 0); + MakeDirRec(APPSPAWN_MSG_DIR"appspawn", 0711, 1); + + CreateTestFile(perforkFile, ""); + int fd = open(perforkFile, O_RDONLY, S_IRWXU); + EXPECT_TRUE(fd > 0); + void *areaAddr = mmap(nullptr, MEMSIZE, PROT_READ, MAP_SHARED, fd, 0); + EXPECT_TRUE(areaAddr != nullptr); + ctx->forkCtx.childMsg = (char *)areaAddr; + + ctx->client.id = CLIENT_ID; + ClearPreforkInfo(ctx); + EXPECT_TRUE(ctx->forkCtx.childMsg == nullptr); + DeleteAppSpawningCtx(ctx); + GTEST_LOG_(INFO) << "ClearPreforkInfo_001 end"; +} + +HWTEST_F(AppspawnServiceSingleTest, ClearPreforkInfo_002, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "ClearPreforkInfo_002 start"; + AppSpawningCtx *ctx = CreateAppSpawningCtx(); + EXPECT_TRUE(ctx != nullptr); + ClearPreforkInfo(ctx); + DeleteAppSpawningCtx(ctx); + GTEST_LOG_(INFO) << "ClearPreforkInfo_002 end"; +} +} \ No newline at end of file diff --git a/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp b/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp index e7c1d7f5..9421ef66 100644 --- a/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp +++ b/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp @@ -36,7 +36,7 @@ using namespace testing::ext; #endif namespace OHOS { -class InitFirststageTest : public testing::Test { +class HnpInstallerSingleTest : public testing::Test { public: static void SetUpTestCase(); static void TearDownTestCase(); @@ -44,22 +44,22 @@ public: void TearDown(); }; -void InitFirststageTest::SetUpTestCase() +void HnpInstallerSingleTest::SetUpTestCase() { GTEST_LOG_(INFO) << "Hnp_Installer_TEST SetUpTestCase"; } -void InitFirststageTest::TearDownTestCase() +void HnpInstallerSingleTest::TearDownTestCase() { GTEST_LOG_(INFO) << "Hnp_Installer_TEST TearDownTestCase"; } -void InitFirststageTest::SetUp() +void HnpInstallerSingleTest::SetUp() { GTEST_LOG_(INFO) << "Hnp_Installer_TEST SetUp"; } -void InitFirststageTest::TearDown() +void HnpInstallerSingleTest::TearDown() { GTEST_LOG_(INFO) << "Hnp_Installer_TEST TearDown"; } @@ -95,7 +95,7 @@ static void CreateTestFile(const char *fileName, const char *data) } } -HWTEST_F(InitFirststageTest, hnp_clearSoftLink_001, TestSize.Level0) +HWTEST_F(HnpInstallerSingleTest, hnp_clearSoftLink_001, TestSize.Level0) { GTEST_LOG_(INFO) << "hnp_clearSoftLink_001 start"; -- Gitee