!734 nweb 合一

Merge pull request !734 from wxt/nweb_code_refine
This commit is contained in:
openharmony_ci 2023-07-29 04:12:28 +00:00 committed by Gitee
commit 3bfafb5714
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 75 additions and 266 deletions

View File

@ -33,35 +33,26 @@ const char* RENDERER_NAME = "renderer";
#include "tokenid_kit.h"
#include "access_token.h"
#define NWEBSPAWN_SERVER_NAME "nwebspawn"
using namespace OHOS::Security::AccessToken;
int SetAppAccessToken(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
uint64_t tokenId = appProperty->property.accessTokenIdEx;
int32_t ret = SetSelfTokenID(tokenId);
if (ret != 0) {
APPSPAWN_LOGE("AppSpawnServer::set access token id failed, ret = %{public}d", ret);
return -1;
int32_t ret = 0;
uint64_t tokenId = 0;
if (content->isNweb) {
TokenIdKit tokenIdKit;
tokenId = tokenIdKit.GetRenderTokenID(appProperty->property.accessTokenIdEx);
if (tokenId == static_cast<uint64_t>(INVALID_TOKENID)) {
APPSPAWN_LOGE("AppSpawnServer::Failed to get render token id, renderTokenId =%{public}llu",
static_cast<unsigned long long>(tokenId));
return -1;
}
} else {
tokenId = appProperty->property.accessTokenIdEx;
}
APPSPAWN_LOGV("AppSpawnServer::set access token id = %{public}llu, ret = %{public}d %{public}d",
static_cast<unsigned long long>(appProperty->property.accessTokenIdEx), ret, getuid());
return 0;
}
int SetAppAccessTokenNweb(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
TokenIdKit tokenIdKit;
uint64_t tokenId = tokenIdKit.GetRenderTokenID(appProperty->property.accessTokenIdEx);
if (tokenId == static_cast<uint64_t>(INVALID_TOKENID)) {
APPSPAWN_LOGE("AppSpawnServer::Failed to get render token id, renderTokenId =%{public}llu",
static_cast<unsigned long long>(tokenId));
return -1;
}
int32_t ret = SetSelfTokenID(tokenId);
ret = SetSelfTokenID(tokenId);
if (ret != 0) {
APPSPAWN_LOGE("AppSpawnServer::set access token id failed, ret = %{public}d", ret);
return -1;
@ -75,57 +66,45 @@ int SetAppAccessTokenNweb(struct AppSpawnContent_ *content, AppSpawnClient *clie
int SetSelinuxCon(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
#ifdef WITH_SELINUX
UNUSED(content);
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
HapContext hapContext;
HapDomainInfo hapDomainInfo;
hapDomainInfo.apl = appProperty->property.apl;
hapDomainInfo.packageName = appProperty->property.processName;
hapDomainInfo.hapFlags = appProperty->property.hapFlags;
if ((appProperty->property.flags & APP_DEBUGGABLE) != 0) {
hapDomainInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
}
int32_t ret = hapContext.HapDomainSetcontext(hapDomainInfo);
if (ret != 0) {
APPSPAWN_LOGE("AppSpawnServer::Failed to hap domain set context, errno = %{public}d %{public}s",
errno, appProperty->property.apl);
return -1;
if (content->isNweb) {
setcon("u:r:isolated_render:s0");
} else {
APPSPAWN_LOGV("AppSpawnServer::Success to hap domain set context, ret = %{public}d", ret);
UNUSED(content);
AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
HapContext hapContext;
HapDomainInfo hapDomainInfo;
hapDomainInfo.apl = appProperty->property.apl;
hapDomainInfo.packageName = appProperty->property.processName;
hapDomainInfo.hapFlags = appProperty->property.hapFlags;
if ((appProperty->property.flags & APP_DEBUGGABLE) != 0) {
hapDomainInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
}
int32_t ret = hapContext.HapDomainSetcontext(hapDomainInfo);
if (ret != 0) {
APPSPAWN_LOGE("AppSpawnServer::Failed to hap domain set context, errno = %{public}d %{public}s",
errno, appProperty->property.apl);
return -1;
} else {
APPSPAWN_LOGV("AppSpawnServer::Success to hap domain set context, ret = %{public}d", ret);
}
}
#endif
return 0;
}
void SetSelinuxConNweb(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
#ifdef WITH_SELINUX
setcon("u:r:isolated_render:s0");
#endif
}
void SetUidGidFilter(struct AppSpawnContent_ *content)
{
#ifdef WITH_SECCOMP
if (!SetSeccompPolicyWithName(INDIVIDUAL, APPSPAWN_NAME)) {
APPSPAWN_LOGE("Failed to set APPSPAWN seccomp filter and exit");
#ifndef APPSPAWN_TEST
_exit(0x7f);
#endif
bool ret = false;
if (content->isNweb) {
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
APPSPAWN_LOGE("Failed to set no new privs");
}
ret = SetSeccompPolicyWithName(INDIVIDUAL, NWEBSPAWN_NAME);
} else {
APPSPAWN_LOGI("Success to set APPSPAWN seccomp filter");
ret = SetSeccompPolicyWithName(INDIVIDUAL, APPSPAWN_NAME);
}
#endif
}
void SetUidGidFilterNweb(struct AppSpawnContent_ *content)
{
#ifdef WITH_SECCOMP
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
APPSPAWN_LOGE("Failed to set no new privs");
}
if (!SetSeccompPolicyWithName(INDIVIDUAL, NWEBSPAWN_NAME)) {
if (!ret) {
APPSPAWN_LOGE("Failed to set APPSPAWN seccomp filter and exit");
#ifndef APPSPAWN_TEST
_exit(0x7f);
@ -141,23 +120,10 @@ int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client)
#ifdef WITH_SECCOMP
const char *appName = APP_NAME;
SeccompFilterType type = APP;
if (!SetSeccompPolicyWithName(type, appName)) {
APPSPAWN_LOGE("Failed to set %{public}s seccomp filter and exit", appName);
#ifndef APPSPAWN_TEST
return -EINVAL;
#endif
} else {
APPSPAWN_LOGI("Success to set %{public}s seccomp filter", appName);
if (content->isNweb) {
appName = RENDERER_NAME;
type = INDIVIDUAL;
}
#endif
return 0;
}
int SetSeccompFilterNweb(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
#ifdef WITH_SECCOMP
const char *appName = RENDERER_NAME;
SeccompFilterType type = INDIVIDUAL;
if (!SetSeccompPolicyWithName(type, appName)) {
APPSPAWN_LOGE("Failed to set %{public}s seccomp filter and exit", appName);
#ifndef APPSPAWN_TEST

View File

@ -25,20 +25,15 @@ extern "C" {
#endif
int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *client);
int32_t SetAppSandboxPropertyNweb(struct AppSpawnContent_ *content, AppSpawnClient *client);
int SetAppAccessToken(struct AppSpawnContent_ *content, AppSpawnClient *client);
int SetAppAccessTokenNweb(struct AppSpawnContent_ *content, AppSpawnClient *client);
int SetSelinuxCon(struct AppSpawnContent_ *content, AppSpawnClient *client);
void SetSelinuxConNweb(struct AppSpawnContent_ *content, AppSpawnClient *client);
void LoadExtendLib(AppSpawnContent *content);
void LoadExtendLibNweb(AppSpawnContent *content);
void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client);
void RunChildProcessorNweb(AppSpawnContent *content, AppSpawnClient *client);
void LoadAppSandboxConfig(void);
void SetUidGidFilter(struct AppSpawnContent_ *content);
void SetUidGidFilterNweb(struct AppSpawnContent_ *content);
int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client);
int SetSeccompFilterNweb(struct AppSpawnContent_ *content, AppSpawnClient *client);
uint32_t GetAppNamespaceFlags(const char *bundleName);
void HandleInternetPermission(const AppSpawnClient *client);

View File

@ -68,43 +68,13 @@ int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *
if ((client->cloneFlags & CLONE_NEWNS) != CLONE_NEWNS) {
return 0;
}
int ret = SandboxUtils::SetAppSandboxProperty(client);
// free HspList
if (clientExt->property.hspList.data != nullptr) {
free(clientExt->property.hspList.data);
clientExt->property.hspList = {};
int ret = 0;
if (content->isNweb) {
ret = SandboxUtils::SetAppSandboxPropertyNweb(client);
} else {
ret = SandboxUtils::SetAppSandboxProperty(client);
}
// free OverlayInfo
if (clientExt->property.overlayInfo.data != nullptr) {
free(clientExt->property.overlayInfo.data);
clientExt->property.overlayInfo = {};
}
// free dataGroupInfoList
if (clientExt->property.dataGroupInfoList.data != nullptr) {
free(clientExt->property.dataGroupInfoList.data);
clientExt->property.dataGroupInfoList = {};
}
// for module test do not create sandbox
if (strncmp(clientExt->property.bundleName,
MODULE_TEST_BUNDLE_NAME.c_str(), MODULE_TEST_BUNDLE_NAME.size()) == 0) {
return 0;
}
return ret;
}
int32_t SetAppSandboxPropertyNweb(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
APPSPAWN_CHECK(client != NULL, return -1, "Invalid nwebspwn client");
AppSpawnClientExt *clientExt = reinterpret_cast<AppSpawnClientExt *>(client);
// no sandbox
if (clientExt->property.flags & APP_NO_SANDBOX) {
return 0;
}
// no news
if ((client->cloneFlags & CLONE_NEWNS) != CLONE_NEWNS) {
return 0;
}
int ret = SandboxUtils::SetAppSandboxPropertyNweb(client);
// free HspList
if (clientExt->property.hspList.data != nullptr) {
free(clientExt->property.hspList.data);

View File

@ -20,7 +20,7 @@
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
#include "beget_ext.h"
#include "hilog/log.h"
#include "securec.h"
@ -48,6 +48,7 @@ typedef struct AppSpawnClient_ {
typedef struct AppSpawnContent_ {
char *longProcName;
uint32_t longProcNameLen;
bool isNweb;
// system
void (*loadExtendLib)(struct AppSpawnContent_ *content);

View File

@ -162,47 +162,6 @@ static int SetCapabilities(struct AppSpawnContent_ *content, AppSpawnClient *cli
return 0;
}
static int SetCapabilitiesNweb(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
// init cap
struct __user_cap_header_struct cap_header;
bool isRet = memset_s(&cap_header, sizeof(cap_header), 0, sizeof(cap_header)) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap header");
cap_header.version = _LINUX_CAPABILITY_VERSION_3;
cap_header.pid = 0;
struct __user_cap_data_struct cap_data[2];
isRet = memset_s(&cap_data, sizeof(cap_data), 0, sizeof(cap_data)) != EOK;
APPSPAWN_CHECK(!isRet, return -EINVAL, "Failed to memset cap data");
// init inheritable permitted effective zero
#ifdef GRAPHIC_PERMISSION_CHECK
const uint64_t inheriTable = 0;
const uint64_t permitted = 0;
const uint64_t effective = 0;
#else
const uint64_t inheriTable = 0x3fffffffff;
const uint64_t permitted = 0x3fffffffff;
const uint64_t effective = 0x3fffffffff;
#endif
cap_data[0].inheritable = (__u32)(inheriTable);
cap_data[1].inheritable = (__u32)(inheriTable >> BITLEN32);
cap_data[0].permitted = (__u32)(permitted);
cap_data[1].permitted = (__u32)(permitted >> BITLEN32);
cap_data[0].effective = (__u32)(effective);
cap_data[1].effective = (__u32)(effective >> BITLEN32);
// set capabilities
isRet = capset(&cap_header, &cap_data[0]) == -1;
APPSPAWN_CHECK(!isRet, return -errno, "capset failed: %{public}d", errno);
SetSelinuxConNweb(content, client);
return 0;
}
static void InitDebugParams(struct AppSpawnContent_ *content, AppSpawnClient *client)
{
#ifndef APPSPAWN_TEST
@ -717,19 +676,11 @@ void SetContentFunction(AppSpawnContent *content)
#ifdef ASAN_DETECTOR
content->getWrapBundleNameValue = GetWrapBundleNameValue;
#endif
if (strcmp(content->longProcName, NWEBSPAWN_SERVER_NAME) == 0) {
content->setAppSandbox = SetAppSandboxPropertyNweb;
content->setSeccompFilter = SetSeccompFilterNweb;
content->setUidGidFilter = SetUidGidFilterNweb;
content->setAppAccessToken = SetAppAccessTokenNweb;
content->setCapabilities = SetCapabilitiesNweb;
} else {
content->setAppAccessToken = SetAppAccessToken;
content->setAppSandbox = SetAppSandboxProperty;
content->setSeccompFilter = SetSeccompFilter;
content->setUidGidFilter = SetUidGidFilter;
content->setCapabilities = SetCapabilities;
}
content->setAppSandbox = SetAppSandboxProperty;
content->setCapabilities = SetCapabilities;
content->setUidGidFilter = SetUidGidFilter;
content->setSeccompFilter = SetSeccompFilter;
content->setAppAccessToken = SetAppAccessToken;
content->handleInternetPermission = HandleInternetPermission;
content->waitForDebugger = WaitForDebugger;
}

View File

@ -479,42 +479,15 @@ static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer,
return;
}
APPSPAWN_CHECK(appProperty->property.gidCount <= APP_MAX_GIDS && strlen(appProperty->property.processName) > 0,
LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return, "Invalid property %{public}u", appProperty->property.gidCount);
// special handle bundle name medialibrary and scanner
HandleSpecial(appProperty);
if (g_appSpawnContent->timer != NULL) {
LE_StopTimer(LE_GetDefaultLoop(), g_appSpawnContent->timer);
g_appSpawnContent->timer = NULL;
if (g_appSpawnContent->content.isNweb) {
// get render process termination status, only nwebspawn need this logic.
if (appProperty->property.code == GET_RENDER_TERMINATION_STATUS) {
int ret = GetProcessTerminationStatus(&appProperty->client);
RemoveAppInfo(appProperty->property.pid);
SendResponse(appProperty, (char *)&ret, sizeof(ret));
return;
}
}
appProperty->pid = 0;
CheckColdAppEnabled(appProperty);
int ret = HandleMessage(appProperty);
if (ret != 0) {
LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
}
}
static void OnReceiveRequestNweb(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen)
{
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)LE_GetUserData(taskHandle);
APPSPAWN_CHECK(appProperty != NULL, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return, "alloc client Failed");
if (!ReceiveRequestData(taskHandle, appProperty, buffer, buffLen)) {
return;
}
// get render process termination status, only nwebspawn need this logic.
if (appProperty->property.code == GET_RENDER_TERMINATION_STATUS) {
int ret = GetProcessTerminationStatus(&appProperty->client);
RemoveAppInfo(appProperty->property.pid);
SendResponse(appProperty, (char *)&ret, sizeof(ret));
return;
}
APPSPAWN_CHECK(appProperty->property.gidCount <= APP_MAX_GIDS && strlen(appProperty->property.processName) > 0,
LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
return, "Invalid property %{public}u", appProperty->property.gidCount);
@ -575,48 +548,6 @@ APPSPAWN_STATIC TaskHandle AcceptClient(const LoopHandle loopHandle, const TaskH
return stream;
}
APPSPAWN_STATIC TaskHandle AcceptClientNweb(const LoopHandle loopHandle, const TaskHandle server, uint32_t flags)
{
static uint32_t clientId = 0;
TaskHandle stream;
LE_StreamInfo info = {};
info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
info.baseInfo.flags |= flags;
info.baseInfo.close = OnClose;
info.baseInfo.userDataSize = sizeof(AppSpawnClientExt);
info.disConnectComplete = NULL;
info.sendMessageComplete = SendMessageComplete;
info.recvMessage = OnReceiveRequestNweb;
LE_STATUS ret = LE_AcceptStreamClient(loopHandle, server, &stream, &info);
APPSPAWN_CHECK(ret == 0, return NULL, "Failed to alloc stream");
AppSpawnClientExt *client = (AppSpawnClientExt *)LE_GetUserData(stream);
APPSPAWN_CHECK(client != NULL, return NULL, "Failed to alloc stream");
#ifndef APPSPAWN_CHECK_GID_UID
struct ucred cred = {-1, -1, -1};
socklen_t credSize = sizeof(struct ucred);
if ((getsockopt(LE_GetSocketFd(stream), SOL_SOCKET, SO_PEERCRED, &cred, &credSize) < 0) ||
(cred.uid != DecodeUid("foundation") && cred.uid != DecodeUid("root"))) {
APPSPAWN_LOGE("Failed to check uid %{public}d", cred.uid);
LE_CloseStreamTask(LE_GetDefaultLoop(), stream);
return NULL;
}
#endif
client->stream = stream;
client->client.id = ++clientId;
client->client.flags = 0;
client->property.hspList.totalLength = 0;
client->property.hspList.savedLength = 0;
client->property.hspList.data = NULL;
client->property.overlayInfo.totalLength = 0;
client->property.overlayInfo.data = NULL;
client->property.dataGroupInfoList.totalLength = 0;
client->property.dataGroupInfoList.data = NULL;
APPSPAWN_LOGI("OnConnection client fd %{public}d Id %{public}d", LE_GetSocketFd(stream), client->client.id);
return stream;
}
static int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
{
APPSPAWN_CHECK(server != NULL && loopHandle != NULL, return -1, "Error server");
@ -624,13 +555,6 @@ static int OnConnection(const LoopHandle loopHandle, const TaskHandle server)
return 0;
}
static int OnConnectionNweb(const LoopHandle loopHandle, const TaskHandle server)
{
APPSPAWN_CHECK(server != NULL && loopHandle != NULL, return -1, "Error server");
(void)AcceptClientNweb(loopHandle, server, 0);
return 0;
}
static void NotifyResToParent(struct AppSpawnContent_ *content, AppSpawnClient *client, int result)
{
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
@ -697,7 +621,7 @@ static void AppSpawnRun(AppSpawnContent *content, int argc, char *const argv[])
LE_STATUS status;
if (strcmp(content->longProcName, NWEBSPAWN_SERVER_NAME) == 0) {
if (content->isNweb) {
status = LE_CreateSignalTask(LE_GetDefaultLoop(), &appSpawnContent->sigHandler, SignalHandlerNweb);
} else {
status = LE_CreateSignalTask(LE_GetDefaultLoop(), &appSpawnContent->sigHandler, SignalHandler);
@ -752,11 +676,7 @@ static int CreateAppSpawnServer(AppSpawnContentExt *appSpawnContent, const char
info.socketId = socketId;
info.server = path;
info.baseInfo.close = NULL;
if (strcmp(socketName, NWEBSPAWN_SOCKET_NAME) == 0) {
info.incommingConnect = OnConnectionNweb;
} else {
info.incommingConnect = OnConnection;
}
info.incommingConnect = OnConnection;
ret = LE_CreateStreamServer(LE_GetDefaultLoop(), &appSpawnContent->server, &info);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to create socket for %{public}s", path);
@ -764,7 +684,7 @@ static int CreateAppSpawnServer(AppSpawnContentExt *appSpawnContent, const char
ret = chmod(path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
APPSPAWN_CHECK(ret == 0, return -1, "Failed to chmod %{public}s, err %{public}d. ", path, errno);
#ifndef APPSPAWN_CHECK_GID_UID
if (strcmp(socketName, NWEBSPAWN_SOCKET_NAME) == 0) {
if (appSpawnContent->content.isNweb) {
ret = lchown(path, 3081, 3081); // 3081 is appspawn gid
} else {
ret = lchown(path, 0, 4000); // 4000 is appspawn gid
@ -787,6 +707,11 @@ AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcNam
(void)memset_s(&appSpawnContent->content, sizeof(appSpawnContent->content), 0, sizeof(appSpawnContent->content));
appSpawnContent->content.longProcName = longProcName;
appSpawnContent->content.longProcNameLen = longProcNameLen;
if (strcmp(longProcName, NWEBSPAWN_SERVER_NAME) == 0) {
appSpawnContent->content.isNweb = true;
} else {
appSpawnContent->content.isNweb = false;
}
appSpawnContent->timer = NULL;
appSpawnContent->flags = 0;
appSpawnContent->server = NULL;

View File

@ -17,6 +17,7 @@
#define APPSPAWN_SERVICE_H
#include <unistd.h>
#include <stdbool.h>
#include "appspawn_msg.h"
#include "appspawn_server.h"
#include "init_hashmap.h"