Appspawn 工程log整改&appspawn ut

Signed-off-by: laiguizhong <laiguizhong@huawei.com>
Change-Id: I5592c051418ce79a22d0c5f0a8f73738379080bc
This commit is contained in:
laiguizhong 2022-06-14 00:06:32 -07:00
parent 32e5941279
commit 77592318b8
28 changed files with 758 additions and 819 deletions

View File

@ -70,7 +70,6 @@ ohos_executable("appspawn") {
ohos_static_library("appspawn_server") {
sources = [
"${appspawn_path}/adapter/appspawn_adapter.cpp",
"${appspawn_path}/adapter/appspawn_log.cpp",
"${appspawn_path}/adapter/appspawn_sandbox.cpp",
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/standard/appspawn_process.c",
@ -113,7 +112,6 @@ ohos_prebuilt_etc("appspawn.rc") {
ohos_static_library("nwebspawn_server") {
sources = [
"${appspawn_path}/adapter/appspawn_adapter.cpp",
"${appspawn_path}/adapter/appspawn_log.cpp",
"${appspawn_path}/adapter/appspawn_sandbox.cpp",
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/standard/appspawn_process.c",

View File

@ -24,17 +24,14 @@ void LoadExtendLib(AppSpawnContent *content)
#else
const char *acelibdir("/system/lib/libace.z.so");
#endif
void *AceAbilityLib = nullptr;
APPSPAWN_LOGI("MainThread::LoadAbilityLibrary. Start calling dlopen acelibdir.");
#ifndef APPSPAWN_TEST
void *AceAbilityLib = NULL;
AceAbilityLib = dlopen(acelibdir, RTLD_NOW | RTLD_GLOBAL);
APPSPAWN_CHECK(AceAbilityLib != NULL, return, "Fail to dlopen %s, [%s]", acelibdir, dlerror());
#endif
if (AceAbilityLib == nullptr) {
APPSPAWN_LOGE("Fail to dlopen %s, [%s]", acelibdir, dlerror());
} else {
APPSPAWN_LOGI("Success to dlopen %s", acelibdir);
}
APPSPAWN_LOGI("MainThread::LoadAbilityLibrary. End calling dlopen.");
APPSPAWN_LOGI("Success to dlopen %s", acelibdir);
APPSPAWN_LOGI("MainThread::LoadAbilityLibrary. End calling dlopen");
}
void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client)

View File

@ -17,6 +17,7 @@
#include <cerrno>
#include "appspawn_service.h"
#ifdef WITH_SELINUX
#include "hap_restorecon.h"
#endif

View File

@ -16,7 +16,7 @@
#ifndef APPSPAWN_ADPATER_CPP
#define APPSPAWN_ADPATER_CPP
#include "appspawn_service.h"
#include "appspawn_server.h"
#include <dlfcn.h>

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "appspawn_server.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <cerrno>
#include <cstdarg>
#include <ctime>
#include "hilog/log.h"
#include "securec.h"
namespace {
AppspawnLogLevel g_logLevel = AppspawnLogLevel::INFO;
constexpr int MAX_LOG_SIZE = 1024;
constexpr int BASE_YEAR = 1900;
constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, APPSPAWN_LABEL};
const char *APPSPAWN_LOG_PATH = "/data/init_agent/appspawn.log";
}
void AppspawnLogPrint(AppspawnLogLevel logLevel, const char *file, int line, const char *fmt, ...)
{
if (logLevel < g_logLevel) {
return;
}
va_list list;
va_start(list, fmt);
char tmpFmt[MAX_LOG_SIZE];
if (vsnprintf_s(tmpFmt, MAX_LOG_SIZE, MAX_LOG_SIZE - 1, fmt, list) == -1) {
va_end(list);
return;
}
va_end(list);
switch (logLevel) {
case AppspawnLogLevel::DEBUG:
OHOS::HiviewDFX::HiLog::Debug(LABEL, "[%{public}s:%{public}d]%{public}s", file, line, tmpFmt);
break;
case AppspawnLogLevel::INFO:
OHOS::HiviewDFX::HiLog::Info(LABEL, "[%{public}s:%{public}d]%{public}s", file, line, tmpFmt);
break;
case AppspawnLogLevel::WARN:
OHOS::HiviewDFX::HiLog::Warn(LABEL, "[%{public}s:%{public}d]%{public}s", file, line, tmpFmt);
break;
case AppspawnLogLevel::ERROR:
OHOS::HiviewDFX::HiLog::Error(LABEL, "[%{public}s:%{public}d]%{public}s", file, line, tmpFmt);
break;
case AppspawnLogLevel::FATAL:
OHOS::HiviewDFX::HiLog::Fatal(LABEL, "[%{public}s:%{public}d]%{public}s", file, line, tmpFmt);
break;
default:
break;
}
time_t second = time(0);
if (second <= 0) {
return;
}
struct tm *t = localtime(&second);
FILE *outfile = fopen(APPSPAWN_LOG_PATH, "a+");
if (t == nullptr || outfile == nullptr) {
return;
}
(void)fprintf(outfile, "[%d-%d-%d %d:%d:%d][pid=%d][%s:%d]%s \n",
(t->tm_year + BASE_YEAR), (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
getpid(), file, line, tmpFmt);
(void)fflush(outfile);
(void)fclose(outfile);
return;
}

View File

@ -20,8 +20,8 @@
#include <map>
#include <string>
#include "appspawn_service.h"
#include "appspawn_adapter.h"
struct RenderProcessNode {
RenderProcessNode(time_t now, int exit):recordTime_(now), exitStatus_(exit) {}
time_t recordTime_;

View File

@ -20,15 +20,13 @@
#include <string>
#include <vector>
#include "hilog/log.h"
#include "appspawn_service.h"
#include "json_utils.h"
#include "sandbox_utils.h"
using namespace std;
using namespace OHOS;
using namespace OHOS::HiviewDFX;
using namespace OHOS::AppSpawn;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawn_SandboxUtil"};
namespace {
#ifdef __aarch64__
@ -43,24 +41,18 @@ void LoadAppSandboxConfig(void)
{
// load sandbox config
nlohmann::json appSandboxConfig;
bool rc = JsonUtils::GetJsonObjFromJson(appSandboxConfig, APP_JSON_CONFIG);
if (!rc) {
HiLog::Error(LABEL, "AppSpawnServer::Failed to load app private sandbox config");
}
APPSPAWN_CHECK_ONLY_LOG(rc, "AppSpawnServer::Failed to load app private sandbox config");
SandboxUtils::StoreJsonConfig(appSandboxConfig);
rc = JsonUtils::GetJsonObjFromJson(appSandboxConfig, PRODUCT_JSON_CONFIG);
if (!rc) {
HiLog::Error(LABEL, "AppSpawnServer::Failed to load app product sandbox config");
}
APPSPAWN_CHECK_ONLY_LOG(rc, "AppSpawnServer::Failed to load app product sandbox config");
SandboxUtils::StoreProductJsonConfig(appSandboxConfig);
}
int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
APPSPAWN_CHECK(client != NULL, return -1, "Invalid appspwn client");
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
return SandboxUtils::SetAppSandboxProperty(&appProperty->property);
}

View File

@ -59,7 +59,7 @@
],
"test": [
"//base/startup/appspawn/test:moduletest",
"//base/startup/appspawn/test:unittest"
"//base/startup/appspawn/test/unittest:unittest"
]
}
}

View File

@ -33,11 +33,10 @@ static void NotifyResToParent(struct AppSpawnContent_ *content, AppSpawnClient *
static void ProcessExit(void)
{
APPSPAWN_LOGI("App exit %d.", getpid());
#ifndef APPSPAWN_TEST
#ifdef OHOS_LITE
_exit(0x7f); // 0x7f user exit
#else
#ifndef APPSPAWN_TEST
quick_exit(0);
#endif
#endif
@ -72,13 +71,11 @@ int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *l
return ret, "Failed to setUidGid");
}
#ifndef APPSPAWN_TEST
if (content->setFileDescriptors) {
ret = content->setFileDescriptors(content, client);
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret);
return ret, "Failed to setFileDescriptors");
}
#endif
if (content->setCapabilities) {
ret = content->setCapabilities(content, client);
@ -91,13 +88,8 @@ int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *l
return 0;
}
int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t *childPid)
int ForkChildProc(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t pid)
{
APPSPAWN_CHECK(content != NULL, return -1, "Invalid content for appspawn");
APPSPAWN_CHECK(client != NULL && childPid != NULL, return -1, "Invalid client for appspawn");
APPSPAWN_LOGI("AppSpawnProcessMsg id %d 0x%x", client->id, client->flags);
pid_t pid = fork();
if (pid < 0) {
return -errno;
} else if (pid == 0) {
@ -118,7 +110,9 @@ int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client,
int ret = -1;
if (client->flags & APP_COLD_START) {
if (content->coldStartApp != NULL && content->coldStartApp(content, client) == 0) {
#ifndef APPSPAWN_TEST
_exit(0x7f); // 0x7f user exit
#endif
return -1;
} else {
ret = DoStartApp(content, client, content->longProcName, content->longProcNameLen);
@ -140,6 +134,21 @@ int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client,
}
ProcessExit();
}
return 0;
}
int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t *childPid)
{
APPSPAWN_CHECK(content != NULL, return -1, "Invalid content for appspawn");
APPSPAWN_CHECK(client != NULL && childPid != NULL, return -1, "Invalid client for appspawn");
APPSPAWN_LOGI("AppSpawnProcessMsg id %d 0x%x", client->id, client->flags);
#ifndef APPSPAWN_TEST
pid_t pid = fork();
#else
pid_t pid = 0;
#endif
int ret = ForkChildProc(content, client, pid);
APPSPAWN_CHECK(ret == 0, return ret, "fork child process error: %d", ret);
*childPid = pid;
return 0;
}

View File

@ -72,6 +72,7 @@ typedef struct AppSpawnContent_ {
AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcName, uint32_t longProcNameLen, int cold);
int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t *childPid);
int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *longProcName, uint32_t longProcNameLen);
int ForkChildProc(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t pid);
#ifdef OHOS_DEBUG
void GetCurTime(struct timespec* tmCur);
@ -109,6 +110,11 @@ void AppspawnLogPrint(AppspawnLogLevel logLevel, const char *file, int line, con
exper; \
}
#define APPSPAWN_CHECK_ONLY_LOG(retCode, ...) \
if (!(retCode)) { \
APPSPAWN_LOGE(__VA_ARGS__); \
}
#ifdef __cplusplus
}
#endif

View File

@ -24,9 +24,16 @@ ohos_static_library("appspawn_socket_client") {
"client/appspawn_socket.cpp",
"client/client_socket.cpp",
]
include_dirs = [ "include" ]
include_dirs = [
"include",
"//base/startup/appspawn/common",
]
public_configs = [ ":exported_header_files" ]
deps = [ "//utils/native/base:utils" ]
deps = [
"//base/startup/init_lite/interfaces/innerkits:libbegetutil",
"//utils/native/base:utils",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
subsystem_name = "${subsystem_name}"

View File

@ -20,15 +20,12 @@
#include <cerrno>
#include <iostream>
#include "hilog/log.h"
#include "appspawn_server.h"
#include "pubdef.h"
#include "securec.h"
namespace OHOS {
namespace AppSpawn {
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawnSocket"};
AppSpawnSocket::AppSpawnSocket(const std::string &name)
{
socketName_ = name;
@ -49,15 +46,10 @@ int AppSpawnSocket::GetSocketFd() const
int AppSpawnSocket::PackSocketAddr()
{
if (socketName_.empty()) {
HiLog::Error(LABEL, "Invalid socket name: empty");
return -EINVAL;
}
APPSPAWN_CHECK(!socketName_.empty(), return -EINVAL, "Invalid socket name: empty");
if (memset_s(&socketAddr_, sizeof(socketAddr_), 0, sizeof(socketAddr_)) != EOK) {
HiLog::Error(LABEL, "Failed to memset socket addr");
return -1;
}
APPSPAWN_CHECK(memset_s(&socketAddr_, sizeof(socketAddr_), 0, sizeof(socketAddr_)) == EOK,
return -1, "Failed to memset socket addr");
socklen_t pathLen = 0;
if (socketName_[0] == '/') {
@ -67,7 +59,7 @@ int AppSpawnSocket::PackSocketAddr()
}
socklen_t pathSize = sizeof(socketAddr_.sun_path);
if (pathLen >= pathSize) {
HiLog::Error(LABEL, "Invalid socket name: '%{public}s' too long", socketName_.c_str());
APPSPAWN_LOGE("Invalid socket name: '%s' too long", socketName_.c_str());
return -1;
}
@ -78,10 +70,7 @@ int AppSpawnSocket::PackSocketAddr()
len = snprintf_s(socketAddr_.sun_path, pathSize, (pathSize - 1), "%s%s",
socketDir_.c_str(), socketName_.c_str());
}
if (static_cast<int>(pathLen) != len) {
HiLog::Error(LABEL, "Failed to copy socket path");
return -1;
}
APPSPAWN_CHECK(static_cast<int>(pathLen) == len, return -1, "Failed to copy socket path");
socketAddr_.sun_family = AF_LOCAL;
socketAddrLen_ = offsetof(struct sockaddr_un, sun_path) + pathLen + 1;
@ -92,19 +81,16 @@ int AppSpawnSocket::PackSocketAddr()
int AppSpawnSocket::CreateSocket()
{
int socketFd = socket(AF_UNIX, SOCK_STREAM, 0); // SOCK_SEQPACKET
if (socketFd < 0) {
HiLog::Error(LABEL, "Failed to create socket: %{public}d", errno);
return (-errno);
}
APPSPAWN_CHECK(socketFd >= 0, return -errno, "Failed to create socket: %d", errno);
HiLog::Debug(LABEL, "Created socket with fd %{public}d", socketFd);
APPSPAWN_LOGV("Created socket with fd %d", socketFd);
return socketFd;
}
void AppSpawnSocket::CloseSocket(int &socketFd)
{
if (socketFd >= 0) {
HiLog::Debug(LABEL, "Closed socket with fd %{public}d", socketFd);
APPSPAWN_LOGV("Closed socket with fd %d", socketFd);
close(socketFd);
socketFd = -1;
}
@ -113,20 +99,15 @@ void AppSpawnSocket::CloseSocket(int &socketFd)
int AppSpawnSocket::ReadSocketMessage(int socketFd, void *buf, int len)
{
if (socketFd < 0 || len <= 0 || buf == nullptr) {
HiLog::Error(LABEL, "Invalid args: socket %{public}d, len %{public}d, buf might be nullptr", socketFd, len);
APPSPAWN_LOGE("Invalid args: socket %d, len %d, buf might be nullptr", socketFd, len);
return -1;
}
if (memset_s(buf, len, 0, len) != EOK) {
HiLog::Warn(LABEL, "Failed to memset read buf");
return -1;
}
APPSPAWN_CHECK(memset_s(buf, len, 0, len) == EOK, return -1, "Failed to memset read buf");
ssize_t rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
if (rLen < 0) {
HiLog::Error(LABEL, "Read message from fd %{public}d error %{public}zd: %{public}d", socketFd, rLen, errno);
return -EFAULT;
}
APPSPAWN_CHECK(rLen >= 0, return -EFAULT, "Read message from fd %d error %zd: %d",
socketFd, rLen, errno);
return rLen;
}
@ -134,7 +115,7 @@ int AppSpawnSocket::ReadSocketMessage(int socketFd, void *buf, int len)
int AppSpawnSocket::WriteSocketMessage(int socketFd, const void *buf, int len)
{
if (socketFd < 0 || len <= 0 || buf == nullptr) {
HiLog::Error(LABEL, "Invalid args: socket %{public}d, len %{public}d, buf might be nullptr", socketFd, len);
APPSPAWN_LOGE("Invalid args: socket %d, len %d, buf might be nullptr", socketFd, len);
return -1;
}
@ -143,12 +124,10 @@ int AppSpawnSocket::WriteSocketMessage(int socketFd, const void *buf, int len)
const uint8_t *offset = reinterpret_cast<const uint8_t *>(buf);
for (ssize_t wLen = 0; remain > 0; offset += wLen, remain -= wLen, written += wLen) {
wLen = write(socketFd, offset, remain);
HiLog::Debug(LABEL, "socket fd %{public}d, wLen %zd", socketFd, wLen);
if ((wLen <= 0) && (errno != EINTR)) {
HiLog::Error(LABEL, "Failed to write message to fd %{public}d, error %zd: %{public}d",
socketFd, wLen, errno);
return (-errno);
}
APPSPAWN_LOGV("socket fd %d, wLen %zd", socketFd, wLen);
bool isRet = (wLen <= 0) && (errno != EINTR);
APPSPAWN_CHECK(!isRet, return -errno, "Failed to write message to fd %d, error %zd: %d",
socketFd, wLen, errno);
}
return written;

View File

@ -20,14 +20,11 @@
#include <cerrno>
#include <iostream>
#include "hilog/log.h"
#include "appspawn_server.h"
#include "securec.h"
namespace OHOS {
namespace AppSpawn {
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "ClientSocket"};
ClientSocket::ClientSocket(const std::string &client) : AppSpawnSocket(client)
{}
@ -35,20 +32,17 @@ int ClientSocket::CreateClient()
{
if (socketFd_ < 0) {
socketFd_ = CreateSocket();
if (socketFd_ < 0) {
HiLog::Error(LABEL, "Client: Create socket failed");
return socketFd_;
}
APPSPAWN_CHECK(socketFd_ >= 0, return socketFd_, "Client: Create socket failed");
}
HiLog::Debug(LABEL, "Client: CreateClient socket fd %{public}d", socketFd_);
APPSPAWN_LOGV("Client: CreateClient socket fd %d", socketFd_);
return 0;
}
void ClientSocket::CloseClient()
{
if (socketFd_ < 0) {
HiLog::Error(LABEL, "Client: Invalid connectFd %{public}d", socketFd_);
APPSPAWN_LOGE("Client: Invalid connectFd %d", socketFd_);
return;
}
@ -59,27 +53,22 @@ void ClientSocket::CloseClient()
int ClientSocket::ConnectSocket(int connectFd)
{
if (connectFd < 0) {
HiLog::Error(LABEL, "Client: Invalid socket fd: %{public}d", connectFd);
APPSPAWN_LOGE("Client: Invalid socket fd: %d", connectFd);
return -1;
}
if (PackSocketAddr() != 0) {
return -1;
}
APPSPAWN_CHECK(PackSocketAddr() == 0, return -1, "pack socket failed");
if ((setsockopt(connectFd, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0) ||
(setsockopt(connectFd, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0)) {
HiLog::Warn(LABEL, "Client: Failed to set opt of socket %{public}d, err %{public}d", connectFd, errno);
return -1;
}
bool isRet = (setsockopt(connectFd, SOL_SOCKET, SO_RCVTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0) ||
(setsockopt(connectFd, SOL_SOCKET, SO_SNDTIMEO, &SOCKET_TIMEOUT, sizeof(SOCKET_TIMEOUT)) != 0);
APPSPAWN_CHECK(!isRet, return (-1), "Client: Failed to set opt of socket %d, err %d", connectFd, errno);
if (connect(connectFd, reinterpret_cast<struct sockaddr *>(&socketAddr_), socketAddrLen_) < 0) {
HiLog::Warn(LABEL, "Client: Connect on socket fd %{public}d, failed: %{public}d", connectFd, errno);
APPSPAWN_LOGW("Client: Connect on socket fd %d, failed: %d", connectFd, errno);
return -1;
}
HiLog::Debug(LABEL, "Client: Connected on socket fd %{public}d, name '%{public}s'",
connectFd, socketAddr_.sun_path);
APPSPAWN_LOGV("Client: Connected on socket fd %d, name '%s'", connectFd, socketAddr_.sun_path);
return 0;
}

View File

@ -54,4 +54,4 @@ void FreeMessageSt(MessageSt *targetSt);
#endif
#endif
#endif // BASE_STARTUP_APPSPAWN_SERVICE_H
#endif // BASE_STARTUP_APPSPAWN_MESSAGE_H

View File

@ -143,12 +143,14 @@ static int SetCapabilities(struct AppSpawnContent_ *content, AppSpawnClient *cli
return -1;
}
#ifndef APPSPAWN_TEST
unsigned int tmpCaps[] = {17}; // 17 means CAP_SYS_RAWIO
unsigned int tmpsCapCnt = sizeof(tmpCaps) / sizeof(tmpCaps[0]);
if (SetCapability(tmpsCapCnt, tmpCaps) != 0) {
APPSPAWN_LOGE("[appspawn] setrlimit failed, err: %d.", errno);
return -1;
}
#endif
#else
if (SetCapability(appProperty->message.capsCnt, appProperty->message.caps) != 0) {
APPSPAWN_LOGE("[appspawn] SetCapability failed, err: %d.", errno);

View File

@ -1,37 +1,37 @@
/*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BASE_STARTUP_APPSPAWN_SERVICE_H
#define BASE_STARTUP_APPSPAWN_SERVICE_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define APPSPAWN_SERVICE_NAME "appspawn"
enum APPSPAWN_FUNCID {
ID_CALL_CREATE_SERVICE = 0,
ID_CALL_BUT
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // BASE_STARTUP_APPSPAWN_SERVICE_H
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BASE_STARTUP_APPSPAWN_SERVICE_H
#define BASE_STARTUP_APPSPAWN_SERVICE_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define APPSPAWN_SERVICE_NAME "appspawn"
enum APPSPAWN_FUNCID {
ID_CALL_CREATE_SERVICE = 0,
ID_CALL_BUT
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // BASE_STARTUP_APPSPAWN_SERVICE_H

View File

@ -39,18 +39,14 @@ static int SetProcessName(struct AppSpawnContent_ *content, AppSpawnClient *clie
AppSpawnClientExt *appPropertyExt = (AppSpawnClientExt *)client;
AppParameter *appProperty = &appPropertyExt->property;
int len = strlen(appProperty->processName);
if (longProcName == NULL || len <= 0) {
APPSPAWN_LOGE("process name is nullptr or length error");
return -EINVAL;
}
bool isRet = longProcName == NULL || len <= 0;
APPSPAWN_CHECK(!isRet, return -EINVAL, "process name is nullptr or length error");
char shortName[MAX_LEN_SHORT_NAME] = {0};
// process short name max length 16 bytes.
if (len >= MAX_LEN_SHORT_NAME) {
if (strncpy_s(shortName, MAX_LEN_SHORT_NAME, appProperty->processName, MAX_LEN_SHORT_NAME - 1) != EOK) {
APPSPAWN_LOGE("strncpy_s short name error: %d", errno);
return -EINVAL;
}
isRet = strncpy_s(shortName, MAX_LEN_SHORT_NAME, appProperty->processName, MAX_LEN_SHORT_NAME - 1) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "strncpy_s short name error: %d", errno);
} else {
if (strncpy_s(shortName, MAX_LEN_SHORT_NAME, appProperty->processName, len) != EOK) {
APPSPAWN_LOGE("strncpy_s short name error: %d", errno);
@ -59,22 +55,17 @@ static int SetProcessName(struct AppSpawnContent_ *content, AppSpawnClient *clie
}
// set short name
if (prctl(PR_SET_NAME, shortName) == -1) {
APPSPAWN_LOGE("prctl(PR_SET_NAME) error: %d", errno);
return (-errno);
}
isRet = prctl(PR_SET_NAME, shortName) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "prctl(PR_SET_NAME) error: %d", errno);
// reset longProcName
if (memset_s(longProcName, (size_t)longProcNameLen, 0, (size_t)longProcNameLen) != EOK) {
APPSPAWN_LOGE("Failed to memset long process name");
return -EINVAL;
}
isRet = memset_s(longProcName, (size_t)longProcNameLen, 0, (size_t)longProcNameLen) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset long process name");
// set long process name
if (strncpy_s(longProcName, sizeof(appProperty->processName) - 1, appProperty->processName, len) != EOK) {
APPSPAWN_LOGE("strncpy_s long name error: %d longProcNameLen %u", errno, longProcNameLen);
return -EINVAL;
}
isRet = strncpy_s(longProcName, sizeof(appProperty->processName) - 1, appProperty->processName, len) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "strncpy_s long name error: %d longProcNameLen %u", errno, longProcNameLen);
return 0;
}
@ -83,10 +74,8 @@ static int SetKeepCapabilities(struct AppSpawnContent_ *content, AppSpawnClient
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
// set keep capabilities when user not root.
if (appProperty->property.uid != 0) {
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
APPSPAWN_LOGE("set keepcaps failed: %d", errno);
return (-errno);
}
bool isRet = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "set keepcaps failed: %d", errno);
}
return 0;
}
@ -96,18 +85,15 @@ static int SetCapabilities(struct AppSpawnContent_ *content, AppSpawnClient *cli
// init cap
struct __user_cap_header_struct cap_header;
if (memset_s(&cap_header, sizeof(cap_header), 0, sizeof(cap_header)) != EOK) {
APPSPAWN_LOGE("Failed to memset cap header");
return -EINVAL;
}
bool isRet = memset_s(&cap_header, sizeof(cap_header), 0, sizeof(cap_header)) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap header");
cap_header.version = _LINUX_CAPABILITY_VERSION_3;
cap_header.pid = 0;
struct __user_cap_data_struct cap_data[2];
if (memset_s(&cap_data, sizeof(cap_data), 0, sizeof(cap_data)) != EOK) {
APPSPAWN_LOGE("Failed to memset cap data");
return -EINVAL;
}
isRet = memset_s(&cap_data, sizeof(cap_data), 0, sizeof(cap_data)) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap data");
// init inheritable permitted effective zero
#ifdef GRAPHIC_PERMISSION_CHECK
@ -128,51 +114,48 @@ static int SetCapabilities(struct AppSpawnContent_ *content, AppSpawnClient *cli
cap_data[1].effective = (__u32)(effective >> BITLEN32);
// set capabilities
if (capset(&cap_header, &cap_data[0]) == -1) {
APPSPAWN_LOGE("capset failed: %d", errno);
return (-errno);
}
isRet = capset(&cap_header, &cap_data[0]) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "capset failed: %d", errno);
return 0;
}
static void InitDebugParams(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
#ifndef APPSPAWN_TEST
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
#ifdef __aarch64__
const char *debugSoPath = "/system/lib64/libhidebug.so";
#else
const char *debugSoPath = "/system/lib/libhidebug.so";
#endif
if (access(debugSoPath, F_OK) != 0) {
return;
}
bool isRet = access(debugSoPath, F_OK) != 0;
APPSPAWN_CHECK(!isRet, return, "access failed, errno = %d", errno);
void *handle = dlopen(debugSoPath, RTLD_LAZY);
if (handle == NULL) {
APPSPAWN_LOGE("Failed to dlopen libhidebug.so, %s", dlerror());
return;
}
APPSPAWN_CHECK(handle != NULL, return, "Failed to dlopen libhidebug.so, %s", dlerror());
bool (*initParam)(const char *name);
initParam = (bool (*)(const char *name))dlsym(handle, "InitEnvironmentParam");
if (initParam == NULL) {
APPSPAWN_LOGE("Failed to dlsym InitEnvironmentParam, %s", dlerror());
dlclose(handle);
return;
}
APPSPAWN_CHECK(initParam != NULL, dlclose(handle);
return, "Failed to dlsym InitEnvironmentParam, %s", dlerror());
(*initParam)(appProperty->property.processName);
dlclose(handle);
#endif
}
static void ClearEnvironment(AppSpawnContent *content, AppSpawnClient *client)
{
APPSPAWN_LOGI("ClearEnvironment id %d", client->id);
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGTERM);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
// close child fd
#ifndef APPSPAWN_TEST
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
close(appProperty->fd[0]);
#endif
InitDebugParams(content, client);
return;
}
@ -182,28 +165,23 @@ static int SetUidGid(struct AppSpawnContent_ *content, AppSpawnClient *client)
#ifdef GRAPHIC_PERMISSION_CHECK
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
// set gids
if (setgroups(appProperty->property.gidCount, (const gid_t *)(&appProperty->property.gidTable[0])) == -1) {
APPSPAWN_LOGE("setgroups failed: %d, gids.size=%u", errno, appProperty->property.gidCount);
return (-errno);
}
bool isRet = setgroups(appProperty->property.gidCount, (const gid_t *)(&appProperty->property.gidTable[0])) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "setgroups failed: %d, gids.size=%u", errno, appProperty->property.gidCount);
// set gid
if (setresgid(appProperty->property.gid, appProperty->property.gid, appProperty->property.gid) == -1) {
APPSPAWN_LOGE("setgid(%u) failed: %d", appProperty->property.gid, errno);
return (-errno);
}
isRet = setresgid(appProperty->property.gid, appProperty->property.gid, appProperty->property.gid) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "setgid(%u) failed: %d", appProperty->property.gid, errno);
// If the effective user ID is changed from 0 to nonzero, then all capabilities are cleared from the effective set
if (setresuid(appProperty->property.uid, appProperty->property.uid, appProperty->property.uid) == -1) {
APPSPAWN_LOGE("setuid(%u) failed: %d", appProperty->property.uid, errno);
return (-errno);
}
isRet = setresuid(appProperty->property.uid, appProperty->property.uid, appProperty->property.uid) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "setuid(%u) failed: %d", appProperty->property.uid, errno);
#endif
return 0;
}
static int32_t SetFileDescriptors(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
#ifndef APPSPAWN_TEST
// close stdin stdout stderr
close(STDIN_FILENO);
close(STDOUT_FILENO);
@ -233,7 +211,7 @@ static int32_t SetFileDescriptors(struct AppSpawnContent_ *content, AppSpawnClie
APPSPAWN_LOGE("dup2 STDERR error: %d", errno);
return (-errno);
};
#endif
return 0;
}

View File

@ -39,7 +39,11 @@
static AppSpawnContentExt *g_appSpawnContent = NULL;
#ifdef APPSPAWN_TEST
static const int TV_SEC = 1;
#else
static const int TV_SEC = 60;
#endif
static int AppInfoHashNodeCompare(const HashNode *node1, const HashNode *node2)
{
@ -76,7 +80,7 @@ static void AppInfoHashNodeFree(const HashNode *node)
free(testNode);
}
static void AddAppInfo(pid_t pid, const char *processName)
APPSPAWN_STATIC void AddAppInfo(pid_t pid, const char *processName)
{
size_t len = strlen(processName) + 1;
AppInfo *node = (AppInfo *)malloc(sizeof(AppInfo) + len + 1);
@ -93,7 +97,7 @@ static void AddAppInfo(pid_t pid, const char *processName)
APPSPAWN_LOGI("Add %s, pid=%d success", processName, pid);
}
static void ProcessTimer(const TimerHandle taskHandle, void *context)
APPSPAWN_STATIC void ProcessTimer(const TimerHandle taskHandle, void *context)
{
APPSPAWN_LOGI("timeout stop appspawn");
LE_StopLoop(LE_GetDefaultLoop());
@ -133,7 +137,7 @@ static void OnClose(const TaskHandle taskHandle)
APPSPAWN_LOGI("OnClose client.id %d ", client->client.id);
}
static void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle)
APPSPAWN_STATIC void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle)
{
AppSpawnClientExt *client = (AppSpawnClientExt *)LE_GetUserData(taskHandle);
APPSPAWN_CHECK(client != NULL, return, "Failed to get client");
@ -170,30 +174,41 @@ static void PrintProcessExitInfo(pid_t pid, uid_t uid, int status)
}
#endif
static void SignalHandler(const struct signalfd_siginfo *siginfo)
static void HandleDiedPid(pid_t pid, uid_t uid, int status)
{
APPSPAWN_LOGI("SignalHandler pid %d status %d", pid, status);
#ifdef REPORT_EVENT
PrintProcessExitInfo(pid, uid, status);
#endif
#ifdef NWEB_SPAWN
// nwebspawn will invoke waitpid and remove appinfo at GetProcessTerminationStatusInner when
// GetProcessTerminationStatusInner is called before the parent process receives the SIGCHLD signal.
RecordRenderProcessExitedStatus(pid, status);
#endif
RemoveAppInfo(pid);
}
APPSPAWN_STATIC void SignalHandler(const struct signalfd_siginfo *siginfo)
{
APPSPAWN_LOGI("SignalHandler signum %d", siginfo->ssi_signo);
switch (siginfo->ssi_signo) {
case SIGCHLD: { // delete pid from app map
#ifndef APPSPAWN_TEST
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
APPSPAWN_LOGI("SignalHandler pid %d status %d", pid, status);
#ifdef REPORT_EVENT
PrintProcessExitInfo(pid, siginfo->ssi_uid, status);
#endif
#ifdef NWEB_SPAWN
// nwebspawn will invoke waitpid and remove appinfo at GetProcessTerminationStatusInner when
// GetProcessTerminationStatusInner is called before the parent process receives the SIGCHLD signal.
RecordRenderProcessExitedStatus(pid, status);
#endif
RemoveAppInfo(pid);
HandleDiedPid(pid, siginfo->ssi_uid, status);
}
#else
HandleDiedPid(siginfo->ssi_pid, siginfo->ssi_uid, 0);
#endif
break;
}
case SIGTERM: { // appswapn killed, use kill without parameter
HashMapTraverse(g_appSpawnContent->appMap, KillProcess, NULL);
#ifndef APPSPAWN_TEST
LE_StopLoop(LE_GetDefaultLoop());
#endif
break;
}
default:
@ -248,7 +263,7 @@ static int WaitChild(int fd, int pid, const AppSpawnClientExt *appProperty)
return result;
}
static void StartColdApp(AppSpawnClientExt *appProperty)
static void CheckColdAppEnabled(AppSpawnClientExt *appProperty)
{
if (appProperty == NULL) {
return;
@ -305,7 +320,7 @@ static void GetProcessTerminationStatus(AppSpawnClientExt *appProperty)
}
#endif
static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen)
APPSPAWN_STATIC void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen)
{
APPSPAWN_CHECK(buffer != NULL && buffLen >= sizeof(AppParameter), LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return, "Invalid buffer buffLen %u", buffLen);
@ -335,7 +350,7 @@ static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer,
g_appSpawnContent->timer = NULL;
}
StartColdApp(appProperty);
CheckColdAppEnabled(appProperty);
// create pipe for commication from child
if (pipe(appProperty->fd) == -1) {
APPSPAWN_LOGE("create pipe fail, errno = %d", errno);
@ -365,7 +380,14 @@ static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer,
}
}
static int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
#ifdef APPSPAWN_TEST
TaskHandle g_testClientHandle = NULL;
TaskHandle GetTestClientHandle()
{
return g_testClientHandle;
}
#endif
APPSPAWN_STATIC int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
{
static uint32_t clientId = 0;
APPSPAWN_LOGI("OnConnection ");
@ -374,6 +396,9 @@ static int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
TaskHandle stream;
LE_StreamInfo info = {};
info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
#ifdef APPSPAWN_TEST
info.baseInfo.flags |= TASK_TEST;
#endif
info.baseInfo.close = OnClose;
info.baseInfo.userDataSize = sizeof(AppSpawnClientExt);
info.disConntectComplete = NULL;
@ -389,6 +414,9 @@ static int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
client->client.id = ++clientId;
client->client.flags = 0;
APPSPAWN_LOGI("OnConnection client fd %d Id %d", LE_GetSocketFd(stream), client->client.id);
#ifdef APPSPAWN_TEST
g_testClientHandle = stream;
#endif
return 0;
}
@ -411,6 +439,7 @@ static void AppSpawnInit(AppSpawnContent *content)
if (content->loadExtendLib) {
content->loadExtendLib(content);
}
content->notifyResToParent = NotifyResToParent;
// set private function
SetContentFunction(content);
@ -457,8 +486,9 @@ static void AppSpawnRun(AppSpawnContent *content, int argc, char *const argv[])
if (status != 0) {
APPSPAWN_LOGE("Failed to add signal %d", status);
}
#ifndef APPSPAWN_TEST
LE_RunLoop(LE_GetDefaultLoop());
#endif
APPSPAWN_LOGI("AppSpawnRun exit ");
LE_CloseSignalTask(LE_GetDefaultLoop(), appSpawnContent->sigHandler);
// release resource

View File

@ -25,6 +25,12 @@
extern "C" {
#endif
#ifdef APPSPAWN_TEST
#define APPSPAWN_STATIC
#else
#define APPSPAWN_STATIC static
#endif
#define APP_HASH_BUTT 32
#define FLAGS_ON_DEMAND 0x1
#define FLAGS_MODE_COLD 0x2

View File

@ -16,6 +16,7 @@
#include "appspawn_adapter.h"
#include "appspawn_msg.h"
#include "appspawn_server.h"
#include "appspawn_service.h"
int main(int argc, char *const argv[])
{

View File

@ -14,59 +14,7 @@
import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni")
group("unittest") {
testonly = true
deps = [
"unittest/app_spawn_socket_test:unittest",
"unittest/app_spawn_standard_test:unittest",
"unittest/client_socket_test:unittest",
]
}
group("moduletest") {
testonly = true
deps = [ "moduletest:moduletest" ]
}
config("appspawn_test_config") {
configs = []
defines = [ "TEST_EXIT" ]
include_dirs = [
"${appspawn_path}/test/mock/include",
"${appspawn_path}/common",
"${appspawn_path}/interfaces/innerkits/include",
"${appspawn_path}/util/include",
]
}
ohos_source_set("appspawn_test_source") {
testonly = true
sources = []
include_dirs = [ "//third_party/json/include" ]
public_configs = [
"//utils/native/base:utils_config",
":appspawn_test_config",
]
public_deps = [
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
deps = []
external_deps = [
"ability_base:want",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"hiviewdfx_hilog_native:libhilog",
]
}

107
test/unittest/BUILD.gn Normal file
View File

@ -0,0 +1,107 @@
# Copyright (c) 2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni")
config("utest_config") {
cflags = [
"-fprofile-arcs",
"-ftest-coverage",
"-Wno-implicit-fallthrough",
"-Wno-unused-function",
]
cflags_cc = [
"-Wno-implicit-fallthrough",
"-fexceptions",
]
ldflags = [ "--coverage" ]
include_dirs = [
"${appspawn_path}/test/mock/include",
"${appspawn_path}/common",
"${appspawn_path}/standard",
"${appspawn_path}/adapter",
"${appspawn_path}/interfaces/innerkits/include",
"${appspawn_path}/util/include",
"//utils/native/base/include",
"${aafwk_path}/frameworks/kits/appkit/native/app/include",
"${aafwk_path}/interfaces/innerkits/app_manager/include/appmgr",
"${aafwk_path}/interfaces/innerkits/ability_manager/include",
"${aafwk_path}/frameworks/kits/ability/native/include",
"${aafwk_path}/services/abilitymgr/include",
"//base/global/resource_management/interfaces/inner_api/include",
"//base/security/access_token/interfaces/innerkits/token_setproc/include",
"//base/startup/init_lite/services/log",
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/loopevent/include",
"//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include",
"//third_party/json/include",
]
}
ohos_unittest("AppSpawn_ut") {
module_out_path = "${module_output_path}"
defines = [
"usleep(time) = MockSleep(time)",
"APPSPAWN_TEST",
]
sources = [
"${appspawn_path}/adapter/appspawn_ace.cpp",
"${appspawn_path}/adapter/appspawn_adapter.cpp",
"${appspawn_path}/adapter/appspawn_sandbox.cpp",
"${appspawn_path}/common/appspawn_server.c",
"${appspawn_path}/interfaces/innerkits/client/appspawn_socket.cpp",
"${appspawn_path}/interfaces/innerkits/client/client_socket.cpp",
"${appspawn_path}/standard/appspawn_process.c",
"${appspawn_path}/standard/appspawn_service.c",
"${appspawn_path}/util/src/json_utils.cpp",
"${appspawn_path}/util/src/sandbox_utils.cpp",
]
sources += [
"${appspawn_path}/test/unittest/app_spawn_socket_test/app_spawn_socket_test.cpp",
"${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_standard_test.cpp",
"${appspawn_path}/test/unittest/client_socket_test/client_socket_test.cpp",
]
configs = [ "//base/startup/appspawn/test/unittest:utest_config" ]
deps = [
"${aafwk_kits_path}/appkit:appkit_native",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
]
external_deps = [
"ability_base:want",
"ability_runtime:app_manager",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"hiviewdfx_hilog_native:libhilog",
"init:libbegetutil",
"ipc:ipc_core",
"utils_base:utils",
]
}
group("unittest") {
testonly = true
deps = [ ":AppSpawn_ut" ]
}

View File

@ -1,36 +0,0 @@
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni")
ohos_unittest("AppSpawnSocketTest") {
module_out_path = "${module_output_path}"
sources =
[ "${appspawn_path}/interfaces/innerkits/client/appspawn_socket.cpp" ]
sources += [ "app_spawn_socket_test.cpp" ]
configs = [ "${appspawn_path}:appspawn_config" ]
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
group("unittest") {
testonly = true
deps = [ ":AppSpawnSocketTest" ]
}

View File

@ -1,60 +0,0 @@
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni")
ohos_unittest("AppSpawnStandardTest") {
module_out_path = "${module_output_path}"
defines = [
"usleep(time) = MockSleep(time)",
"APPSPAWN_TEST",
]
include_dirs = [
"${appspawn_path}/standard/",
"${appspawn_path}/common/",
]
configs = [ "${appspawn_path}:appspawn_config" ]
sources = [
"${appspawn_path}/adapter/appspawn_ace.cpp",
"${appspawn_path}/standard/appspawn_process.c",
"${appspawn_path}/standard/appspawn_service.c",
"app_spawn_standard_test.cpp",
]
deps = [
"${aafwk_kits_path}/appkit:appkit_native",
"${appspawn_path}:appspawn_server",
"${appspawn_path}/test:appspawn_test_source",
"//base/startup/init_lite/interfaces/innerkits:libbegetutil",
]
external_deps = [
"ability_base:want",
"ability_runtime:app_manager",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"utils_base:utils",
]
}
group("unittest") {
testonly = true
deps = [ ":AppSpawnStandardTest" ]
}

View File

@ -15,7 +15,7 @@
#include <gtest/gtest.h>
#include <cstring>
#include <string>
#include <cerrno>
#include <memory>
@ -29,11 +29,65 @@
#include "appspawn_adapter.h"
#include "appspawn_server.h"
#include "securec.h"
#include "json_utils.h"
#include "init_hashmap.h"
#include "loop_event.h"
#include "sandbox_utils.h"
using namespace testing;
using namespace testing::ext;
using namespace OHOS::AppSpawn;
using nlohmann::json;
#ifdef __cplusplus
extern "C" {
#endif
int OnConnection(const LoopHandle loopHandle, const TaskHandle server);
void AddAppInfo(pid_t pid, const char *processName);
void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen);
void ProcessTimer(const TimerHandle taskHandle, void *context);
void SignalHandler(const struct signalfd_siginfo *siginfo);
void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle);
TaskHandle GetTestClientHandle();
#ifdef __cplusplus
}
#endif
namespace OHOS {
static void runAppSpawn(struct AppSpawnContent_ *content, int argc, char *const argv[])
{}
static int setAppSandbox(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
return 0;
}
static int setKeepCapabilities(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
return 0;
}
static int setFileDescriptors(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
return 0;
}
static int setProcessName(struct AppSpawnContent_ *content, AppSpawnClient *client,
char *longProcName, uint32_t longProcNameLen)
{
return 0;
}
static int setUidGid(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
return 0;
}
static int setCapabilities(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
return 0;
}
class AppSpawnStandardTest : public testing::Test {
public:
static void SetUpTestCase();
@ -54,10 +108,99 @@ void AppSpawnStandardTest::SetUp()
void AppSpawnStandardTest::TearDown()
{}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_001, TestSize.Level0)
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_002, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_001 start";
string longProcName = "AppSpawnStandardTest1";
GTEST_LOG_(INFO) << "App_Spawn_Standard_002 start";
char longProcName[124] = "App_Spawn_Standard_002";
int64_t longProcNameLen = 124; // 124 is str length
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
client->client.id = 8; // 8 is client id
client->client.flags = 0;
client->fd[0] = 100; // 100 is fd
client->fd[1] = 200; // 200 is fd
client->property.uid = 10000; // 10000 is uid
client->property.gid = 1000; // 1000 is gid
client->property.gidCount = 1; // 1 is gidCount
if (strcpy_s(client->property.processName, APP_LEN_PROC_NAME, "xxx.xxx.xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.bundleName, APP_LEN_BUNDLE_NAME, "xxx.xxx.xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.soPath, APP_LEN_SO_PATH, "xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
client->property.accessTokenId = 671201800; // 671201800 is accessTokenId
if (strcpy_s(client->property.apl, APP_APL_MAX_LEN, "xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.renderCmd, APP_RENDER_CMD_MAX_LEN, "xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
AppSpawnContent *content = AppSpawnCreateContent("AppSpawn", longProcName, longProcNameLen, 1);
content->loadExtendLib = LoadExtendLib;
content->runChildProcessor = RunChildProcessor;
SetContentFunction(content);
EXPECT_EQ(ForkChildProc(content, &client->client, 0), 0);
EXPECT_NE(ForkChildProc(content, &client->client, -1), 0);
content->clearEnvironment(content, &client->client);
EXPECT_EQ(content->setProcessName(content, &client->client, (char *)longProcName, longProcNameLen), 0);
EXPECT_EQ(content->setKeepCapabilities(content, &client->client), 0);
EXPECT_EQ(content->setUidGid(content, &client->client), 0);
EXPECT_EQ(content->setCapabilities(content, &client->client), 0);
EXPECT_EQ(content->setFileDescriptors(content, &client->client), 0);
content->setAppSandbox(content, &client->client);
content->setAppAccessToken(content, &client->client);
EXPECT_EQ(content->coldStartApp(content, &client->client), 0);
GTEST_LOG_(INFO) << "App_Spawn_Standard_002 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_003 start";
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
client->client.id = 8; // 8 is client id
client->client.flags = 1; // 1 is flags
client->fd[0] = 100; // 100 is fd
client->fd[1] = 200; // 200 is fd
client->property.uid = 10000; // 10000 is uid
client->property.gid = 1000; // 1000 is gid
client->property.gidCount = 1; // 1 is gidCount
if (strcpy_s(client->property.processName, APP_LEN_PROC_NAME, "xxx.xxx.xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.bundleName, APP_LEN_BUNDLE_NAME, "xxx.xxx.xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.soPath, APP_LEN_SO_PATH, "xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
client->property.accessTokenId = 671201800; // 671201800 is accessTokenId
if (strcpy_s(client->property.apl, APP_APL_MAX_LEN, "xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.renderCmd, APP_RENDER_CMD_MAX_LEN, "xxx") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
client->property.flags = 0;
char arg1[] = "xxx";
char arg2[] = "xxx";
char* argv[] = {arg1, arg2};
int argc = sizeof(argv)/sizeof(argv[0]);
EXPECT_EQ(GetAppSpawnClientFromArg(argc, argv, client), -1);
free(client);
GTEST_LOG_(INFO) << "App_Spawn_Standard_003 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_004, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_004 start";
string longProcName = "App_Spawn_Standard_004";
int64_t longProcNameLen = longProcName.length();
int cold = 1;
AppSpawnContent *content = AppSpawnCreateContent("AppSpawn", (char*)longProcName.c_str(), longProcNameLen, cold);
@ -65,122 +208,233 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_001, TestSize.Level0)
content->loadExtendLib = LoadExtendLib;
content->runChildProcessor = RunChildProcessor;
char *const argv[] = {};
content->initAppSpawn(content);
AppSpawnColdRun(content, 1, argv);
content->runChildProcessor(content, nullptr);
char tmp0[] = "/system/bin/appspawn";
char tmp1[] = "cold-start";
char tmp2[] = "1";
char tmp3[] = "1:1:1:1:0:ohos.samples.ecg.default:ohos.samples.ecg:default:671201800:system_core:default";
char * const argv[] = {tmp0, tmp1, tmp2, tmp3};
GTEST_LOG_(INFO) << "App_Spawn_Standard_001 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_002, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_002 start";
string longProcName = "AppSpawnStandardTest2";
int64_t longProcNameLen = longProcName.length();
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
client->client.id = 1;
client->client.flags = 1;
if (strcpy_s(client->property.apl, APP_APL_MAX_LEN, "system_basic") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
pid_t pid = 100;
AppSpawnContentExt* appSpawnContent = (AppSpawnContentExt*)calloc(1, sizeof(AppSpawnContentExt));
EXPECT_TRUE(appSpawnContent);
appSpawnContent->content.longProcNameLen = longProcNameLen;
appSpawnContent->timer = NULL;
appSpawnContent->content.runAppSpawn = NULL;
appSpawnContent->content.initAppSpawn = NULL;
AppSpawnProcessMsg(&appSpawnContent->content, &client->client, &pid);
free(appSpawnContent);
free(client);
GTEST_LOG_(INFO) << "App_Spawn_Standard_002 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_003, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_003 start";
char longProcName[124] = "AppSpawnStandardTest3";
int64_t longProcNameLen = 124; // 124 is str length
std::unique_ptr<AppSpawnClientExt> clientExt = std::make_unique<AppSpawnClientExt>();
clientExt->client.id = 1;
clientExt->client.flags = 0;
clientExt->fd[0] = 123;
clientExt->fd[1] = 456;
clientExt->property.uid = 10002;
clientExt->property.gid = 1000;
clientExt->property.gidCount = 1;
if (strcpy_s(clientExt->property.processName, APP_LEN_PROC_NAME, "com.ohos.settingsdata") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(clientExt->property.bundleName, APP_LEN_BUNDLE_NAME, "com.ohos.settingsdata") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(clientExt->property.soPath, APP_LEN_SO_PATH, "/test") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
clientExt->property.accessTokenId = 671201800;
if (strcpy_s(clientExt->property.apl, APP_APL_MAX_LEN, "system_core") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(clientExt->property.renderCmd, APP_RENDER_CMD_MAX_LEN, "cmd_test") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
clientExt->property.flags = 0;
AppSpawnContent *content = AppSpawnCreateContent("AppSpawn", longProcName, longProcNameLen, 1);
content->loadExtendLib = LoadExtendLib;
content->runChildProcessor = RunChildProcessor;
SetContentFunction(content);
content->clearEnvironment(content, &clientExt->client);
EXPECT_EQ(content->setProcessName(content, &clientExt->client, longProcName, longProcNameLen), 0);
EXPECT_EQ(content->setKeepCapabilities(content, &clientExt->client), 0);
EXPECT_EQ(content->setUidGid(content, &clientExt->client), 0);
EXPECT_EQ(content->setCapabilities(content, &clientExt->client), 0);
content->setAppSandbox(content, &clientExt->client);
content->setAppAccessToken(content, &clientExt->client);
EXPECT_EQ(content->coldStartApp(content, &clientExt->client), 0);
DoStartApp(content, &clientExt->client, longProcName, longProcNameLen);
free(content);
GTEST_LOG_(INFO) << "App_Spawn_Standard_003 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_004, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_004 start";
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
client->client.id = 1;
client->client.flags = 0;
client->fd[0] = 1;
client->fd[1] = 2;
client->property.uid = 10000;
client->property.gid = 1000;
client->property.gidCount = 1;
if (strcpy_s(client->property.processName, APP_LEN_PROC_NAME, "test4") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.bundleName, APP_LEN_BUNDLE_NAME, "test4") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.soPath, APP_LEN_SO_PATH, "test4") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
client->property.accessTokenId = 671201800;
if (strcpy_s(client->property.apl, APP_APL_MAX_LEN, "system_core") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
if (strcpy_s(client->property.renderCmd, APP_RENDER_CMD_MAX_LEN, "test4") != 0) {
GTEST_LOG_(INFO) << "strcpy_s failed";
}
client->property.flags = 0;
char* argv[] = {const_cast<char*>("AppSpawnStandardTest4"), const_cast<char*>("test4")};
int argc = sizeof(argv)/sizeof(argv[0]);
EXPECT_EQ(GetAppSpawnClientFromArg(argc, argv, client), -1);
free(client);
AppSpawnColdRun(content, 4, argv);
GTEST_LOG_(INFO) << "App_Spawn_Standard_004 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_005, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_005 start";
string longProcName = "ohos.samples.ecg.default";
int64_t longProcNameLen = longProcName.length();
std::unique_ptr<AppSpawnClientExt> clientExt = std::make_unique<AppSpawnClientExt>();
AppSpawnContent *content = AppSpawnCreateContent("AppSpawn", (char*)longProcName.c_str(), longProcNameLen, 1);
content->loadExtendLib = LoadExtendLib;
content->runChildProcessor = RunChildProcessor;
content->setAppSandbox = setAppSandbox;
content->setKeepCapabilities = setKeepCapabilities;
content->setProcessName = setProcessName;
content->setUidGid = setUidGid;
content->setFileDescriptors = setFileDescriptors;
content->setCapabilities = setCapabilities;
int ret = DoStartApp((AppSpawnContent_*)content, &clientExt->client, (char*)"", 0);
EXPECT_EQ(ret, 0);
free(content);
GTEST_LOG_(INFO) << "App_Spawn_Standard_005 end";
}
static AppSpawnContentExt *TestClient(int cold, AppOperateType code, const std::string &processName)
{
char buffer[64] = {0}; // 64 buffer size
AppSpawnContentExt *content =
(AppSpawnContentExt *)AppSpawnCreateContent("AppSpawnTest009", buffer, sizeof(buffer), cold);
if (content == nullptr) {
return nullptr;
}
APPSPAWN_CHECK(content->content.initAppSpawn != nullptr, return nullptr, "Invalid content for appspawn");
APPSPAWN_CHECK(content->content.runAppSpawn != nullptr, return nullptr, "Invalid content for appspawn");
// set common operation
content->content.loadExtendLib = LoadExtendLib;
content->content.runChildProcessor = RunChildProcessor;
content->content.initAppSpawn(&content->content);
// create connection
OnConnection(LE_GetDefaultLoop(), content->server);
// process recv message
if (GetTestClientHandle() == nullptr) {
free(content);
return nullptr;
}
AppParameter property = {};
property.uid = 100; // 100 is uid
property.gid = 100; // 100 is gid
property.gidCount = 1; // 1 is gidCount
property.gidTable[0] = 101; // 101 is gidTable
(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.renderCmd, sizeof(property.renderCmd), processName.c_str());
(void)strcpy_s(property.soPath, sizeof(property.soPath), processName.c_str());
(void)strcpy_s(property.apl, sizeof(property.apl), "system_core");
property.flags = 0;
property.code = code;
property.accessTokenId = 0;
OnReceiveRequest(GetTestClientHandle(), (const uint8_t *)&property, sizeof(property));
SendMessageComplete(GetTestClientHandle(), nullptr);
LE_CloseTask(LE_GetDefaultLoop(), GetTestClientHandle());
return content;
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_006, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_006 start";
AppSpawnContentExt *content = TestClient(0, DEFAULT, "ohos.test.testapp");
EXPECT_TRUE(content != nullptr);
content->content.runAppSpawn(&content->content, 0, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_006 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_07, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_07 start";
AppSpawnContentExt *content = TestClient(0, DEFAULT, "ohos.test.testapp");
EXPECT_TRUE(content != nullptr);
AddAppInfo(111, "111");
AddAppInfo(65, "112");
AddAppInfo(97, "113");
struct signalfd_siginfo siginfo = {};
siginfo.ssi_signo = SIGCHLD;
siginfo.ssi_pid = 111; // 111 is pid
SignalHandler(&siginfo);
siginfo.ssi_signo = SIGTERM;
siginfo.ssi_pid = 111; // 111 is pid
SignalHandler(&siginfo);
siginfo.ssi_signo = 0;
siginfo.ssi_pid = 111; // 111 is pid
SignalHandler(&siginfo);
content->content.runAppSpawn(&content->content, 0, nullptr);
ProcessTimer(nullptr, nullptr);
GTEST_LOG_(INFO) << "App_Spawn_Standard_07 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_08, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_08 start";
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
ClientSocket::AppProperty *m_appProperty = nullptr;
m_appProperty = &client->property;
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->gidCount = 1;
if (strcpy_s(m_appProperty->processName, APP_LEN_PROC_NAME, "ohos.samples.ecg") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 1" << std::endl;
}
if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "ohos.samples.ecg") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl;
}
if (strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "normal") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 3" << std::endl;
}
GTEST_LOG_(INFO) << "SetAppSandboxProperty section 2" << std::endl;
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty);
GTEST_LOG_(INFO) << "App_Spawn_Standard_08 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_09, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_09 start";
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
ClientSocket::AppProperty *m_appProperty = nullptr;
m_appProperty = &client->property;
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->gidCount = 1;
if (strcpy_s(m_appProperty->processName, APP_LEN_PROC_NAME, "com.ohos.dlpmanager") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 1" << std::endl;
}
if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "com.ohos.dlpmanager") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl;
}
if (strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "normal") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 3" << std::endl;
}
GTEST_LOG_(INFO) << "SetAppSandboxProperty section 2" << std::endl;
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty);
GTEST_LOG_(INFO) << "App_Spawn_Standard_09 end";
}
HWTEST(AppSpawnStandardTest, App_Spawn_Standard_10, TestSize.Level0)
{
GTEST_LOG_(INFO) << "App_Spawn_Standard_10 start";
std::string m_jsconfig = "{ \
\"common\":[{ \
\"top-sandbox-switch\": \"ON\", \
\"app-base\":[{ \
\"sandbox-root\" : \"/mnt/sandbox/<PackageName>\", \
\"mount-paths\" : [{ \
\"src-path\" : \"/config\", \
\"sandbox-path\" : \"/config\", \
\"sandbox-flags\" : [ \"bind\", \"rec\" ], \
\"check-action-status\": \"false\", \
\"dest-mode\": \"S_IRUSR | S_IWOTH | S_IRWXU \" \
}], \
\"symbol-links\" : [] \
}] \
}], \
\"individual\": [] \
}";
nlohmann::json j_config = nlohmann::json::parse(m_jsconfig.c_str());
OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config);
GTEST_LOG_(INFO) << "SetAppSandboxProperty start" << std::endl;
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
ClientSocket::AppProperty *m_appProperty = nullptr;
m_appProperty = &client->property;
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()
if (strcpy_s(m_appProperty->processName, APP_LEN_PROC_NAME, "test.appspawn") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 1" << std::endl;
}
if (strcpy_s(m_appProperty->bundleName, APP_LEN_BUNDLE_NAME, "test.bundle.name") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 2" << std::endl;
}
if (strcpy_s(m_appProperty->apl, APP_APL_MAX_LEN, "normal") != 0) {
GTEST_LOG_(INFO) << "SetAppSandboxProperty start 3" << std::endl;
}
GTEST_LOG_(INFO) << "SetAppSandboxProperty section 2" << std::endl;
m_appProperty->accessTokenId = 671201800; // 671201800 is accessTokenId
m_appProperty->pid = 354; // query render process exited status by render process pid
OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(m_appProperty);
GTEST_LOG_(INFO) << "App_Spawn_Standard_10 end";
}
} // namespace OHOS

View File

@ -1,40 +0,0 @@
# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/startup/appspawn/appspawn.gni")
import("//build/test.gni")
ohos_unittest("ClientSocketTest") {
module_out_path = "${module_output_path}"
defines = [ "usleep(time) = MockSleep(time)" ]
sources = [
"${appspawn_path}/interfaces/innerkits/client/appspawn_socket.cpp",
"${appspawn_path}/interfaces/innerkits/client/client_socket.cpp",
]
sources += [ "client_socket_test.cpp" ]
configs = [ "${appspawn_path}:appspawn_config" ]
deps = [ "${appspawn_path}/test:appspawn_test_source" ]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
}
group("unittest") {
testonly = true
deps = [ ":ClientSocketTest" ]
}

View File

@ -14,105 +14,39 @@
*/
#include "json_utils.h"
#include <fstream>
#include "appspawn_server.h"
#include <sstream>
#include "hilog/log.h"
#include <fstream>
using namespace std;
using namespace OHOS;
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawn_JsonUtil"};
namespace OHOS {
namespace AppSpawn {
bool JsonUtils::GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath)
{
if (jsonPath.length() > PATH_MAX) {
HiLog::Error(LABEL, "jsonPath is too long");
return false;
}
APPSPAWN_CHECK(jsonPath.length() <= PATH_MAX, return false, "jsonPath is too long");
std::ifstream jsonFileStream;
jsonFileStream.open(jsonPath.c_str(), std::ios::in);
if (!jsonFileStream.is_open()) {
HiLog::Error(LABEL, "Open json file failed.");
return false;
}
APPSPAWN_CHECK(jsonFileStream.is_open(), return false, "Open json file failed.");
std::ostringstream buf;
char ch;
while (buf && jsonFileStream.get(ch)) {
buf.put(ch);
}
jsonFileStream.close();
jsonObj = nlohmann::json::parse(buf.str(), nullptr, false);
if (!jsonObj.is_structured()) {
HiLog::Error(LABEL, "Parse json file into jsonObj failed.");
return false;
}
APPSPAWN_CHECK(jsonObj.is_structured(), return false, "Parse json file into jsonObj failed.");
return true;
}
bool JsonUtils::GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value)
{
if (!json.is_object()) {
HiLog::Error(LABEL, "json is not object.");
return false;
}
if (json.find(key) != json.end() && json.at(key).is_string()) {
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
value = json.at(key).get<std::string>();
return true;
}
return false;
}
bool JsonUtils::GetIntFromJson(const nlohmann::json &json, const std::string &key, int &value)
{
if (!json.is_object()) {
HiLog::Error(LABEL, "json is not object.");
return false;
}
if (json.find(key) != json.end() && json.at(key).is_number()) {
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
value = json.at(key).get<int>();
return true;
}
return false;
}
bool JsonUtils::GetStringVecFromJson(const nlohmann::json &json, const std::string &key,
std::vector<std::string> &value)
{
if (!json.is_object()) {
HiLog::Error(LABEL, "json is not object.");
return false;
}
if (json.find(key) != json.end() && json.at(key).is_array()) {
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
value = json.at(key).get<std::vector<std::string>>();
return true;
}
return false;
}
bool JsonUtils::ParseObjVecFromJson(const nlohmann::json &json, const std::string &key,
std::vector<nlohmann::json> &value)
{
if (!json.is_object()) {
HiLog::Error(LABEL, "json is not object.");
return false;
}
if (json.find(key) != json.end() && json.at(key).is_array()) {
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
value = json.at(key).get<std::vector<nlohmann::json>>();
return true;
}
APPSPAWN_CHECK(json.is_object(), return false, "json is not object.");
bool isRet = json.find(key) != json.end() && json.at(key).is_string();
APPSPAWN_CHECK(!isRet, value = json.at(key).get<std::string>();
return true, "Find key[%s] successful.", key.c_str());
return false;
}
} // namespace AppSpawn

View File

@ -30,14 +30,12 @@
#include <fstream>
#include <sstream>
#include "hilog/log.h"
#include "json_utils.h"
#include "securec.h"
#include "appspawn_server.h"
using namespace std;
using namespace OHOS;
using namespace OHOS::HiviewDFX;
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawn_SandboxUtil"};
namespace OHOS {
namespace AppSpawn {
@ -114,10 +112,8 @@ static void MakeDirRecursive(const std::string &path, mode_t mode)
size_t pathIndex = path.find_first_of('/', index);
index = pathIndex == std::string::npos ? size : pathIndex + 1;
std::string dir = path.substr(0, index);
if (access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0) {
HiLog::Error(LABEL, "mkdir %{public}s error", dir.c_str());
return;
}
APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0),
return, "mkdir %s error", dir.c_str());
} while (index < size);
}
@ -125,25 +121,17 @@ int32_t SandboxUtils::DoAppSandboxMountOnce(const char *originPath, const char *
const char *fsType, unsigned long mountFlags,
const char *options)
{
int ret = 0;
// To make sure destinationPath exist
MakeDirRecursive(destinationPath, FILE_MODE);
#ifndef APPSPAWN_TEST
int ret = 0;
// to mount fs and bind mount files or directory
ret = mount(originPath, destinationPath, fsType, mountFlags, options);
if (ret) {
HiLog::Error(LABEL, "bind mount %{public}s to %{public}s failed %{public}d", originPath,
APPSPAWN_CHECK(ret == 0, return ret, "bind mount %s to %s failed %d", originPath,
destinationPath, errno);
return ret;
}
ret = mount(NULL, destinationPath, NULL, MS_PRIVATE, NULL);
if (ret) {
HiLog::Error(LABEL, "private mount to %{public}s failed %{public}d", destinationPath, errno);
return ret;
}
APPSPAWN_CHECK(ret == 0, return ret, "private mount to %s failed %d", destinationPath, errno);
#endif
return 0;
}
@ -249,8 +237,8 @@ std::string SandboxUtils::GetSbxPathByConfig(const ClientSocket::AppProperty *ap
sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot);
} else {
sandboxRoot = SANDBOX_DIR + appProperty->bundleName;
HiLog::Error(LABEL, "read sandbox-root config failed, set sandbox-root to default root"
"app name is %{public}s", appProperty->bundleName);
APPSPAWN_LOGE("read sandbox-root config failed, set sandbox-root to default root"
"app name is %s", appProperty->bundleName);
}
return sandboxRoot;
@ -273,11 +261,9 @@ bool SandboxUtils::GetSbxSwitchStatusByConfig(nlohmann::json &config)
static bool CheckMountConfig(nlohmann::json &mntPoint, const ClientSocket::AppProperty *appProperty)
{
if (mntPoint.find(SRC_PATH) == mntPoint.end() || mntPoint.find(SANDBOX_PATH) == mntPoint.end()
|| mntPoint.find(SANDBOX_FLAGS) == mntPoint.end()) {
HiLog::Error(LABEL, "read mount config failed, app name is %{public}s", appProperty->bundleName);
return false;
}
bool istrue = mntPoint.find(SRC_PATH) == mntPoint.end() || mntPoint.find(SANDBOX_PATH) == mntPoint.end()
|| mntPoint.find(SANDBOX_FLAGS) == mntPoint.end();
APPSPAWN_CHECK(!istrue, return false, "read mount config failed, app name is %s", appProperty->bundleName);
if (mntPoint[APP_APL_NAME] != nullptr) {
std::string app_apl_name = mntPoint[APP_APL_NAME];
@ -296,10 +282,7 @@ static int32_t DoDlpAppMountStrategy(const ClientSocket::AppProperty *appPropert
const std::string &fsType, unsigned long mountFlags)
{
int fd = open("/dev/fuse", O_RDWR);
if (fd == -1) {
HiLog::Error(LABEL, "open /dev/fuse failed, errno is %{public}d", errno);
return -EINVAL;
}
APPSPAWN_CHECK(fd != -1, return -EINVAL, "open /dev/fuse failed, errno is %d", errno);
char options[FUSE_OPTIONS_MAX_LEN];
(void)sprintf_s(options, sizeof(options), "fd=%d,rootmode=40000,user_id=%d,group_id=%d", fd,
@ -308,27 +291,19 @@ static int32_t DoDlpAppMountStrategy(const ClientSocket::AppProperty *appPropert
// To make sure destinationPath exist
MakeDirRecursive(sandboxPath, FILE_MODE);
int ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options);
if (ret) {
HiLog::Error(LABEL, "DoDlpAppMountStrategy failed, bind mount %{public}s to %{public}s"
"failed %{public}d", srcPath.c_str(), sandboxPath.c_str(), errno);
return ret;
}
int ret = 0;
#ifndef APPSPAWN_TEST
ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options);
APPSPAWN_CHECK(ret == 0, return ret, "DoDlpAppMountStrategy failed, bind mount %s to %s"
"failed %d", srcPath.c_str(), sandboxPath.c_str(), errno);
ret = mount(NULL, sandboxPath.c_str(), NULL, MS_PRIVATE, NULL);
if (ret) {
HiLog::Error(LABEL, "private mount to %{public}s failed %{public}d", sandboxPath.c_str(), errno);
return ret;
}
APPSPAWN_CHECK(ret == 0, return ret, "private mount to %s failed %d", sandboxPath.c_str(), errno);
#endif
/* close DLP_FUSE_FD and dup FD to it */
close(DLP_FUSE_FD);
ret = dup2(fd, DLP_FUSE_FD);
if (ret == -1) {
HiLog::Error(LABEL, "dup fuse fd %{public}d failed, errno is %{public}d",
fd, errno);
}
APPSPAWN_CHECK_ONLY_LOG(ret != -1, "dup fuse fd %d failed, errno is %d", fd, errno);
return ret;
}
@ -354,8 +329,8 @@ static int32_t HandleSpecialAppMount(const ClientSocket::AppProperty *appPropert
int SandboxUtils::DoAllMntPointsMount(const ClientSocket::AppProperty *appProperty, nlohmann::json &appConfig)
{
if (appConfig.find(MOUNT_PREFIX) == appConfig.end()) {
HiLog::Debug(LABEL, "mount config is not found, maybe reuslt sandbox launch failed"
"app name is %{public}s", appProperty->bundleName);
APPSPAWN_LOGV("mount config is not found, maybe reuslt sandbox launch failed"
"app name is %s", appProperty->bundleName);
return 0;
}
@ -390,7 +365,7 @@ int SandboxUtils::DoAllMntPointsMount(const ClientSocket::AppProperty *appProper
}
}
if (ret) {
HiLog::Error(LABEL, "DoAppSandboxMountOnce failed, %{public}s", sandboxPath.c_str());
APPSPAWN_LOGE("DoAppSandboxMountOnce failed, %s", sandboxPath.c_str());
std::string actionStatus = STATUS_CHECK;
(void)JsonUtils::GetStringFromJson(mntPoint, ACTION_STATUS, actionStatus);
@ -407,11 +382,8 @@ int SandboxUtils::DoAllMntPointsMount(const ClientSocket::AppProperty *appProper
int SandboxUtils::DoAllSymlinkPointslink(const ClientSocket::AppProperty *appProperty, nlohmann::json &appConfig)
{
if (appConfig.find(SYMLINK_PREFIX) == appConfig.end()) {
HiLog::Debug(LABEL, "symlink config is not found, maybe reuslt sandbox launch failed"
"app name is %{public}s", appProperty->bundleName);
return 0;
}
APPSPAWN_CHECK(appConfig.find(SYMLINK_PREFIX) != appConfig.end(), return 0, "symlink config is not found,"
"maybe reuslt sandbox launch failed app name is %s", appProperty->bundleName);
nlohmann::json symlinkPoints = appConfig[SYMLINK_PREFIX];
std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig);
@ -422,17 +394,17 @@ int SandboxUtils::DoAllSymlinkPointslink(const ClientSocket::AppProperty *appPro
// Check the validity of the symlink configuration
if (symPoint.find(TARGET_NAME) == symPoint.end() || symPoint.find(LINK_NAME) == symPoint.end()) {
HiLog::Error(LABEL, "read symlink config failed, app name is %{public}s", appProperty->bundleName);
APPSPAWN_LOGE("read symlink config failed, app name is %s", appProperty->bundleName);
continue;
}
std::string targetName = ConvertToRealPath(appProperty, symPoint[TARGET_NAME].get<std::string>());
std::string linkName = sandboxRoot + ConvertToRealPath(appProperty, symPoint[LINK_NAME].get<std::string>());
HiLog::Debug(LABEL, "symlink, from %{public}s to %{public}s", targetName.c_str(), linkName.c_str());
APPSPAWN_LOGV("symlink, from %s to %s", targetName.c_str(), linkName.c_str());
int ret = symlink(targetName.c_str(), linkName.c_str());
if (ret && errno != EEXIST) {
HiLog::Error(LABEL, "symlink failed, %{public}s, errno is %{public}d", linkName.c_str(), errno);
APPSPAWN_LOGE("symlink failed, %s, errno is %d", linkName.c_str(), errno);
std::string actionStatus = STATUS_CHECK;
(void)JsonUtils::GetStringFromJson(symPoint, ACTION_STATUS, actionStatus);
@ -514,16 +486,10 @@ int32_t SandboxUtils::SetPrivateAppSandboxProperty_(const ClientSocket::AppPrope
int ret = 0;
ret = DoSandboxFilePrivateBind(appProperty, config);
if (ret) {
HiLog::Error(LABEL, "DoSandboxFilePrivateBind failed");
return ret;
}
APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePrivateBind failed");
ret = DoSandboxFilePrivateSymlink(appProperty, config);
if (ret) {
HiLog::Error(LABEL, "DoSandboxFilePrivateSymlink failed");
}
APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateSymlink failed");
return ret;
}
@ -534,15 +500,9 @@ int32_t SandboxUtils::SetPrivateAppSandboxProperty(const ClientSocket::AppProper
int ret = 0;
ret = SetPrivateAppSandboxProperty_(appProperty, config);
if (ret) {
HiLog::Error(LABEL, "parse adddata-sandbox config failed");
return ret;
}
APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed");
ret = SetPrivateAppSandboxProperty_(appProperty, productConfig);
if (ret) {
HiLog::Error(LABEL, "parse product-sandbox config failed");
}
APPSPAWN_CHECK_ONLY_LOG(ret == 0, "parse product-sandbox config failed");
return ret;
}
@ -553,19 +513,13 @@ int32_t SandboxUtils::SetCommonAppSandboxProperty_(const ClientSocket::AppProper
int rc = 0;
rc = DoSandboxFileCommonBind(appProperty, config);
if (rc) {
HiLog::Error(LABEL, "DoSandboxFileCommonBind failed, %{public}s", appProperty->bundleName);
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonBind failed, %s", appProperty->bundleName);
// if sandbox switch is off, don't do symlink work again
if (CheckAppSandboxSwitchStatus(appProperty) == true && (CheckTotalSandboxSwitchStatus(appProperty) == true)) {
rc = DoSandboxFileCommonSymlink(appProperty, config);
if (rc) {
HiLog::Error(LABEL, "DoSandboxFileCommonSymlink failed, %{public}s", appProperty->bundleName);
}
APPSPAWN_CHECK_ONLY_LOG(rc == 0, "DoSandboxFileCommonSymlink failed, %s", appProperty->bundleName);
}
return rc;
}
@ -577,16 +531,10 @@ int32_t SandboxUtils::SetCommonAppSandboxProperty(const ClientSocket::AppPropert
int ret = 0;
ret = SetCommonAppSandboxProperty_(appProperty, jsonConfig);
if (ret) {
HiLog::Error(LABEL, "parse appdata config for common failed, %{public}s", sandboxPackagePath.c_str());
return ret;
}
APPSPAWN_CHECK(ret == 0, return ret, "parse appdata config for common failed, %s", sandboxPackagePath.c_str());
ret = SetCommonAppSandboxProperty_(appProperty, productConfig);
if (ret) {
HiLog::Error(LABEL, "parse product config for common failed, %{public}s", sandboxPackagePath.c_str());
return ret;
}
APPSPAWN_CHECK(ret == 0, return ret, "parse product config for common failed, %s", sandboxPackagePath.c_str());
if (strcmp(appProperty->apl, APL_SYSTEM_BASIC.data()) == 0 ||
strcmp(appProperty->apl, APL_SYSTEM_CORE.data()) == 0) {
@ -601,33 +549,30 @@ int32_t SandboxUtils::SetCommonAppSandboxProperty(const ClientSocket::AppPropert
int32_t SandboxUtils::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath)
{
#ifndef APPSPAWN_TEST
int rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
if (rc) {
HiLog::Error(LABEL, "set propagation slave failed");
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "set propagation slave failed");
#endif
MakeDirRecursive(sandboxPackagePath, FILE_MODE);
// bind mount "/" to /mnt/sandbox/<packageName> path
// rootfs: to do more resources bind mount here to get more strict resources constraints
#ifndef APPSPAWN_TEST
rc = mount("/", sandboxPackagePath.c_str(), NULL, BASIC_MOUNT_FLAGS, NULL);
if (rc) {
HiLog::Error(LABEL, "mount bind / failed, %{public}d", errno);
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "mount bind / failed, %d", errno);
#endif
return 0;
}
int32_t SandboxUtils::DoSandboxRootFolderCreate(const ClientSocket::AppProperty *appProperty,
std::string &sandboxPackagePath)
{
#ifndef APPSPAWN_TEST
int rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
if (rc) {
return rc;
}
#endif
DoAppSandboxMountOnce(sandboxPackagePath.c_str(), sandboxPackagePath.c_str(), "",
BASIC_MOUNT_FLAGS, nullptr);
@ -661,7 +606,7 @@ bool SandboxUtils::CheckAppSandboxSwitchStatus(const ClientSocket::AppProperty *
if (privateAppConfig.find(appProperty->bundleName) != privateAppConfig.end()) {
nlohmann::json appConfig = privateAppConfig[appProperty->bundleName][0];
rc = GetSbxSwitchStatusByConfig(appConfig);
HiLog::Error(LABEL, "CheckAppSandboxSwitchStatus middle, %{public}d", rc);
APPSPAWN_LOGE("CheckAppSandboxSwitchStatus middle, %d", rc);
}
// default sandbox switch is on
@ -678,10 +623,7 @@ int32_t SandboxUtils::SetAppSandboxProperty(const ClientSocket::AppProperty *app
// add pid to a new mnt namespace
int rc = unshare(CLONE_NEWNS);
if (rc) {
HiLog::Error(LABEL, "unshare failed, packagename is %{public}s", bundleName.c_str());
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %s", bundleName.c_str());
// to make wargnar work and check app sandbox switch
if (access(WARGNAR_DEVICE_PATH, F_OK) == 0 || (CheckTotalSandboxSwitchStatus(appProperty) == false) ||
@ -690,43 +632,26 @@ int32_t SandboxUtils::SetAppSandboxProperty(const ClientSocket::AppProperty *app
} else {
rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath);
}
if (rc) {
HiLog::Error(LABEL, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str());
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %s", bundleName.c_str());
rc = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath);
if (rc) {
HiLog::Error(LABEL, "SetCommonAppSandboxProperty failed, packagename is %{public}s", bundleName.c_str());
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "SetCommonAppSandboxProperty failed, packagename is %s", bundleName.c_str());
rc = SetPrivateAppSandboxProperty(appProperty);
if (rc) {
HiLog::Error(LABEL, "SetPrivateAppSandboxProperty failed, packagename is %{public}s", bundleName.c_str());
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "SetPrivateAppSandboxProperty failed, packagename is %s", bundleName.c_str());
rc = chdir(sandboxPackagePath.c_str());
if (rc) {
HiLog::Error(LABEL, "chdir failed, packagename is %{public}s, path is %{public}s", \
bundleName.c_str(), sandboxPackagePath.c_str());
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "chdir failed, packagename is %s, path is %s",
bundleName.c_str(), sandboxPackagePath.c_str());
#ifndef APPSPAWN_TEST
rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
if (rc) {
HiLog::Error(LABEL, "pivot root failed, packagename is %{public}s, errno is %{public}d", \
bundleName.c_str(), errno);
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "pivot root failed, packagename is %s, errno is %d",
bundleName.c_str(), errno);
#endif
rc = umount2(".", MNT_DETACH);
if (rc) {
HiLog::Error(LABEL, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str());
return rc;
}
APPSPAWN_CHECK(rc == 0, return rc, "MNT_DETACH failed, packagename is %s", bundleName.c_str());
return 0;
}
} // namespace AppSpawn