!1621 限制最大fork进程数

Merge pull request !1621 from 樊景乐/master
This commit is contained in:
openharmony_ci 2024-10-29 06:12:09 +00:00 committed by Gitee
commit 421daadd78
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 76 additions and 125 deletions

View File

@ -30,8 +30,6 @@
#include "appspawn_manager.h"
#include "appspawn_utils.h"
#include "securec.h"
#include "cJSON.h"
#include <sys/ioctl.h>
APPSPAWN_STATIC int GetCgroupPath(const AppSpawnedProcessInfo *appInfo, char *buffer, uint32_t buffLen)
{
@ -68,57 +66,6 @@ APPSPAWN_STATIC int WriteToFile(const char *path, int truncated, pid_t pids[], u
return ret;
}
#define APP_PIDS_MAX_ENCAPS "encaps"
#define APP_PIDS_MAX_OHOS_ENCAPS_COUNT_KEY "ohos.encaps.count"
#define APP_PIDS_MAX_OHOS_ENCAPS_FORK_KEV "ohos.encaps.fork"
#define APP_PIDS_MAX_OHOS_ENCAPS_FORK_DFX_KEY "ohos.encaps.fork.dfx"
#define APP_PIDS_MAX_OHOS_ENCAPS_FORK_WEBDFX_KEY "ohos.encaps.fork.webdfx"
#define APP_PIDS_MAX_OHOS_ENCAPS_COUNT_VALUE 3
#define APP_PIDS_MAX_OHOS_ENCAPS_FORK_DFX_AND_WEBDFX_VALUE 5
#define APP_ENABLE_ENCAPS 1
#define ASSICN_ENCAPS_CMD _lOW('E', 0x1A, char *)
static int WritePidMax(const char *path, uint32_t max)
{
#if APP_ENABLE_ENCAPS == 0
cJSON *encaps = cJSON_CreateObject();
cJSON_AddNumberToObject(encaps, APP_PIDS_MAX_OHOS_ENCAPS_COUNT_KEY,
APP_PIDS_MAX_OHOS_ENCAPS_COUNT_VALUE);
cJSON_AddNumberToObject(encaps, APP_PIDS_MAX_OHOS_ENCAPS_FORK_KEV, max);
cJSON_AddNumberToObject(encaps, APP_PIDS_MAX_OHOS_ENCAPS_FORK_DFX_KEY,
APP_PIDS_MAX_OHOS_ENCAPS_FORK_DFX_AND_WEBDFX_VALUE);
cJSON_AddNumberToObject(encaps, APP_PIDS_MAX_OHOS_ENCAPS_FORK_WEBDFX_KEY,
APP_PIDS_MAX_OHOS_ENCAPS_FORK_DFX_AND_WEBDFX_VALUE);
cJSON *addGinseng = cJSON_CreateObject();
cJSON_AddItemToObject(addGinseng, APP_PIDS_MAX_ENCAPS, encaps);
char *maxPid = cJSON_PrintUnformatted(addGinseng);
int ret = 0;
int fd = 0;
fd = open("dev/encaps", O_RDWR);
ret = ioctl(fd, ASSICN_ENCAPS_CMD, maxPid);
close(fd);
free(maxPid);
cJSON_Delete(addGinseng);
cJSON_Delete(encaps);
return ret;
#else
char value[32] = {0}; // 32 max len
int fd = open(path, O_RDWR | O_TRUNC);
APPSPAWN_CHECK(fd >= 0, return -1,
"Failed to open file errno: %{public}d path: %{public}s", errno, path);
int ret = 0;
do {
ret = snprintf_s(value, sizeof(value), sizeof(value) - 1, "%u\n", max);
APPSPAWN_CHECK(ret > 0, break, "Failed to snprintf_s errno: %{public}d", errno);
ret = write(fd, value, strlen(value));
APPSPAWN_CHECK(ret > 0, break,
"Failed to write file errno: %{public}d path: %{public}s %{public}s %{public}d", errno, path, value, ret);
ret = 0;
} while (0);
close(fd);
return ret;
#endif
}
static void SetForkDenied(const AppSpawnedProcessInfo *appInfo)
{
char pathForkDenied[PATH_MAX] = {};
@ -205,18 +152,10 @@ APPSPAWN_STATIC int ProcessMgrAddApp(const AppSpawnMgr *content, const AppSpawne
int ret = GetCgroupPath(appInfo, path, sizeof(path));
APPSPAWN_CHECK(ret == 0, return -1, "Failed to get real path errno: %{public}d", errno);
(void)CreateSandboxDir(path, 0750); // 0750 default mode
uint32_t pathLen = strlen(path);
ret = strcat_s(path, sizeof(path), "cgroup.procs");
APPSPAWN_CHECK(ret == 0, return ret, "Failed to strcat_s errno: %{public}d", errno);
ret = WriteToFile(path, 0, (pid_t *)&appInfo->pid, 1);
APPSPAWN_CHECK(ret == 0, return ret, "write pid to cgroup.procs fail %{public}s", path);
if (appInfo->max != 0) {
path[pathLen] = '\0';
ret = strcat_s(path, sizeof(path), "pids.max");
APPSPAWN_CHECK(ret == 0, return ret, "Failed to strcat_s errno: %{public}d", errno);
ret = WritePidMax(path, appInfo->max);
APPSPAWN_CHECK(ret == 0, return ret, "write max to pids.max fail %{public}s", path);
}
APPSPAWN_LOGV("Add app %{public}d to cgroup %{public}s success", appInfo->pid, path);
return 0;
}

View File

@ -46,6 +46,7 @@
#include "init_param.h"
#include "parameter.h"
#include "securec.h"
#include "cJSON.h"
#ifdef CODE_SIGNATURE_ENABLE // for xpm
#include "code_sign_attr_utils.h"
@ -391,6 +392,76 @@ static void SpawnLoadSilk(const AppSpawnMgr *content, const AppSpawningCtx *prop
LoadSilkLibrary(processName);
}
#define APP_PIDS_MAX_ENCAPS "encaps"
#define APP_PIDS_MAX_OHOS_ENCAPS_COUNT_KEY "ohos.encaps.count"
#define APP_PIDS_MAX_OHOS_ENCAPS_FORK_KEY "ohos.encaps.fork.count"
#define APP_PIDS_MAX_OHOS_ENCAPS_COUNT_VALUE 1
#define MSG_EXT_NAME_MAX_DECIMAL 10
#define ASSICN_ENCAPS_CMD _IOW('E', 0x1A, char *)
static int SpawnSetEncaps(AppSpawnMgr *content, AppSpawningCtx *property)
{
int ret = 0;
char *pidMaxStr = NULL;
uint32_t len = 0;
pidMaxStr = GetAppPropertyExt(property, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, &len);
APPSPAWN_CHECK_ONLY_EXPER(pidMaxStr != NULL, return ret);
uint32_t max = 0;
if (len != 0) {
char *endPtr = NULL;
max = strtoul(pidMaxStr, &endPtr, MSG_EXT_NAME_MAX_DECIMAL);
if (endPtr == pidMaxStr || *endPtr != '\0') {
APPSPAWN_LOGE("pidMaxStr: %{public}s Data errors", endPtr);
return ret;
}
}
cJSON *encaps = cJSON_CreateObject();
APPSPAWN_CHECK(encaps != NULL, return ret, "Failed to create encaps json object");
cJSON *addGinseng = cJSON_CreateObject();
if (addGinseng == NULL) {
cJSON_Delete(encaps);
encaps = NULL;
APPSPAWN_LOGE("Failed to create addGinseng json object");
return ret;
}
cJSON_AddNumberToObject(encaps, APP_PIDS_MAX_OHOS_ENCAPS_COUNT_KEY,
APP_PIDS_MAX_OHOS_ENCAPS_COUNT_VALUE);
cJSON_AddNumberToObject(encaps, APP_PIDS_MAX_OHOS_ENCAPS_FORK_KEY, max);
cJSON_AddItemToObject(addGinseng, APP_PIDS_MAX_ENCAPS, encaps);
char *maxPid = cJSON_PrintUnformatted(addGinseng);
int fd = 0;
fd = open("dev/encaps", O_RDWR);
if (fd < 0) {
APPSPAWN_LOGW("Failed to open encaps fd for bundleName:%{public}s errno:%{public}d",
GetBundleName(property), errno);
goto EXIT;
}
ret = ioctl(fd, ASSICN_ENCAPS_CMD, maxPid);
APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Encaps the setup failed ret:%{public}d fd:%{public}d maxPid: %{public}s",
ret, fd, maxPid);
close(fd);
EXIT:
free(maxPid);
maxPid = NULL;
cJSON_Delete(addGinseng);
encaps = NULL;
addGinseng = NULL;
return ret;
}
static int SpawnSetCommonProperties(AppSpawnMgr *content, AppSpawningCtx *property)
{
if (IsNWebSpawnMode(content)) {
return 0;
}
uint32_t len = 0;
char *processType = (char *)(GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_PROCESS_TYPE, &len));
if (processType != NULL && strcmp(processType, "gpu") == 0) {
return 0;
}
int ret = SpawnSetEncaps(content, property);
return ret;
}
static int SpawnSetProperties(AppSpawnMgr *content, AppSpawningCtx *property)
{
APPSPAWN_LOGV("Spawning: set child property");
@ -544,6 +615,7 @@ MODULE_CONSTRUCTOR(void)
AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_HIGHEST, SpawnInitSpawningEnv);
AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_COMMON + 1, SpawnSetAppEnv);
AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_HIGHEST, SpawnSetIntPermission);
AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_COMMON, SpawnSetCommonProperties);
AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_PROPERTY, SpawnSetProperties);
AddAppSpawnHook(STAGE_CHILD_POST_RELY, HOOK_PRIO_HIGHEST, SpawnComplete);
AddAppSpawnHook(STAGE_PARENT_POST_FORK, HOOK_PRIO_HIGHEST, CloseFdArgs);

View File

@ -990,8 +990,6 @@ static int ProcessChildFdCheck(int fd, AppSpawningCtx *property, int *pResult)
return 0;
}
#define MSG_EXT_NAME_MAX_DECIMAL 10
#define MSG_EXT_NAME 1
static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context)
{
AppSpawningCtx *property = (AppSpawningCtx *)context;
@ -1006,20 +1004,9 @@ static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_
// success
bool isDebuggable = CheckAppMsgFlagsSet(property, APP_FLAGS_DEBUGGABLE) == 1 ? true : false;
AppSpawnedProcess *appInfo = AddSpawnedProcess(property->pid, GetBundleName(property), isDebuggable);
uint32_t len = 0;
char *pidMaxStr = NULL;
pidMaxStr = GetAppPropertyExt(property, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, &len);
uint32_t pidMax = 0;
if (pidMaxStr != NULL && len != 0) {
pidMax = strtoul(pidMaxStr, NULL, MSG_EXT_NAME_MAX_DECIMAL);
}
#if MSG_EXT_NAME != 0
pidMax = 0;
#endif
if (appInfo) {
AppSpawnMsgDacInfo *dacInfo = GetAppProperty(property, TLV_DAC_INFO);
appInfo->uid = dacInfo != NULL ? dacInfo->uid : 0;
appInfo->max = pidMax;
appInfo->spawnStart.tv_sec = property->spawnStart.tv_sec;
appInfo->spawnStart.tv_nsec = property->spawnStart.tv_nsec;
#ifdef DEBUG_BEGETCTL_BOOT

View File

@ -287,54 +287,7 @@ HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_006, TestSize.Level0)
ASSERT_EQ(ret, 0);
}
/**
* @brief in appspawn service, max write
*
*/
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_007, TestSize.Level0)
{
int ret = -1;
AppSpawnedProcess *appInfo = nullptr;
AppSpawnContent *content = nullptr;
const char name[] = "app-test-001";
do {
char path[PATH_MAX] = {};
appInfo = CreateTestAppInfo(name);
APPSPAWN_CHECK(appInfo != nullptr, break, "Failed to create appInfo");
appInfo->max = 10; // 10 test max
ret = GetTestCGroupFilePath(appInfo, "pids.max", path, true);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
content = AppSpawnCreateContent(APPSPAWN_SOCKET_NAME, path, sizeof(path), MODE_FOR_APP_SPAWN);
APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, break);
ProcessMgrHookExecute(STAGE_SERVER_APP_ADD, content, appInfo);
// add success
ret = GetTestCGroupFilePath(appInfo, "pids.max", path, false);
APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
ret = -1;
FILE *file = fopen(path, "r");
APPSPAWN_CHECK(file != nullptr, break, "Open file fail %{public}s errno: %{public}d", path, errno);
uint32_t max = 0;
ret = -1;
while (fscanf_s(file, "%d\n", &max) == 1 && max > 0) {
APPSPAWN_LOGV("max %{public}d %{public}d", max, appInfo->max);
if (max == appInfo->max) {
ret = 0;
break;
}
}
fclose(file);
} while (0);
if (appInfo) {
free(appInfo);
}
AppSpawnDestroyContent(content);
LE_StopLoop(LE_GetDefaultLoop());
LE_CloseLoop(LE_GetDefaultLoop());
ASSERT_EQ(ret, 0);
}
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_008, TestSize.Level0)
{
int ret = -1;
AppSpawnedProcess *appInfo = nullptr;
@ -351,14 +304,14 @@ HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_008, TestSize.Level0)
ASSERT_NE(ret, 0);
}
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_009, TestSize.Level0)
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_008, TestSize.Level0)
{
pid_t pids[] = {100, 101, 102};
int ret = WriteToFile(nullptr, -1, pids, 3);
ASSERT_NE(ret, 0);
}
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_010, TestSize.Level0)
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_009, TestSize.Level0)
{
int ret = -1;
AppSpawnedProcess *appInfo = nullptr;
@ -393,7 +346,7 @@ HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_010, TestSize.Level0)
ASSERT_EQ(ret, 0);
}
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_011, TestSize.Level0)
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_010, TestSize.Level0)
{
int ret = ProcessMgrRemoveApp(nullptr, nullptr);
ASSERT_EQ(ret, -1);
@ -403,7 +356,7 @@ HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_011, TestSize.Level0)
ASSERT_EQ(ret, -1);
}
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_012, TestSize.Level0)
HWTEST_F(AppSpawnCGroupTest, App_Spawn_CGroup_011, TestSize.Level0)
{
int ret = ProcessMgrAddApp(nullptr, nullptr);
ASSERT_EQ(ret, -1);