Merge branch 'master' of gitee.com:openharmony/startup_appspawn into cloneappspawn

Signed-off-by: cheng_jinsong <chengjinsong2@huawei.com>
This commit is contained in:
cheng_jinsong 2023-05-06 06:55:36 +00:00
commit 1ff6e3eba4
20 changed files with 980 additions and 298 deletions

View File

@ -117,7 +117,14 @@ void LoadExtendLib(AppSpawnContent *content)
void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client) void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client)
{ {
APPSPAWN_LOGI("AppExecFwk::MainThread::Start"); APPSPAWN_CHECK(client != NULL && content != NULL, return, "Invalid client");
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
if (appProperty->property.code == SPAWN_NATIVE_PROCESS) {
APPSPAWN_LOGI("renderCmd %{public}s", appProperty->property.renderCmd);
(void)system(appProperty->property.renderCmd);
return;
}
APPSPAWN_LOGI("LoadExtendLib: RunChildProcessor");
#ifndef APPSPAWN_TEST #ifndef APPSPAWN_TEST
OHOS::AppExecFwk::MainThread::Start(); OHOS::AppExecFwk::MainThread::Start();
#endif #endif

View File

@ -94,8 +94,8 @@ void HandleInternetPermission(const AppSpawnClient *client)
{ {
AppSpawnClientExt *appPropertyExt = (AppSpawnClientExt *)client; AppSpawnClientExt *appPropertyExt = (AppSpawnClientExt *)client;
APPSPAWN_LOGV("HandleInternetPermission id %{public}d setAllowInternet %hhu allowInternet %hhu", APPSPAWN_LOGV("HandleInternetPermission id %{public}d setAllowInternet %hhu allowInternet %hhu",
client->id, appPropertyExt->setAllowInternet, appPropertyExt->allowInternet); client->id, appPropertyExt->property.setAllowInternet, appPropertyExt->property.allowInternet);
if (appPropertyExt->setAllowInternet == 1 && appPropertyExt->allowInternet == 0) { if (appPropertyExt->property.setAllowInternet == 1 && appPropertyExt->property.allowInternet == 0) {
DisallowInternet(); DisallowInternet();
} }
} }

View File

@ -29,8 +29,6 @@ void SetAppAccessToken(struct AppSpawnContent_ *content, AppSpawnClient *client)
void SetSelinuxCon(struct AppSpawnContent_ *content, AppSpawnClient *client); void SetSelinuxCon(struct AppSpawnContent_ *content, AppSpawnClient *client);
void LoadExtendLib(AppSpawnContent *content); void LoadExtendLib(AppSpawnContent *content);
void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client); void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client);
int GetRenderProcessTerminationStatus(int32_t pid, int *status);
void RecordRenderProcessExitedStatus(pid_t pid, int status);
void LoadAppSandboxConfig(void); void LoadAppSandboxConfig(void);
void SetUidGidFilter(struct AppSpawnContent_ *content); void SetUidGidFilter(struct AppSpawnContent_ *content);
int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client); int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client);
@ -38,6 +36,9 @@ uint32_t GetAppNamespaceFlags(const char *bundleName);
void HandleInternetPermission(const AppSpawnClient *client); void HandleInternetPermission(const AppSpawnClient *client);
void DisallowInternet(void); void DisallowInternet(void);
void RecordRenderProcessExitedStatus(pid_t pid, int status);
int GetProcessTerminationStatus(AppSpawnClient *client);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -13,7 +13,11 @@
* limitations under the License. * limitations under the License.
*/ */
#include <cerrno>
#include <dlfcn.h> #include <dlfcn.h>
#include <fcntl.h>
#include <sys/signalfd.h>
#include <sys/wait.h>
#include <algorithm> #include <algorithm>
#include <ctime> #include <ctime>
@ -66,7 +70,7 @@ void *LoadWithRelroFile(const std::string &lib, const std::string &nsName,
APPSPAWN_LOGE("LoadWithRelroFile open failed, error=[%{public}s]", strerror(tmpNo)); APPSPAWN_LOGE("LoadWithRelroFile open failed, error=[%{public}s]", strerror(tmpNo));
return nullptr; return nullptr;
} }
void *nwebReservedAddress = mmap(NULL, nwebReservedSize, PROT_NONE, void *nwebReservedAddress = mmap(nullptr, nwebReservedSize, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (nwebReservedAddress == MAP_FAILED) { if (nwebReservedAddress == MAP_FAILED) {
close(relroFd); close(relroFd);
@ -201,3 +205,40 @@ int GetRenderProcessTerminationStatus(int32_t pid, int *status)
DumpRenderProcessExitedMap(); DumpRenderProcessExitedMap();
return -1; return -1;
} }
static int GetProcessTerminationStatusInner(int32_t pid, int *status)
{
if (status == nullptr) {
return -1;
}
if (GetRenderProcessTerminationStatus(pid, status) == 0) {
// this shows that the parent process has received SIGCHLD signal.
return 0;
}
if (kill(pid, SIGKILL) != 0) {
APPSPAWN_LOGE("unable to kill render process, pid: %d ret %d", pid, errno);
}
pid_t exitPid = waitpid(pid, status, WNOHANG);
if (exitPid != pid) {
APPSPAWN_LOGE("waitpid failed, return : %d, pid: %d, status: %d", exitPid, pid, *status);
return -1;
}
return 0;
}
int GetProcessTerminationStatus(AppSpawnClient *client)
{
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
int exitStatus = 0;
int ret = GetProcessTerminationStatusInner(appProperty->property.pid, &exitStatus);
if (ret) {
exitStatus = ret;
}
APPSPAWN_LOGI("AppSpawnServer::get render process termination status, status = %d pid = %d uid %d %s %s",
exitStatus, appProperty->property.pid, appProperty->property.uid,
appProperty->property.processName, appProperty->property.bundleName);
return exitStatus;
}

View File

@ -56,16 +56,23 @@ void LoadAppSandboxConfig(void)
int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *client) int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *client)
{ {
APPSPAWN_CHECK(client != NULL, return -1, "Invalid appspwn client"); APPSPAWN_CHECK(client != NULL, return -1, "Invalid appspwn client");
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client); AppSpawnClientExt *clientExt = reinterpret_cast<AppSpawnClientExt *>(client);
appProperty->property.cloneFlags = client->cloneFlags; // no sandbox
int ret = SandboxUtils::SetAppSandboxProperty(&appProperty->property); if (clientExt->property.flags & APP_NO_SANDBOX) {
return 0;
}
// no news
if ((client->cloneFlags & CLONE_NEWNS) != CLONE_NEWNS) {
return 0;
}
int ret = SandboxUtils::SetAppSandboxProperty(client);
// free HspList // free HspList
if (appProperty->property.hspList.data != nullptr) { if (clientExt->property.hspList.data != nullptr) {
free(appProperty->property.hspList.data); free(clientExt->property.hspList.data);
appProperty->property.hspList = {}; clientExt->property.hspList = {};
} }
// for module test do not create sandbox // for module test do not create sandbox
if (strncmp(appProperty->property.bundleName, if (strncmp(clientExt->property.bundleName,
MODULE_TEST_BUNDLE_NAME.c_str(), MODULE_TEST_BUNDLE_NAME.size()) == 0) { MODULE_TEST_BUNDLE_NAME.c_str(), MODULE_TEST_BUNDLE_NAME.size()) == 0) {
return 0; return 0;
} }

View File

@ -21,4 +21,5 @@ module_output_path = "${part_name}/appspawn_l2"
declare_args() { declare_args() {
appspawn_support_nweb = true appspawn_support_nweb = true
appspawn_report_event = true appspawn_report_event = true
appspawn_test_cmd = false
} }

View File

@ -17,14 +17,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#undef _GNU_SOURCE #undef _GNU_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
#include <sched.h> #include <sched.h>
#include <string.h>
#include <time.h> #include <time.h>
#include <stdbool.h> #include <stdbool.h>
@ -89,7 +87,7 @@ int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *l
content->handleInternetPermission(client); content->handleInternetPermission(client);
} }
if ((client->cloneFlags & CLONE_NEWNS) && (content->setAppSandbox)) { if (content->setAppSandbox) {
ret = content->setAppSandbox(content, client); ret = content->setAppSandbox(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret); APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret);
return ret, "Failed to set app sandbox"); return ret, "Failed to set app sandbox");

View File

@ -38,8 +38,8 @@ extern "C" {
typedef struct AppSpawnClient_ { typedef struct AppSpawnClient_ {
uint32_t id; uint32_t id;
uint32_t flags; uint32_t flags; // Save negotiated flags
uint32_t cloneFlags; uint32_t cloneFlags; // for clone flags
} AppSpawnClient; } AppSpawnClient;
#define MAX_SOCKEYT_NAME_LEN 128 #define MAX_SOCKEYT_NAME_LEN 128

View File

@ -49,6 +49,7 @@ enum AppType {
typedef enum AppOperateType_ { typedef enum AppOperateType_ {
DEFAULT = 0, DEFAULT = 0,
GET_RENDER_TERMINATION_STATUS, GET_RENDER_TERMINATION_STATUS,
SPAWN_NATIVE_PROCESS
} AppOperateType; } AppOperateType;
#define APP_MSG_MAX_SIZE 4096 // appspawn message max size #define APP_MSG_MAX_SIZE 4096 // appspawn message max size
@ -67,6 +68,7 @@ typedef enum AppOperateType_ {
#define APP_ASANENABLED 0x10 #define APP_ASANENABLED 0x10
#define APP_ACCESS_BUNDLE_DIR 0x20 #define APP_ACCESS_BUNDLE_DIR 0x20
#define APP_NATIVEDEBUG 0X40 #define APP_NATIVEDEBUG 0X40
#define APP_NO_SANDBOX 0x80 // Do not enter sandbox
#define BITLEN32 32 #define BITLEN32 32
#define FDLEN2 2 #define FDLEN2 2
@ -79,21 +81,20 @@ typedef struct HspList_ {
} HspList; } HspList;
typedef struct AppParameter_ { typedef struct AppParameter_ {
uint32_t cloneFlags; AppOperateType code;
uint32_t flags;
int32_t pid; // query render process exited status by render process pid
uint32_t uid; // the UNIX uid that the child process setuid() to after fork() uint32_t uid; // the UNIX uid that the child process setuid() to after fork()
uint32_t gid; // the UNIX gid that the child process setgid() to after fork() uint32_t gid; // the UNIX gid that the child process setgid() to after fork()
uint32_t gidTable[APP_MAX_GIDS]; // a list of UNIX gids that the child process setgroups() to after fork()
uint32_t gidCount; // the size of gidTable uint32_t gidCount; // the size of gidTable
uint32_t gidTable[APP_MAX_GIDS]; // a list of UNIX gids that the child process setgroups() to after fork()
char processName[APP_LEN_PROC_NAME]; // process name char processName[APP_LEN_PROC_NAME]; // process name
char bundleName[APP_LEN_BUNDLE_NAME]; // bundle name char bundleName[APP_LEN_BUNDLE_NAME]; // bundle name
char soPath[APP_LEN_SO_PATH]; // so lib path char soPath[APP_LEN_SO_PATH]; // so lib path
uint32_t accessTokenId;
char apl[APP_APL_MAX_LEN]; char apl[APP_APL_MAX_LEN];
char renderCmd[APP_RENDER_CMD_MAX_LEN]; char renderCmd[APP_RENDER_CMD_MAX_LEN];
uint32_t flags; uint32_t accessTokenId;
int32_t pid; // query render process exited status by render process pid
int32_t bundleIndex; int32_t bundleIndex;
AppOperateType code;
uint64_t accessTokenIdEx; uint64_t accessTokenIdEx;
int32_t hapFlags; int32_t hapFlags;
#ifndef OHOS_LITE #ifndef OHOS_LITE

View File

@ -17,6 +17,7 @@
#include "appspawn_adapter.h" #include "appspawn_adapter.h"
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -211,7 +212,7 @@ int SetXpmRegion(struct AppSpawnContent_ *content)
APPSPAWN_CHECK_ONLY_LOG(ret != -1, "set xpm region failed: %s", strerror(errno)); APPSPAWN_CHECK_ONLY_LOG(ret != -1, "set xpm region failed: %s", strerror(errno));
close(fd); close(fd);
return ret; return 0;
} }
static int SetUidGid(struct AppSpawnContent_ *content, AppSpawnClient *client) static int SetUidGid(struct AppSpawnContent_ *content, AppSpawnClient *client)
@ -409,6 +410,34 @@ static int GetWrapBundleNameValue(struct AppSpawnContent_ *content, AppSpawnClie
} }
#endif #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");
}
len = sprintf_s(param + startLen, originLen - startLen, ":%s:%s:%s:%u:%s:%s:%u:%" PRId64 "",
appProperty->processName, appProperty->bundleName, appProperty->soPath,
appProperty->accessTokenId, appProperty->apl, appProperty->renderCmd,
appProperty->hapFlags, appProperty->accessTokenIdEx);
APPSPAWN_CHECK(len > 0 && (len < (originLen - startLen)), return -1, "Invalid to format processName");
startLen += len;
return 0;
}
static int ColdStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client) static int ColdStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client)
{ {
AppParameter *appProperty = &((AppSpawnClientExt *)client)->property; AppParameter *appProperty = &((AppSpawnClientExt *)client)->property;
@ -418,16 +447,11 @@ static int ColdStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client
APPSPAWN_CHECK(len > 0, return -1, "Invalid to format fd"); APPSPAWN_CHECK(len > 0, return -1, "Invalid to format fd");
char **argv = calloc(1, (NULL_INDEX + 1) * sizeof(char *)); char **argv = calloc(1, (NULL_INDEX + 1) * sizeof(char *));
APPSPAWN_CHECK(argv != NULL, return -1, "Failed to get argv"); APPSPAWN_CHECK(argv != NULL, return -1, "Failed to get argv");
int32_t startLen = 0;
const int32_t originLen = sizeof(AppParameter) + PARAM_BUFFER_LEN;
// param
char *param = malloc(originLen + APP_LEN_PROC_NAME);
APPSPAWN_CHECK(param != NULL, free(argv);
return -1, "Failed to malloc for param");
int ret = -1; int ret = -1;
do { 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[PARAM_INDEX] = param;
argv[0] = param + originLen; argv[0] = param + originLen;
const char *appSpawnPath = "/system/bin/appspawn"; const char *appSpawnPath = "/system/bin/appspawn";
@ -443,32 +467,13 @@ static int ColdStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client
APPSPAWN_CHECK(argv[START_INDEX] != NULL, break, "Invalid strdup"); APPSPAWN_CHECK(argv[START_INDEX] != NULL, break, "Invalid strdup");
argv[FD_INDEX] = strdup(buffer); argv[FD_INDEX] = strdup(buffer);
APPSPAWN_CHECK(argv[FD_INDEX] != NULL, break, "Invalid strdup"); APPSPAWN_CHECK(argv[FD_INDEX] != NULL, break, "Invalid strdup");
ret = EncodeAppClient(client, param, originLen);
len = sprintf_s(param + startLen, originLen - startLen, "%u:%u:%u:%u:%u", APPSPAWN_CHECK(ret == 0, break, "Failed to encode client");
((AppSpawnClientExt *)client)->client.id, ((AppSpawnClientExt *)client)->client.cloneFlags,
appProperty->uid, appProperty->gid, appProperty->gidCount);
APPSPAWN_CHECK(len > 0 && (len < (originLen - startLen)), break, "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)), break, "Invalid to format gid");
startLen += len;
}
// processName
if (appProperty->soPath[0] == '\0') {
strcpy_s(appProperty->soPath, sizeof(appProperty->soPath), "NULL");
}
len = sprintf_s(param + startLen, originLen - startLen, ":%s:%s:%s:%u:%s:%s",
appProperty->processName, appProperty->bundleName, appProperty->soPath,
appProperty->accessTokenId, appProperty->apl, appProperty->renderCmd);
APPSPAWN_CHECK(len > 0 && (len < (originLen - startLen)), break, "Invalid to format processName");
startLen += len;
len = sprintf_s(buffer, sizeof(buffer), "%u", appProperty->hspList.totalLength); len = sprintf_s(buffer, sizeof(buffer), "%u", appProperty->hspList.totalLength);
APPSPAWN_CHECK(len > 0 && len < sizeof(buffer), break, "Invalid hspList.totalLength"); APPSPAWN_CHECK(len > 0 && len < (int)sizeof(buffer), break, "Invalid hspList.totalLength");
argv[HSP_LIST_LEN_INDEX] = strdup(buffer); argv[HSP_LIST_LEN_INDEX] = strdup(buffer);
argv[HSP_LIST_INDEX] = appProperty->hspList.data; argv[HSP_LIST_INDEX] = appProperty->hspList.data;
ret = 0; ret = 0;
} while (0); } while (0);
@ -483,90 +488,94 @@ static int ColdStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client
APPSPAWN_LOGE("Failed to execv, errno = %{public}d", errno); APPSPAWN_LOGE("Failed to execv, errno = %{public}d", errno);
} }
} }
argv[0] = NULL;
Free(argv, &appProperty->hspList); Free(argv, &appProperty->hspList);
return ret; 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) int GetAppSpawnClientFromArg(int argc, char *const argv[], AppSpawnClientExt *client)
{ {
APPSPAWN_CHECK(argv != NULL && argc > PARAM_INDEX, return -1, "Invalid argv argc %{public}d", argc); APPSPAWN_CHECK(argv != NULL && argc > PARAM_INDEX, return -1, "Invalid argv argc %{public}d", argc);
client->fd[1] = atoi(argv[FD_INDEX]); client->fd[1] = atoi(argv[FD_INDEX]);
APPSPAWN_LOGV("GetAppSpawnClientFromArg %{public}s ", argv[PARAM_INDEX]); APPSPAWN_LOGV("GetAppSpawnClientFromArg %{public}s ", argv[PARAM_INDEX]);
char *end = NULL;
char *start = strtok_r(argv[PARAM_INDEX], ":", &end);
// clientid // clientid
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get client id"); char *end = NULL;
client->client.id = atoi(start); int ret = GetUInt32FromArg(argv[PARAM_INDEX], &end, &client->client.id);
start = strtok_r(NULL, ":", &end); ret += GetUInt32FromArg(NULL, &end, &client->client.flags);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get client cloneFlags"); ret += GetUInt32FromArg(NULL, &end, &client->client.cloneFlags);
client->client.cloneFlags = atoi(start); ret += GetUInt32FromArg(NULL, &end, &client->property.code);
start = strtok_r(NULL, ":", &end); ret += GetUInt32FromArg(NULL, &end, &client->property.flags);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get uid"); ret += GetUInt32FromArg(NULL, &end, &client->property.uid);
client->property.uid = atoi(start); ret += GetUInt32FromArg(NULL, &end, &client->property.gid);
start = strtok_r(NULL, ":", &end); uint32_t value = 0;
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get gid"); ret += GetUInt32FromArg(NULL, &end, &value);
client->property.gid = atoi(start); client->property.setAllowInternet = (uint8_t)value;
ret += GetUInt32FromArg(NULL, &end, &value);
// gidCount client->property.allowInternet = (uint8_t)value;
start = strtok_r(NULL, ":", &end); ret += GetUInt32FromArg(NULL, &end, &client->property.gidCount);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get gidCount"); APPSPAWN_CHECK(ret == 0, return -1, "Failed to get client info");
client->property.gidCount = atoi(start);
for (uint32_t i = 0; i < client->property.gidCount; i++) { for (uint32_t i = 0; i < client->property.gidCount; i++) {
start = strtok_r(NULL, ":", &end); ret = GetUInt32FromArg(NULL, &end, &client->property.gidTable[i]);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get gidTable"); APPSPAWN_CHECK(ret == 0, return -1, "Failed to get gidTable");
client->property.gidTable[i] = atoi(start);
} }
// processname // processname
start = strtok_r(NULL, ":", &end); ret = GetStringFromArg(NULL, &end, client->property.processName, sizeof(client->property.processName));
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get processName"); ret += GetStringFromArg(NULL, &end, client->property.bundleName, sizeof(client->property.bundleName));
int ret = strcpy_s(client->property.processName, sizeof(client->property.processName), start); ret += GetStringFromArg(NULL, &end, client->property.soPath, sizeof(client->property.soPath));
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy processName"); APPSPAWN_CHECK(ret == 0, return -1, "Failed to get process name");
start = strtok_r(NULL, ":", &end);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get bundleName");
ret = strcpy_s(client->property.bundleName, sizeof(client->property.bundleName), start);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy bundleName");
start = strtok_r(NULL, ":", &end);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get soPath");
if (strcmp(start, "NULL")) {
ret = strcpy_s(client->property.soPath, sizeof(client->property.soPath), start);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy soPath");
} else {
client->property.soPath[0] = '\0';
}
// accesstoken // access token
start = strtok_r(NULL, ":", &end); ret = GetUInt32FromArg(NULL, &end, &client->property.accessTokenId);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get accessTokenId"); ret += GetStringFromArg(NULL, &end, client->property.apl, sizeof(client->property.apl));
client->property.accessTokenId = atoi(start); ret += GetStringFromArg(NULL, &end, client->property.renderCmd, sizeof(client->property.renderCmd));
start = strtok_r(NULL, ":", &end); ret += GetUInt32FromArg(NULL, &end, &value);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get apl"); client->property.hapFlags = (int32_t)value;
ret = strcpy_s(client->property.apl, sizeof(client->property.apl), start); ret += GetUInt64FromArg(NULL, &end, &client->property.accessTokenIdEx);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy apl"); APPSPAWN_CHECK(ret == 0, return -1, "Failed to access token info");
start = strtok_r(NULL, ":", &end);
APPSPAWN_CHECK(start != NULL, return -1, "Failed to get renderCmd");
ret = strcpy_s(client->property.renderCmd, sizeof(client->property.renderCmd), start);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy renderCmd");
if (argc > HSP_LIST_LEN_INDEX) { client->property.hspList.totalLength = 0;
APPSPAWN_CHECK(argv[HSP_LIST_LEN_INDEX] != NULL, return -1, "Invalid HspList length");
client->property.hspList.totalLength = atoi(argv[HSP_LIST_LEN_INDEX]);
} else {
client->property.hspList.totalLength = 0;
}
client->property.hspList.data = NULL; client->property.hspList.data = NULL;
ret = -1;
if (client->property.hspList.totalLength > 0) { if (argc > HSP_LIST_LEN_INDEX && argv[HSP_LIST_LEN_INDEX] != NULL) {
APPSPAWN_CHECK(argc > HSP_LIST_INDEX && argv[HSP_LIST_INDEX] != NULL, return -1, "Invalid argv for HspList"); client->property.hspList.totalLength = atoi(argv[HSP_LIST_LEN_INDEX]);
APPSPAWN_CHECK_ONLY_EXPER(client->property.hspList.totalLength != 0, return 0);
APPSPAWN_CHECK(argc > HSP_LIST_INDEX && argv[HSP_LIST_INDEX] != NULL, return -1, "Invalid hspList.data");
client->property.hspList.data = malloc(client->property.hspList.totalLength); client->property.hspList.data = malloc(client->property.hspList.totalLength);
APPSPAWN_CHECK(client->property.hspList.data != NULL, return -1, "Failed to malloc hspList.data"); APPSPAWN_CHECK(client->property.hspList.data != NULL, return -1, "Failed to malloc hspList.data");
ret = strcpy_s(client->property.hspList.data, client->property.hspList.totalLength, argv[HSP_LIST_INDEX]); ret = strcpy_s(client->property.hspList.data, client->property.hspList.totalLength, argv[HSP_LIST_INDEX]);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy hspList.data"); APPSPAWN_CHECK(ret == 0, return -1, "Failed to strcpy hspList.data");
} }
return ret;
return 0;
} }
void SetContentFunction(AppSpawnContent *content) void SetContentFunction(AppSpawnContent *content)

View File

@ -100,12 +100,17 @@ APPSPAWN_STATIC void ProcessTimer(const TimerHandle taskHandle, void *context)
LE_StopLoop(LE_GetDefaultLoop()); LE_StopLoop(LE_GetDefaultLoop());
} }
static void RemoveAppInfo(pid_t pid) static AppInfo *GetAppInfo(pid_t pid)
{ {
HashNode *node = OH_HashMapGet(g_appSpawnContent->appMap, (const void *)&pid); HashNode *node = OH_HashMapGet(g_appSpawnContent->appMap, (const void *)&pid);
APPSPAWN_CHECK(node != NULL, return, "Invalid node %{public}d", pid); APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return NULL);
AppInfo *appInfo = HASHMAP_ENTRY(node, AppInfo, node); return HASHMAP_ENTRY(node, AppInfo, node);
APPSPAWN_CHECK(appInfo != NULL, return, "Invalid node %{public}d", pid); }
static void RemoveAppInfo(pid_t pid)
{
AppInfo *appInfo = GetAppInfo(pid);
APPSPAWN_CHECK(appInfo != NULL, return, "Can not find app info for %{public}d", pid);
OH_HashMapRemove(g_appSpawnContent->appMap, (const void *)&pid); OH_HashMapRemove(g_appSpawnContent->appMap, (const void *)&pid);
free(appInfo); free(appInfo);
if ((g_appSpawnContent->flags & FLAGS_ON_DEMAND) != FLAGS_ON_DEMAND) { if ((g_appSpawnContent->flags & FLAGS_ON_DEMAND) != FLAGS_ON_DEMAND) {
@ -129,7 +134,16 @@ static void KillProcess(const HashNode *node, const void *context)
static void OnClose(const TaskHandle taskHandle) static void OnClose(const TaskHandle taskHandle)
{ {
UNUSED(taskHandle); AppSpawnClientExt *client = (AppSpawnClientExt *)LE_GetUserData(taskHandle);
APPSPAWN_CHECK(client != NULL, return, "Invalid client");
APPSPAWN_LOGI("OnClose %{public}d processName = %{public}s",
client->client.id, client->property.processName);
if (client->property.hspList.data != NULL) {
free(client->property.hspList.data);
client->property.hspList.totalLength = 0;
client->property.hspList.savedLength = 0;
client->property.hspList.data = NULL;
}
} }
static void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle) static void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle)
@ -155,14 +169,10 @@ static int SendResponse(AppSpawnClientExt *client, const char *buff, size_t buff
return LE_Send(LE_GetDefaultLoop(), client->stream, handle, buffSize); return LE_Send(LE_GetDefaultLoop(), client->stream, handle, buffSize);
} }
#ifdef REPORT_EVENT static void HandleDiedPid(pid_t pid, uid_t uid, int status)
static void PrintProcessExitInfo(pid_t pid, uid_t uid, int status)
{ {
HashNode *node = OH_HashMapGet(g_appSpawnContent->appMap, (const void *)&pid); AppInfo *appInfo = GetAppInfo(pid);
APPSPAWN_CHECK(node != NULL, return, "Handle SIGCHLD from pid:%{public}d status:%{public}d", pid, status); APPSPAWN_CHECK(appInfo != NULL, return, "Can not find app info for %{public}d", pid);
AppInfo *appInfo = HASHMAP_ENTRY(node, AppInfo, node);
APPSPAWN_CHECK(appInfo != NULL, return, "Handle SIGCHLD from pid:%{public}d status:%{public}d", pid, status);
if (WIFSIGNALED(status)) { if (WIFSIGNALED(status)) {
APPSPAWN_LOGW("%{public}s with pid %{public}d exit with signal:%{public}d", APPSPAWN_LOGW("%{public}s with pid %{public}d exit with signal:%{public}d",
appInfo->name, pid, WTERMSIG(status)); appInfo->name, pid, WTERMSIG(status));
@ -172,21 +182,17 @@ static void PrintProcessExitInfo(pid_t pid, uid_t uid, int status)
appInfo->name, pid, WEXITSTATUS(status)); appInfo->name, pid, WEXITSTATUS(status));
} }
#ifdef REPORT_EVENT
ReportProcessExitInfo(appInfo->name, pid, uid, status); ReportProcessExitInfo(appInfo->name, pid, uid, status);
}
#endif #endif
static void HandleDiedPid(pid_t pid, uid_t uid, int status)
{
APPSPAWN_LOGI("SignalHandler pid %{public}d status %{public}d", pid, status);
#ifdef REPORT_EVENT
PrintProcessExitInfo(pid, uid, status);
#endif
#ifdef NWEB_SPAWN #ifdef NWEB_SPAWN
// nwebspawn will invoke waitpid and remove appinfo at GetProcessTerminationStatusInner when // nwebspawn will invoke waitpid and remove appinfo at GetProcessTerminationStatusInner when
// GetProcessTerminationStatusInner is called before the parent process receives the SIGCHLD signal. // GetProcessTerminationStatusInner is called before the parent process receives the SIGCHLD signal.
RecordRenderProcessExitedStatus(pid, status); RecordRenderProcessExitedStatus(pid, status);
#endif #endif
// delete app info
RemoveAppInfo(pid); RemoveAppInfo(pid);
} }
@ -276,67 +282,6 @@ static void CheckColdAppEnabled(AppSpawnClientExt *appProperty)
} }
} }
#ifdef NWEB_SPAWN
static int GetProcessTerminationStatusInner(int32_t pid, int *status)
{
if (status == NULL) {
return -1;
}
if (GetRenderProcessTerminationStatus(pid, status) == 0) {
// this shows that the parent process has received SIGCHLD signal.
return 0;
}
if (kill(pid, SIGKILL) != 0) {
APPSPAWN_LOGE("unable to kill render process, pid: %{public}d", pid);
}
pid_t exitPid = waitpid(pid, status, WNOHANG);
if (exitPid != pid) {
APPSPAWN_LOGE("waitpid failed, return : %{public}d, pid: %{public}d, status: %{public}d",
exitPid, pid, *status);
return -1;
}
RemoveAppInfo(pid);
return 0;
}
static void GetProcessTerminationStatus(AppSpawnClientExt *appProperty)
{
int exitStatus = 0;
int ret = GetProcessTerminationStatusInner(appProperty->property.pid, &exitStatus);
if (ret) {
SendResponse(appProperty, (char *)&ret, sizeof(ret));
} else {
SendResponse(appProperty, (char *)&exitStatus, sizeof(exitStatus));
}
APPSPAWN_LOGI("AppSpawnServer::get render process termination status, \
status = %{public}d pid = %{public}d uid %{public}d %{public}s %{public}s",
exitStatus, appProperty->property.pid, appProperty->property.uid,
appProperty->property.processName, appProperty->property.bundleName);
}
#endif
static void SetInternetPermission(AppSpawnClientExt *appProperty)
{
if (appProperty->property.setAllowInternet == 1 && appProperty->property.allowInternet == 0) {
appProperty->setAllowInternet = 1;
appProperty->allowInternet = 0;
}
}
static void FreeHspList(AppSpawnClientExt *client)
{
if (client != NULL && client->property.hspList.data != NULL) {
free(client->property.hspList.data);
client->property.hspList.totalLength = 0;
client->property.hspList.savedLength = 0;
client->property.hspList.data = NULL;
}
}
APPSPAWN_STATIC bool ReceiveRequestData(const TaskHandle taskHandle, AppSpawnClientExt *client, APPSPAWN_STATIC bool ReceiveRequestData(const TaskHandle taskHandle, AppSpawnClientExt *client,
const uint8_t *buffer, uint32_t buffLen) const uint8_t *buffer, uint32_t buffLen)
{ {
@ -375,8 +320,8 @@ APPSPAWN_STATIC bool ReceiveRequestData(const TaskHandle taskHandle, AppSpawnCli
HspList *hspList = &client->property.hspList; HspList *hspList = &client->property.hspList;
if (hspList->savedLength == 0) { if (hspList->savedLength == 0) {
hspList->data = (char *)malloc(hspList->totalLength); hspList->data = (char *)malloc(hspList->totalLength);
APPSPAWN_CHECK(hspList->data != NULL, FreeHspList(client); LE_CloseTask(LE_GetDefaultLoop(), taskHandle); APPSPAWN_CHECK(hspList->data != NULL, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return false, "ReceiveRequestData: malloc hspList failed"); return false, "ReceiveRequestData: malloc hspList failed %{public}u", hspList->totalLength);
} }
uint32_t saved = hspList->savedLength; uint32_t saved = hspList->savedLength;
@ -385,12 +330,12 @@ APPSPAWN_STATIC bool ReceiveRequestData(const TaskHandle taskHandle, AppSpawnCli
APPSPAWN_LOGV("Receiving hspList: (%{public}u saved + %{public}u incoming) / %{public}u total", APPSPAWN_LOGV("Receiving hspList: (%{public}u saved + %{public}u incoming) / %{public}u total",
saved, buffLen, total); saved, buffLen, total);
APPSPAWN_CHECK((total - saved) >= buffLen, FreeHspList(client); LE_CloseTask(LE_GetDefaultLoop(), taskHandle); APPSPAWN_CHECK((total - saved) >= buffLen, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return false, "ReceiveRequestData: too many data for hspList %{public}u ", buffLen); return false, "ReceiveRequestData: too many data for hspList %{public}u ", buffLen);
int ret = memcpy_s(data + saved, buffLen, buffer, buffLen); int ret = memcpy_s(data + saved, buffLen, buffer, buffLen);
APPSPAWN_CHECK(ret == 0, FreeHspList(client); LE_CloseTask(LE_GetDefaultLoop(), taskHandle); APPSPAWN_CHECK(ret == 0, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return false, "ReceiveRequestData: memcpy hspList failed"); return false, "ReceiveRequestData: memcpy hspList failed");
hspList->savedLength += buffLen; hspList->savedLength += buffLen;
if (hspList->savedLength < hspList->totalLength) { if (hspList->savedLength < hspList->totalLength) {
@ -401,6 +346,38 @@ APPSPAWN_STATIC bool ReceiveRequestData(const TaskHandle taskHandle, AppSpawnCli
return true; return true;
} }
static int HandleMessage(AppSpawnClientExt *appProperty)
{
// create pipe
if (pipe(appProperty->fd) == -1) {
APPSPAWN_LOGE("create pipe fail, errno = %{public}d", errno);
return -1;
}
fcntl(appProperty->fd[0], F_SETFL, O_NONBLOCK);
/* Clone support only one parameter, so need to package application parameters */
AppSandboxArg sandboxArg = { 0 };
sandboxArg.content = &g_appSpawnContent->content;
sandboxArg.client = &appProperty->client;
sandboxArg.client->cloneFlags = GetAppNamespaceFlags(appProperty->property.bundleName);
SHOW_CLIENT("Receive client message ", appProperty);
int result = AppSpawnProcessMsg(&sandboxArg, &appProperty->pid);
if (result == 0) { // wait child process result
result = WaitChild(appProperty->fd[0], appProperty->pid, appProperty);
}
close(appProperty->fd[0]);
close(appProperty->fd[1]);
APPSPAWN_LOGI("child process %{public}s %{public}s pid %{public}d",
appProperty->property.processName, (result == 0) ? "success" : "fail", appProperty->pid);
if (result == 0) {
AddAppInfo(appProperty->pid, appProperty->property.processName);
SendResponse(appProperty, (char *)&appProperty->pid, sizeof(appProperty->pid));
} else {
SendResponse(appProperty, (char *)&result, sizeof(result));
}
return 0;
}
static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen) static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen)
{ {
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)LE_GetUserData(taskHandle); AppSpawnClientExt *appProperty = (AppSpawnClientExt *)LE_GetUserData(taskHandle);
@ -414,56 +391,29 @@ static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer,
#ifdef NWEB_SPAWN #ifdef NWEB_SPAWN
// get render process termination status, only nwebspawn need this logic. // get render process termination status, only nwebspawn need this logic.
if (appProperty->property.code == GET_RENDER_TERMINATION_STATUS) { if (appProperty->property.code == GET_RENDER_TERMINATION_STATUS) {
GetProcessTerminationStatus(appProperty); int ret = GetProcessTerminationStatus(&appProperty->client);
RemoveAppInfo(appProperty->property.pid);
SendResponse(appProperty, (char *)&ret, sizeof(ret));
return; return;
} }
#endif #endif
APPSPAWN_CHECK(appProperty->property.gidCount <= APP_MAX_GIDS && strlen(appProperty->property.processName) > 0, APPSPAWN_CHECK(appProperty->property.gidCount <= APP_MAX_GIDS && strlen(appProperty->property.processName) > 0,
LE_CloseTask(LE_GetDefaultLoop(), taskHandle); FreeHspList(appProperty); LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return, "Invalid property %{public}u", appProperty->property.gidCount); return, "Invalid property %{public}u", appProperty->property.gidCount);
// special handle bundle name medialibrary and scanner // special handle bundle name medialibrary and scanner
HandleSpecial(appProperty); HandleSpecial(appProperty);
SetInternetPermission(appProperty);
if (g_appSpawnContent->timer != NULL) { if (g_appSpawnContent->timer != NULL) {
LE_StopTimer(LE_GetDefaultLoop(), g_appSpawnContent->timer); LE_StopTimer(LE_GetDefaultLoop(), g_appSpawnContent->timer);
g_appSpawnContent->timer = NULL; g_appSpawnContent->timer = NULL;
} }
appProperty->pid = 0; appProperty->pid = 0;
CheckColdAppEnabled(appProperty); CheckColdAppEnabled(appProperty);
// create pipe for commication from child int ret = HandleMessage(appProperty);
if (pipe(appProperty->fd) == -1) { if (ret != 0) {
APPSPAWN_LOGE("create pipe fail, errno = %{public}d", errno);
LE_CloseTask(LE_GetDefaultLoop(), taskHandle); LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
FreeHspList(appProperty);
return;
} }
APPSPAWN_LOGI("Client.id %{public}d appProperty %{public}d processname %{public}s buffLen %{public}d flags 0x%x",
appProperty->client.id, appProperty->property.uid, appProperty->property.processName,
buffLen, appProperty->property.flags);
fcntl(appProperty->fd[0], F_SETFL, O_NONBLOCK);
/* Clone support only one parameter, so need to package application parameters */
AppSandboxArg sandboxArg = { 0 };
sandboxArg.content = &g_appSpawnContent->content;
sandboxArg.client = &appProperty->client;
sandboxArg.client->cloneFlags = GetAppNamespaceFlags(appProperty->property.bundleName);
int result = AppSpawnProcessMsg(&sandboxArg, &appProperty->pid);
if (result == 0) { // wait child process result
result = WaitChild(appProperty->fd[0], appProperty->pid, appProperty);
}
close(appProperty->fd[0]);
close(appProperty->fd[1]);
APPSPAWN_LOGI("child process %{public}s %{public}s pid %{public}d",
appProperty->property.processName, (result == 0) ? "success" : "fail", appProperty->pid);
if (result == 0) {
AddAppInfo(appProperty->pid, appProperty->property.processName);
SendResponse(appProperty, (char *)&appProperty->pid, sizeof(appProperty->pid));
} else {
SendResponse(appProperty, (char *)&result, sizeof(result));
}
FreeHspList(appProperty);
} }
APPSPAWN_STATIC TaskHandle AcceptClient(const LoopHandle loopHandle, const TaskHandle server, uint32_t flags) APPSPAWN_STATIC TaskHandle AcceptClient(const LoopHandle loopHandle, const TaskHandle server, uint32_t flags)
@ -497,8 +447,6 @@ APPSPAWN_STATIC TaskHandle AcceptClient(const LoopHandle loopHandle, const TaskH
client->stream = stream; client->stream = stream;
client->client.id = ++clientId; client->client.id = ++clientId;
client->client.flags = 0; client->client.flags = 0;
client->setAllowInternet = 0;
client->allowInternet = 1;
client->property.hspList.totalLength = 0; client->property.hspList.totalLength = 0;
client->property.hspList.savedLength = 0; client->property.hspList.savedLength = 0;
client->property.hspList.data = NULL; client->property.hspList.data = NULL;
@ -558,9 +506,8 @@ void AppSpawnColdRun(AppSpawnContent *content, int argc, char *const argv[])
int ret = GetAppSpawnClientFromArg(argc, argv, client); int ret = GetAppSpawnClientFromArg(argc, argv, client);
APPSPAWN_CHECK(ret == 0, free(client); APPSPAWN_CHECK(ret == 0, free(client);
return, "Failed to get client from arg"); return, "Failed to get client from arg");
APPSPAWN_LOGI("Cold running %{public}d processName %{public}s %{public}u ", client->client.flags &= ~ APP_COLD_START;
getpid(), client->property.processName, content->longProcNameLen); SHOW_CLIENT("Cold running", client);
ret = DoStartApp(content, &client->client, content->longProcName, content->longProcNameLen); ret = DoStartApp(content, &client->client, content->longProcName, content->longProcNameLen);
if (ret == 0 && content->runChildProcessor != NULL) { if (ret == 0 && content->runChildProcessor != NULL) {
content->runChildProcessor(content, &client->client); content->runChildProcessor(content, &client->client);

View File

@ -51,10 +51,6 @@ typedef struct {
int32_t fd[2]; // 2 fd count int32_t fd[2]; // 2 fd count
AppParameter property; AppParameter property;
pid_t pid; pid_t pid;
uint8_t setAllowInternet;
uint8_t allowInternet;
uint8_t reserved1;
uint8_t reserved2;
} AppSpawnClientExt; } AppSpawnClientExt;
typedef struct { typedef struct {
@ -75,6 +71,23 @@ typedef struct {
void SetContentFunction(AppSpawnContent *content); void SetContentFunction(AppSpawnContent *content);
void AppSpawnColdRun(AppSpawnContent *content, int argc, char *const argv[]); void AppSpawnColdRun(AppSpawnContent *content, int argc, char *const argv[]);
int GetAppSpawnClientFromArg(int argc, char *const argv[], AppSpawnClientExt *client); 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", \
(clientExt)->property.apl, (clientExt)->property.renderCmd); \
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)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -14,10 +14,33 @@
import("//base/startup/appspawn/appspawn.gni") import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni") import("//build/test.gni")
ohos_executable("AppSpawnTest") {
sources = [ "${appspawn_path}/test/moduletest/appspawn_test_cmd.cpp" ]
include_dirs = [
"//commonlibrary/c_utils/base/include",
"//third_party/zlib/contrib/minizip",
"//third_party/zlib",
]
configs = [ "${appspawn_path}:appspawn_config" ]
deps = [ "${appspawn_path}/interfaces/innerkits:appspawn_socket_client" ]
external_deps = [
"c_utils:utils",
"hiviewdfx_hilog_native:libhilog",
"init:libbegetutil",
]
}
ohos_moduletest("AppSpawnModuleTest") { ohos_moduletest("AppSpawnModuleTest") {
module_out_path = "${module_output_path}" module_out_path = "${module_output_path}"
sources = [ "${appspawn_path}/test/moduletest/appspawn_module_test.cpp" ] sources = [
"${appspawn_path}/test/moduletest/appspawn_client_test.cpp",
"${appspawn_path}/test/moduletest/appspawn_module_test.cpp",
]
include_dirs = [ include_dirs = [
"//commonlibrary/c_utils/base/include", "//commonlibrary/c_utils/base/include",
@ -40,6 +63,7 @@ ohos_moduletest("AppSpawnModuleTest") {
"bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_base",
"c_utils:utils", "c_utils:utils",
"hiviewdfx_hilog_native:libhilog", "hiviewdfx_hilog_native:libhilog",
"init:libbegetutil",
] ]
} }
@ -47,4 +71,7 @@ group("moduletest") {
testonly = true testonly = true
deps = [ ":AppSpawnModuleTest" ] deps = [ ":AppSpawnModuleTest" ]
if (appspawn_test_cmd) {
deps += [ ":AppSpawnTest" ]
}
} }

View File

@ -0,0 +1,341 @@
/*
* 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_test_client.h"
#include "gtest/gtest.h"
#include "securec.h"
using namespace testing::ext;
using namespace OHOS;
namespace OHOS {
namespace AppSpawn {
class AppSpawnClientTest : public testing::Test, public AppSpawnTestClient {
public:
static void SetUpTestCase() {}
static void TearDownTestCase() {}
void SetUp() {}
void TearDown() {}
};
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_1, TestSize.Level0)
{
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
request.code = SPAWN_NATIVE_PROCESS;
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_EQ(ret, 0);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_2, TestSize.Level0)
{
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
// more gid
request.gidCount = APP_MAX_GIDS + 1;
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_NE(ret, 0);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
}
// has hsp data,read json from etc
static const std::string g_jsonStr = "{ "
"\"bundles\": [{ "
"\"name\":\"test_service\", "
"\"path\":[\"/data/init_ut/test_service\"], "
"\"importance\":-20, "
"\"uid\":\"system\", "
"\"writepid\":[\"/dev/test_service\"], "
"\"console\":1, "
"\"caps\":[\"TEST_ERR\"], "
"\"gid\":[\"system\"], "
"\"critical\":1 "
"}], "
"\"modules\": [{ "
"\"name\":\"test_service\", "
"\"path\":[\"/data/init_ut/test_service\"], "
"\"importance\":-20, "
"\"uid\":\"system\", "
"\"writepid\":[\"/dev/test_service\"], "
"\"console\":1, "
"\"caps\":[\"TEST_ERR\"], "
"\"gid\":[\"system\"], "
"\"critical\":1 "
"}], "
" \"versions\": [{ "
"\"name\":\"test_service\", "
"\"path\":[\"/data/init_ut/test_service\"], "
"\"importance\":-20, "
"\"uid\":\"system\", "
"\"writepid\":[\"/dev/test_service\"], "
"\"console\":1, "
"\"caps\":[\"TEST_ERR\"], "
"\"gid\":[\"system\"], "
"\"critical\":1 "
"}] "
"}";
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_3, TestSize.Level0)
{
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_3");
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
printf("AppSpawn_Client_AppSpawn_3 hsp %zu %s \n", g_jsonStr.size(), g_jsonStr.c_str());
request.hspList.totalLength = g_jsonStr.size();
std::vector<char *> data(sizeof(request) + g_jsonStr.size());
memcpy_s(data.data(), sizeof(request), &request, sizeof(request));
memcpy_s(data.data() + sizeof(request), g_jsonStr.size(), g_jsonStr.data(), g_jsonStr.size());
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(data.data()), data.size());
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_4, TestSize.Level0)
{
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_4");
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
// has hsp data,read json from etc
const std::string jsonPath("/system/etc/sandbox/system-sandbox.json");
std::ifstream jsonFileStream;
jsonFileStream.open(jsonPath.c_str(), std::ios::in);
EXPECT_EQ(jsonFileStream.is_open() == true, 1);
std::vector<char> buf;
char ch;
while (jsonFileStream.get(ch)) {
buf.insert(buf.end(), ch);
}
jsonFileStream.close();
printf("AppSpawn_Client_AppSpawn_4 hsp %zu \n", buf.size());
request.hspList.totalLength = buf.size();
std::vector<char *> data(sizeof(request) + buf.size());
memcpy_s(data.data(), sizeof(request), &request, sizeof(request));
memcpy_s(data.data() + sizeof(request), buf.size(), buf.data(), buf.size());
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(data.data()), data.size());
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_5, TestSize.Level0)
{
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_5 start");
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
// more hsp data,read json from etc
const std::string jsonPath("/system/etc/sandbox/appdata-sandbox.json");
std::ifstream jsonFileStream;
jsonFileStream.open(jsonPath.c_str(), std::ios::in);
EXPECT_EQ(jsonFileStream.is_open() == true, 1);
std::vector<char> buf;
char ch;
while (jsonFileStream.get(ch)) {
buf.insert(buf.end(), ch);
}
jsonFileStream.close();
request.hspList.totalLength = buf.size();
std::vector<char *> data(sizeof(request) + buf.size());
memcpy_s(data.data(), sizeof(request), &request, sizeof(request));
memcpy_s(data.data() + sizeof(request), buf.size(), buf.data(), buf.size());
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(data.data()), data.size());
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_5 end");
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_6, TestSize.Level0)
{
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_6 start");
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
SetParameter("startup.appspawn.cold.boot", "1");
SetParameter("persist.appspawn.client.timeout", "10");
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > /data/aaa.txt");
request.flags = APP_COLD_BOOT;
request.code = SPAWN_NATIVE_PROCESS;
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_EQ(ret, 0);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_6 end");
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_7, TestSize.Level0)
{
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_7 start");
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
SetParameter("startup.appspawn.cold.boot", "1");
SetParameter("persist.appspawn.client.timeout", "10");
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.2222222222222clock", "ls -l > /data/aaa.txt");
request.flags = APP_COLD_BOOT | APP_NO_SANDBOX;
request.code = SPAWN_NATIVE_PROCESS;
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_EQ(ret, 0);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_7 end");
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_AppSpawn_8, TestSize.Level0)
{
// for clod start, but not in sandbox
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_8 start");
int ret = ClientCreateSocket("/dev/unix/socket/AppSpawn");
EXPECT_EQ(ret, 0);
SetParameter("startup.appspawn.cold.boot", "1");
SetParameter("persist.appspawn.client.timeout", "10");
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.2222222222222clock", "ls -l > /data/aaa.txt");
request.flags = APP_COLD_BOOT | APP_NO_SANDBOX;
request.code = SPAWN_NATIVE_PROCESS;
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_EQ(ret, 0);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
APPSPAWN_LOGI("AppSpawn_Client_AppSpawn_8 end");
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_NWebSpawn_1, TestSize.Level0)
{
int ret = ClientCreateSocket("/dev/unix/socket/NWebSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_EQ(ret, 0);
if (pid > 0) {
kill(pid, SIGKILL);
}
// close client
ClientClose();
}
HWTEST_F(AppSpawnClientTest, AppSpawn_Client_NWebSpawn_2, TestSize.Level0)
{
int ret = ClientCreateSocket("/dev/unix/socket/NWebSpawn");
EXPECT_EQ(ret, 0);
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
ClientFillMsg(&request, "ohos.samples.clock", "ls -l > aaa.txt");
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
pid_t pid = 0;
ret = ClientRecvMsg(pid);
EXPECT_EQ(ret, 0);
printf("AppSpawn_Client_NWebSpawn_2 pid %d \n", pid);
request.code = GET_RENDER_TERMINATION_STATUS;
request.pid = pid;
ret = ClientSendMsg(reinterpret_cast<const uint8_t *>(&request), sizeof(request));
EXPECT_EQ(ret, 0);
ret = ClientRecvMsg(pid);
printf("AppSpawn_Client_NWebSpawn_2 result %d \n", ret);
// close client
ClientClose();
}
} // namespace AppSpawn
} // namespace OHOS

View File

@ -0,0 +1,123 @@
/*
* 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 APPSPAWN_CLIENT_TEST_H
#define APPSPAWN_CLIENT_TEST_H
#include <sstream>
#include <fstream>
#include <fcntl.h>
#include <unistd.h>
#include <cstdio>
#include <vector>
#include "client_socket.h"
#include "appspawn_server.h"
#include "parameter.h"
namespace OHOS {
namespace AppSpawn {
class AppSpawnTestClient {
public:
AppSpawnTestClient() = default;
~AppSpawnTestClient() = default;
int ClientCreateSocket(std::string path = "/dev/unix/socket/NWebSpawn")
{
// close old socket and create new
if (clientSocket_ != nullptr) {
clientSocket_->CloseClient();
clientSocket_ = nullptr;
}
clientSocket_ = std::make_shared<ClientSocket>(path);
APPSPAWN_CHECK(clientSocket_ != nullptr, return -1, "Failed to create client for path %s", path.c_str());
int ret = clientSocket_->CreateClient();
APPSPAWN_CHECK(ret == 0, return -1, "Failed to create socket for path %ss", path.c_str());
ret = clientSocket_->ConnectSocket();
APPSPAWN_CHECK(ret == 0, return -1, "Failed to connect to server %ss", path.c_str());
return 0;
}
void ClientClose()
{
if (clientSocket_ != nullptr) {
clientSocket_->CloseClient();
clientSocket_ = nullptr;
}
}
int ClientSendMsg(const uint8_t *buf, int len)
{
int curr = 0;
int real = 0;
uint8_t *buffer = const_cast<uint8_t *>(buf);
const int maxLen = 5 * 1024;
while (curr < len) {
if ((len - curr) > maxLen) {
real = maxLen;
} else {
real = len - curr;
}
if (clientSocket_->WriteSocketMessage(static_cast<const void *>(buffer + curr), real) != real) {
return -1;
}
curr += real;
}
return 0;
}
int ClientRecvMsg(pid_t &pid)
{
pid = -1;
std::vector<uint8_t> data(sizeof(pid_t)); // 4 pid size
if (clientSocket_->ReadSocketMessage(data.data(), data.size()) == sizeof(pid_t)) {
int ret = *(reinterpret_cast<int *>(data.data()));
if (ret < 0) {
return ret;
}
pid = static_cast<pid_t>(ret);
return 0;
}
return -1;
}
void ClientFillMsg(AppParameter *request, const std::string &processName, const std::string &cmd)
{
request->code = DEFAULT;
request->flags = 0;
request->uid = 20010033; // 20010033 test uid
request->gid = 20010033; // 20010033 test gid
request->gidCount = 0;
request->accessTokenId = 0x200a509d; // 0x200a509d test token id
request->accessTokenIdEx = 0x4832514205; // 0x4832514205 test token id
request->allowInternet = 1;
request->hspList.totalLength = 0;
request->hspList.savedLength = 0;
request->hspList.data = nullptr;
int ret = strcpy_s(request->apl, sizeof(request->processName), processName.c_str());
ret += strcpy_s(request->processName, sizeof(request->processName), processName.c_str());
ret += strcpy_s(request->bundleName, sizeof(request->bundleName), processName.c_str());
ret += strcpy_s(request->renderCmd, sizeof(request->renderCmd), cmd.c_str());
if (ret != 0) {
printf("Failed to copy bundle name \n");
}
}
private:
std::shared_ptr<ClientSocket> clientSocket_ {};
};
} // namespace AppSpawn
} // namespace OHOS
#endif // APPSPAWN_CLIENT_TEST_H

View File

@ -0,0 +1,98 @@
/*
* 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_test_client.h"
#include <signal.h>
#include <unistd.h>
OHOS::AppSpawn::AppSpawnTestClient g_testClient;
static int DoRun(const char *server, const AppParameter *request)
{
int ret = g_testClient.ClientCreateSocket(server);
if (ret != 0) {
printf("Failed to connect server \n");
return 1;
}
ret = g_testClient.ClientSendMsg(reinterpret_cast<const uint8_t *>(request), sizeof(AppParameter));
if (ret != 0) {
printf("Failed to send msg to server \n");
g_testClient.ClientClose();
return 1;
}
pid_t pid = 0;
ret = g_testClient.ClientRecvMsg(pid);
if (ret != 0) {
printf("Failed spawn new app result %d \n", ret);
g_testClient.ClientClose();
quick_exit(0);
return 1;
}
if (pid > 0) {
printf("Success spawn new app pid %d \n", pid);
}
int index = 0;
while (index < 5) { // wait 5s
sleep(1);
index++;
}
if (pid > 0) {
APPSPAWN_LOGI("Success spawn new app pid %{public}d \n", pid);
kill(pid, SIGKILL);
}
// close client
g_testClient.ClientClose();
quick_exit(0);
return 0;
}
int main(int argc, char *const argv[])
{
int coldStart = 0;
int withSandbox = 0;
const char *cmd = "ls -l /data > /data/test.log";
const char *bundleName = "ohos.samples.test";
const char *server = "/dev/unix/socket/AppSpawn";
for (int32_t i = 0; i < argc; i++) {
if (strcmp(argv[i], "-c") == 0) {
coldStart = 1;
} else if (strcmp(argv[i], "-s") == 0) {
withSandbox = 1;
} else if (strcmp(argv[i], "--nwebspawn") == 0) {
server = "/dev/unix/socket/NWebSpawn";
} else if (strcmp(argv[i], "-b") == 0 && ((i + 1) < argc)) {
i++;
bundleName = argv[i];
} else if (strcmp(argv[i], "-C") == 0 && ((i + 1) < argc)) {
i++;
cmd= argv[i];
}
}
if (coldStart) {
SetParameter("startup.appspawn.cold.boot", "1");
SetParameter("persist.appspawn.client.timeout", "10");
}
AppParameter request = {};
memset_s((void *)(&request), sizeof(request), 0, sizeof(request));
g_testClient.ClientFillMsg(&request, bundleName, cmd);
request.flags = coldStart ? APP_COLD_BOOT : 0;
request.flags |= !withSandbox ? APP_NO_SANDBOX : 0;
request.code = SPAWN_NATIVE_PROCESS;
return DoRun(server, &request);
}

View File

@ -56,10 +56,20 @@ void AppSpawnSandboxTest::SetUp()
void AppSpawnSandboxTest::TearDown() void AppSpawnSandboxTest::TearDown()
{} {}
static ClientSocket::AppProperty *GetAppProperty(void) static AppSpawnClientExt *GetAppSpawnClientExt(void)
{ {
static AppSpawnClientExt client; static AppSpawnClientExt client;
return &client.property; return &client;
}
static ClientSocket::AppProperty *GetAppProperty(void)
{
return &GetAppSpawnClientExt()->property;
}
static AppSpawnClient *GetAppSpawnClient(void)
{
return &GetAppSpawnClientExt()->client;
} }
/** /**
@ -95,7 +105,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_08, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_08 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_08 end";
} }
@ -131,7 +141,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_09, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09 end";
} }
@ -159,17 +169,17 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_09_1, TestSize.Level0)
int ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(nullptr); int ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(nullptr);
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
m_appProperty->bundleName[0] = '\0'; m_appProperty->bundleName[0] = '\0';
ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "com.\\ohos.dlpmanager") != 0) { if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "com.\\ohos.dlpmanager") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl; GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl;
} }
ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "com./ohos.dlpmanager") != 0) { if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "com./ohos.dlpmanager") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl; GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl;
} }
ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 end";
} }
@ -225,7 +235,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_10, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_10 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_10 end";
} }
@ -351,7 +361,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_13, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_13 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_13 end";
} }
@ -404,7 +414,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_14, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_14 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_14 end";
} }
@ -458,7 +468,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_15, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_15 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_15 end";
} }
@ -505,7 +515,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_16, TestSize.Level0)
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
GTEST_LOG_(INFO) << "App_Spawn_Sandbox_16 end"; GTEST_LOG_(INFO) << "App_Spawn_Sandbox_16 end";
} }
@ -576,7 +586,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_19, TestSize.Level0)
GTEST_LOG_(ERROR) << "Failed to memset_s err=" << errno; GTEST_LOG_(ERROR) << "Failed to memset_s err=" << errno;
ASSERT_TRUE(0); ASSERT_TRUE(0);
} }
ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
EXPECT_EQ(ret, -1); EXPECT_EQ(ret, -1);
ret = strncpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "\\test", APP_LEN_BUNDLE_NAME - 1); ret = strncpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "\\test", APP_LEN_BUNDLE_NAME - 1);
@ -584,7 +594,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_19, TestSize.Level0)
GTEST_LOG_(ERROR) << "Failed to strncpy_s err=" << errno; GTEST_LOG_(ERROR) << "Failed to strncpy_s err=" << errno;
ASSERT_TRUE(0); ASSERT_TRUE(0);
} }
ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
EXPECT_EQ(ret, -1); EXPECT_EQ(ret, -1);
ret = strncpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "/test", APP_LEN_BUNDLE_NAME - 1); ret = strncpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "/test", APP_LEN_BUNDLE_NAME - 1);
@ -592,7 +602,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_19, TestSize.Level0)
GTEST_LOG_(ERROR) << "Failed to strncpy_s err=" << errno; GTEST_LOG_(ERROR) << "Failed to strncpy_s err=" << errno;
ASSERT_TRUE(0); ASSERT_TRUE(0);
} }
ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
EXPECT_EQ(ret, -1); EXPECT_EQ(ret, -1);
} }
@ -615,7 +625,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_20, TestSize.Level0)
m_appProperty->uid = 1000; // the UNIX uid that the child process setuid() to after fork() m_appProperty->uid = 1000; // the UNIX uid that the child process setuid() to after fork()
m_appProperty->gid = 1000; // the UNIX gid that the child process setgid() to after fork() m_appProperty->gid = 1000; // the UNIX gid that the child process setgid() to after fork()
m_appProperty->cloneFlags = CLONE_NEWPID; GetAppSpawnClient()->cloneFlags = CLONE_NEWPID;
if (strcpy_s(m_appProperty->processName, APP_LEN_PROC_NAME, "test.appspawn") != 0) { if (strcpy_s(m_appProperty->processName, APP_LEN_PROC_NAME, "test.appspawn") != 0) {
GTEST_LOG_(INFO) << "Failed to strcpy_s err=" << errno << std::endl; GTEST_LOG_(INFO) << "Failed to strcpy_s err=" << errno << std::endl;
@ -626,7 +636,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_20, TestSize.Level0)
if (strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "normal") != 0) { if (strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "normal") != 0) {
GTEST_LOG_(INFO) << "Failed to strcpy_s err=" << errno << std::endl; GTEST_LOG_(INFO) << "Failed to strcpy_s err=" << errno << std::endl;
} }
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
std::string mJsconfig1 = "{ \ std::string mJsconfig1 = "{ \
\"common\":[{ \ \"common\":[{ \
@ -644,7 +654,7 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_20, TestSize.Level0)
}"; }";
nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str());
OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config1); OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config1);
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty); OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(GetAppSpawnClient());
} }
HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_21, TestSize.Level0) HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_21, TestSize.Level0)
@ -665,13 +675,6 @@ HWTEST(AppSpawnSandboxTest, App_Spawn_Sandbox_22, TestSize.Level0)
nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str());
OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config1); OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config1);
std::string pJsconfig1 = "{ \
\"common\":[], \
\"individual\": [] \
}";
nlohmann::json p_config1 = nlohmann::json::parse(pJsconfig1.c_str());
OHOS::AppSpawn::SandboxUtils::StoreProductJsonConfig(p_config1);
ClientSocket::AppProperty *m_appProperty = GetAppProperty(); ClientSocket::AppProperty *m_appProperty = GetAppProperty();
int ret = strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "system_basic"); int ret = strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "system_basic");
if (ret != 0) { if (ret != 0) {

View File

@ -278,13 +278,14 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003, TestSize.Level0)
*/ */
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_1, TestSize.Level0) HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_1, TestSize.Level0)
{ {
GTEST_LOG_(INFO) << "App_Spawn_Standard_003_1 start"; APPSPAWN_LOGI("App_Spawn_Standard_003_1 start");
AppSpawnClientExt client = {}; AppSpawnClientExt client = {};
char arg1[] = "/system/bin/appspawn"; char arg1[] = "/system/bin/appspawn";
char arg2[] = "cold-start"; char arg2[] = "cold-start";
char arg3[] = "1"; char arg3[] = "1";
{ {
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg5[] = "10"; char arg5[] = "10";
char arg6[] = "012345678"; char arg6[] = "012345678";
char* argv[] = {arg1, arg2, arg3, arg4, arg5, arg6}; char* argv[] = {arg1, arg2, arg3, arg4, arg5, arg6};
@ -293,35 +294,39 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_1, TestSize.Level0)
FreeHspList(client.property.hspList); FreeHspList(client.property.hspList);
} }
{ // hsp length is 0 { // hsp length is 0
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg5[] = "0"; char arg5[] = "0";
char* argv[] = {arg1, arg2, arg3, arg4, arg5, nullptr}; char* argv[] = {arg1, arg2, arg3, arg4, arg5, nullptr};
int argc = sizeof(argv)/sizeof(argv[0]); int argc = sizeof(argv)/sizeof(argv[0]);
EXPECT_EQ(0, GetAppSpawnClientFromArg(argc, argv, &client)); EXPECT_EQ(0, GetAppSpawnClientFromArg(argc, argv, &client));
} }
{ // hsp length is null { // hsp length is null
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg6[] = "0123456789"; char arg6[] = "0123456789";
char* argv[] = {arg1, arg2, arg3, arg4, nullptr, arg6}; char* argv[] = {arg1, arg2, arg3, arg4, nullptr, arg6};
int argc = sizeof(argv)/sizeof(argv[0]); int argc = sizeof(argv)/sizeof(argv[0]);
EXPECT_EQ(-1, GetAppSpawnClientFromArg(argc, argv, &client)); EXPECT_EQ(-1, GetAppSpawnClientFromArg(argc, argv, &client));
} }
{ // hsp length is non-zero, but argc is 5 { // hsp length is non-zero, but argc is 5
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg5[] = "10"; char arg5[] = "10";
char* argv[] = {arg1, arg2, arg3, arg4, arg5}; char* argv[] = {arg1, arg2, arg3, arg4, arg5};
int argc = sizeof(argv)/sizeof(argv[0]); int argc = sizeof(argv)/sizeof(argv[0]);
EXPECT_EQ(-1, GetAppSpawnClientFromArg(argc, argv, &client)); EXPECT_EQ(-1, GetAppSpawnClientFromArg(argc, argv, &client));
} }
{ // hsp length is non-zero, but content is null { // hsp length is non-zero, but content is null
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg5[] = "10"; char arg5[] = "10";
char* argv[] = {arg1, arg2, arg3, arg4, arg5, nullptr}; char* argv[] = {arg1, arg2, arg3, arg4, arg5, nullptr};
int argc = sizeof(argv)/sizeof(argv[0]); int argc = sizeof(argv)/sizeof(argv[0]);
EXPECT_EQ(-1, GetAppSpawnClientFromArg(argc, argv, &client)); EXPECT_EQ(-1, GetAppSpawnClientFromArg(argc, argv, &client));
} }
GTEST_LOG_(INFO) << "App_Spawn_Standard_003_1 end"; APPSPAWN_LOGI("App_Spawn_Standard_003_1 en");
} }
/** /**
@ -333,13 +338,14 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_1, TestSize.Level0)
*/ */
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_2, TestSize.Level0) HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_2, TestSize.Level0)
{ {
GTEST_LOG_(INFO) << "App_Spawn_Standard_003_2 start"; APPSPAWN_LOGI("App_Spawn_Standard_003_2 start");
AppSpawnClientExt client = {}; AppSpawnClientExt client = {};
char arg1[] = "/system/bin/appspawn"; char arg1[] = "/system/bin/appspawn";
char arg2[] = "cold-start"; char arg2[] = "cold-start";
char arg3[] = "1"; char arg3[] = "1";
{ // actual data is shorter than totalLength { // actual data is shorter than totalLength
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg5[] = "10"; char arg5[] = "10";
char arg6[] = "01234"; char arg6[] = "01234";
char* argv[] = {arg1, arg2, arg3, arg4, arg5, arg6}; char* argv[] = {arg1, arg2, arg3, arg4, arg5, arg6};
@ -348,7 +354,8 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_2, TestSize.Level0)
FreeHspList(client.property.hspList); FreeHspList(client.property.hspList);
} }
{ // actual data is longer than totalLength { // actual data is longer than totalLength
char arg4[] = "1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:default:671201800:system_core:default"; char arg4[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
"default:671201800:system_core:default:0:671201800";
char arg5[] = "5"; char arg5[] = "5";
char arg6[] = "0123456789"; char arg6[] = "0123456789";
char* argv[] = {arg1, arg2, arg3, arg4, arg5, arg6}; char* argv[] = {arg1, arg2, arg3, arg4, arg5, arg6};
@ -357,7 +364,7 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003_2, TestSize.Level0)
FreeHspList(client.property.hspList); FreeHspList(client.property.hspList);
} }
GTEST_LOG_(INFO) << "App_Spawn_Standard_003_2 end"; APPSPAWN_LOGI("App_Spawn_Standard_003_2 end");
} }
/** /**
@ -379,12 +386,13 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_004, TestSize.Level0)
content->runChildProcessor = RunChildProcessor; content->runChildProcessor = RunChildProcessor;
content->runChildProcessor(content, nullptr); content->runChildProcessor(content, nullptr);
char tmp0[] = "/system/bin/appspawn"; char tmp0[] = "/system/bin/appspawn";
char tmp1[] = "cold-start"; char tmp1[] = "cold-start";
char tmp2[] = "1"; char tmp2[] = "1";
{ {
char tmp3[] = "1:1:1:1:2:1000:1000:ohos.samples.ecg.default: \ char tmp3[] = "1:1:1:1:1:1:1:1:1:2:1000:1000:ohos.samples:ohos.samples.ecg:"
ohos.samples.ecg:default:671201800:system_core:default"; "default:671201800:system_core:default:0:671201800";
char * const argv[] = {tmp0, tmp1, tmp2, tmp3}; char * const argv[] = {tmp0, tmp1, tmp2, tmp3};
AppSpawnColdRun(content, 4, argv); AppSpawnColdRun(content, 4, argv);
} }
@ -448,7 +456,7 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_005, TestSize.Level0)
GTEST_LOG_(INFO) << "App_Spawn_Standard_005 end"; GTEST_LOG_(INFO) << "App_Spawn_Standard_005 end";
} }
static int RunClient(AppSpawnContentExt *content, int cold, AppOperateType code, const std::string &processName) static int RunClient(AppSpawnContentExt *content, int flags, AppOperateType code, const std::string &processName)
{ {
// create connection // create connection
TaskHandle stream = AcceptClient(LE_GetDefaultLoop(), content->server, TASK_TEST); TaskHandle stream = AcceptClient(LE_GetDefaultLoop(), content->server, TASK_TEST);
@ -465,12 +473,16 @@ static int RunClient(AppSpawnContentExt *content, int cold, AppOperateType code,
property.gid = 100; // 100 is gid property.gid = 100; // 100 is gid
property.gidCount = 1; // 1 is gidCount property.gidCount = 1; // 1 is gidCount
property.gidTable[0] = 101; // 101 is gidTable property.gidTable[0] = 101; // 101 is gidTable
(void)strcpy_s(property.processName, sizeof(property.processName), processName.c_str()); if (code == SPAWN_NATIVE_PROCESS) {
(void)strcpy_s(property.processName, sizeof(property.processName), "ohos.appspawn.test.cmd");
} else {
(void)strcpy_s(property.processName, sizeof(property.processName), processName.c_str());
}
(void)strcpy_s(property.bundleName, sizeof(property.bundleName), processName.c_str()); (void)strcpy_s(property.bundleName, sizeof(property.bundleName), processName.c_str());
(void)strcpy_s(property.renderCmd, sizeof(property.renderCmd), processName.c_str()); (void)strcpy_s(property.renderCmd, sizeof(property.renderCmd), processName.c_str());
(void)strcpy_s(property.soPath, sizeof(property.soPath), processName.c_str()); (void)strcpy_s(property.soPath, sizeof(property.soPath), processName.c_str());
(void)strcpy_s(property.apl, sizeof(property.apl), "system_core"); (void)strcpy_s(property.apl, sizeof(property.apl), "system_core");
property.flags = cold ? 0x01 : 0; property.flags = flags;
property.code = code; property.code = code;
property.accessTokenId = 0; property.accessTokenId = 0;
property.setAllowInternet = 1; property.setAllowInternet = 1;
@ -491,7 +503,7 @@ static int RunClient(AppSpawnContentExt *content, int cold, AppOperateType code,
return 0; return 0;
} }
static AppSpawnContentExt *TestClient(int cold, static AppSpawnContentExt *TestClient(int flags,
AppOperateType code, const std::string &processName, const std::string &serverName) AppOperateType code, const std::string &processName, const std::string &serverName)
{ {
char buffer[64] = {0}; // 64 buffer size char buffer[64] = {0}; // 64 buffer size
@ -506,7 +518,7 @@ static AppSpawnContentExt *TestClient(int cold,
// set common operation // set common operation
content->content.loadExtendLib = LoadExtendLib; content->content.loadExtendLib = LoadExtendLib;
content->content.runChildProcessor = RunChildProcessor; content->content.runChildProcessor = RunChildProcessor;
content->flags |= cold ? FLAGS_ON_DEMAND : 0; content->flags |= (flags & APP_COLD_BOOT) ? FLAGS_ON_DEMAND : 0;
// test null // test null
StreamServerTask *task = reinterpret_cast<StreamServerTask *>(content->server); StreamServerTask *task = reinterpret_cast<StreamServerTask *>(content->server);
task->incommingConnect(nullptr, nullptr); task->incommingConnect(nullptr, nullptr);
@ -519,7 +531,7 @@ static AppSpawnContentExt *TestClient(int cold,
ret = LE_StartTimer(LE_GetDefaultLoop(), content->timer, 500, 1); // 500 ms is timeout ret = LE_StartTimer(LE_GetDefaultLoop(), content->timer, 500, 1); // 500 ms is timeout
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
} }
ret = RunClient(content, cold, code, processName); ret = RunClient(content, flags, code, processName);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
if (content->timer == nullptr) { // create timer for exit if (content->timer == nullptr) { // create timer for exit
@ -562,7 +574,8 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_006_2, TestSize.Level0)
GTEST_LOG_(INFO) << "App_Spawn_Standard_006_2 start"; GTEST_LOG_(INFO) << "App_Spawn_Standard_006_2 start";
SetHapDomainSetcontextResult(-1); SetHapDomainSetcontextResult(-1);
SetParameter("startup.appspawn.cold.boot", "1"); SetParameter("startup.appspawn.cold.boot", "1");
AppSpawnContentExt *content = TestClient(1, DEFAULT, "com.ohos.medialibrary.medialibrarydata", "test006_2"); AppSpawnContentExt *content = TestClient(APP_COLD_BOOT,
DEFAULT, "com.ohos.medialibrary.medialibrarydata", "test006_2");
ASSERT_TRUE(content != nullptr); ASSERT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr); content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_006_2 end"; GTEST_LOG_(INFO) << "App_Spawn_Standard_006_2 end";
@ -572,7 +585,8 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_006_3, TestSize.Level0)
{ {
GTEST_LOG_(INFO) << "App_Spawn_Standard_006_3 start"; GTEST_LOG_(INFO) << "App_Spawn_Standard_006_3 start";
SetHapDomainSetcontextResult(-1); SetHapDomainSetcontextResult(-1);
AppSpawnContentExt *content = TestClient(1, DEFAULT, "com.ohos.medialibrary.medialibrarydata", "test006_2"); AppSpawnContentExt *content = TestClient(APP_COLD_BOOT,
DEFAULT, "com.ohos.medialibrary.medialibrarydata", "test006_2");
ASSERT_TRUE(content != nullptr); ASSERT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr); content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_006_3 end"; GTEST_LOG_(INFO) << "App_Spawn_Standard_006_3 end";
@ -583,7 +597,8 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_006_4, TestSize.Level0)
GTEST_LOG_(INFO) << "App_Spawn_Standard_006_4 start"; GTEST_LOG_(INFO) << "App_Spawn_Standard_006_4 start";
SetHapDomainSetcontextResult(-1); SetHapDomainSetcontextResult(-1);
SetParameter("const.appspawn.preload", "false"); SetParameter("const.appspawn.preload", "false");
AppSpawnContentExt *content = TestClient(1, DEFAULT, "com.ohos.medialibrary.medialibrarydata", "test006_2"); AppSpawnContentExt *content = TestClient(APP_COLD_BOOT,
DEFAULT, "com.ohos.medialibrary.medialibrarydata", "test006_2");
ASSERT_TRUE(content != nullptr); ASSERT_TRUE(content != nullptr);
content->content.coldStartApp = nullptr; content->content.coldStartApp = nullptr;
content->content.runAppSpawn(&content->content, 0, nullptr); content->content.runAppSpawn(&content->content, 0, nullptr);
@ -817,4 +832,48 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_ReportEvent, TestSize.Level0)
ReportProcessExitInfo(nullptr, 100, 100, 0); ReportProcessExitInfo(nullptr, 100, 100, 0);
ReportProcessExitInfo("nullptr", 100, 100, 0); ReportProcessExitInfo("nullptr", 100, 100, 0);
} }
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_009_01, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_01 start";
SetHapDomainSetcontextResult(-1);
AppSpawnContentExt *content = TestClient(0,
SPAWN_NATIVE_PROCESS, "ls -l > /data/appspawn_ut/test009_1", "test009_1");
ASSERT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_01 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_009_02, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_02 start";
SetHapDomainSetcontextResult(-1);
AppSpawnContentExt *content = TestClient(APP_NO_SANDBOX,
SPAWN_NATIVE_PROCESS, "ls -l > /data/appspawn_ut/test009_02", "test009_02");
ASSERT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_02 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_009_03, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_03 start";
SetHapDomainSetcontextResult(-1);
AppSpawnContentExt *content = TestClient(APP_COLD_BOOT,
SPAWN_NATIVE_PROCESS, "ls -l > /data/appspawn_ut/test009_03", "test009_03");
ASSERT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_03 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_009_04, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_04 start";
SetHapDomainSetcontextResult(-1);
AppSpawnContentExt *content = TestClient(APP_COLD_BOOT | APP_NO_SANDBOX,
SPAWN_NATIVE_PROCESS, "ls -l > /data/appspawn_ut/test009_04", "test009_04");
ASSERT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_009_04 end";
}
} // namespace OHOS } // namespace OHOS

View File

@ -21,6 +21,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "nlohmann/json.hpp" #include "nlohmann/json.hpp"
#include "client_socket.h" #include "client_socket.h"
#include "appspawn_server.h"
namespace OHOS { namespace OHOS {
namespace AppSpawn { namespace AppSpawn {
@ -32,7 +33,7 @@ public:
static nlohmann::json GetJsonConfig(); static nlohmann::json GetJsonConfig();
static void StoreProductJsonConfig(nlohmann::json &productSandboxConfig); static void StoreProductJsonConfig(nlohmann::json &productSandboxConfig);
static nlohmann::json GetProductJsonConfig(); static nlohmann::json GetProductJsonConfig();
static int32_t SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty); static int32_t SetAppSandboxProperty(AppSpawnClient *client);
static uint32_t GetNamespaceFlagsFromConfig(const char *bundleName); static uint32_t GetNamespaceFlagsFromConfig(const char *bundleName);
private: private:

View File

@ -27,6 +27,7 @@
#include "json_utils.h" #include "json_utils.h"
#include "securec.h" #include "securec.h"
#include "appspawn_server.h" #include "appspawn_server.h"
#include "appspawn_service.h"
#ifdef WITH_SELINUX #ifdef WITH_SELINUX
#include "hap_restorecon.h" #include "hap_restorecon.h"
#endif #endif
@ -936,18 +937,22 @@ static int CheckBundleName(const std::string &bundleName)
return 0; return 0;
} }
int32_t SandboxUtils::SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty) int32_t SandboxUtils::SetAppSandboxProperty(AppSpawnClient *client)
{ {
if (appProperty == nullptr || CheckBundleName(appProperty->bundleName) != 0) { APPSPAWN_CHECK(client != NULL, return -1, "Invalid appspwn client");
AppSpawnClientExt *clientExt = reinterpret_cast<AppSpawnClientExt *>(client);
ClientSocket::AppProperty *appProperty = &clientExt->property;
if (CheckBundleName(appProperty->bundleName) != 0) {
return -1; return -1;
} }
std::string sandboxPackagePath = g_sandBoxRootDir; std::string sandboxPackagePath = g_sandBoxRootDir;
const std::string bundleName = appProperty->bundleName; const std::string bundleName = appProperty->bundleName;
sandboxPackagePath += bundleName; sandboxPackagePath += bundleName;
MakeDirRecursive(sandboxPackagePath.c_str(), FILE_MODE); MakeDirRecursive(sandboxPackagePath.c_str(), FILE_MODE);
int rc = 0; int rc = 0;
// when CLONE_NEWPID is enabled, CLONE_NEWNS must be enabled. // when CLONE_NEWPID is enabled, CLONE_NEWNS must be enabled.
if (!(appProperty->cloneFlags & CLONE_NEWPID)) { if (!(client->cloneFlags & CLONE_NEWPID)) {
// add pid to a new mnt namespace // add pid to a new mnt namespace
rc = unshare(CLONE_NEWNS); rc = unshare(CLONE_NEWNS);
APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str());