1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "appspawn_adapter.h"
17 #include "param_helper.h"
18
19 #include <cerrno>
20
21 #include "selinux/selinux.h"
22
23 #include "appspawn_service.h"
24 #ifdef WITH_SELINUX
25 #include "hap_restorecon.h"
26 #endif
27 #include "token_setproc.h"
28 #ifdef WITH_SECCOMP
29 #include "seccomp_policy.h"
30 #include <sys/prctl.h>
31
32 const char* RENDERER_NAME = "renderer";
33 #endif
34
35 #include "tokenid_kit.h"
36 #include "access_token.h"
37 #define NWEBSPAWN_SERVER_NAME "nwebspawn"
38 using namespace OHOS::Security::AccessToken;
39
SetAppAccessToken(struct AppSpawnContent_ * content,AppSpawnClient * client)40 int SetAppAccessToken(struct AppSpawnContent_ *content, AppSpawnClient *client)
41 {
42 AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
43 int32_t ret = 0;
44 uint64_t tokenId = 0;
45 if (content->isNweb) {
46 TokenIdKit tokenIdKit;
47 tokenId = tokenIdKit.GetRenderTokenID(appProperty->property.accessTokenIdEx);
48 if (tokenId == static_cast<uint64_t>(INVALID_TOKENID)) {
49 APPSPAWN_LOGE("AppSpawnServer::Failed to get render token id, renderTokenId =%{public}llu",
50 static_cast<unsigned long long>(tokenId));
51 return -1;
52 }
53 } else {
54 tokenId = appProperty->property.accessTokenIdEx;
55 }
56 ret = SetSelfTokenID(tokenId);
57 if (ret != 0) {
58 APPSPAWN_LOGE("AppSpawnServer::set access token id failed, ret = %{public}d", ret);
59 return -1;
60 }
61
62 APPSPAWN_LOGV("AppSpawnServer::set access token id = %{public}llu, ret = %{public}d %{public}d",
63 static_cast<unsigned long long>(appProperty->property.accessTokenIdEx), ret, getuid());
64 return 0;
65 }
66
SetSelinuxCon(struct AppSpawnContent_ * content,AppSpawnClient * client)67 int SetSelinuxCon(struct AppSpawnContent_ *content, AppSpawnClient *client)
68 {
69 #ifdef WITH_SELINUX
70 if (content->isNweb) {
71 setcon("u:r:isolated_render:s0");
72 } else {
73 UNUSED(content);
74 AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
75 if (appProperty->property.code == SPAWN_NATIVE_PROCESS) {
76 if (!IsDeveloperModeOn()) {
77 APPSPAWN_LOGE("Denied Launching a native process: not in developer mode");
78 return -1;
79 }
80 return 0;
81 }
82 HapContext hapContext;
83 HapDomainInfo hapDomainInfo;
84 hapDomainInfo.apl = appProperty->property.apl;
85 hapDomainInfo.packageName = appProperty->property.processName;
86 hapDomainInfo.hapFlags = appProperty->property.hapFlags;
87 if ((appProperty->property.flags & APP_DEBUGGABLE) != 0) {
88 hapDomainInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
89 }
90 int32_t ret = hapContext.HapDomainSetcontext(hapDomainInfo);
91 if (ret != 0) {
92 APPSPAWN_LOGE("AppSpawnServer::Failed to hap domain set context, errno = %{public}d %{public}s",
93 errno, appProperty->property.apl);
94 return -1;
95 } else {
96 APPSPAWN_LOGV("AppSpawnServer::Success to hap domain set context, ret = %{public}d", ret);
97 }
98 }
99 #endif
100 return 0;
101 }
102
SetUidGidFilter(struct AppSpawnContent_ * content)103 void SetUidGidFilter(struct AppSpawnContent_ *content)
104 {
105 #ifdef WITH_SECCOMP
106 bool ret = false;
107 if (content->isNweb) {
108 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
109 APPSPAWN_LOGE("Failed to set no new privs");
110 }
111 ret = SetSeccompPolicyWithName(INDIVIDUAL, NWEBSPAWN_NAME);
112 } else {
113 ret = SetSeccompPolicyWithName(INDIVIDUAL, APPSPAWN_NAME);
114 }
115 if (!ret) {
116 APPSPAWN_LOGE("Failed to set APPSPAWN seccomp filter and exit");
117 #ifndef APPSPAWN_TEST
118 _exit(0x7f);
119 #endif
120 } else {
121 APPSPAWN_LOGI("Success to set APPSPAWN seccomp filter");
122 }
123 #endif
124 }
125
SetSeccompFilter(struct AppSpawnContent_ * content,AppSpawnClient * client)126 int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client)
127 {
128 #ifdef WITH_SECCOMP
129 const char *appName = APP_NAME;
130 SeccompFilterType type = APP;
131 if (content->isNweb) {
132 return 0;
133 }
134 if (!SetSeccompPolicyWithName(type, appName)) {
135 APPSPAWN_LOGE("Failed to set %{public}s seccomp filter and exit", appName);
136 #ifndef APPSPAWN_TEST
137 return -EINVAL;
138 #endif
139 } else {
140 APPSPAWN_LOGI("Success to set %{public}s seccomp filter", appName);
141 }
142 #endif
143 return 0;
144 }
145
HandleInternetPermission(const AppSpawnClient * client)146 void HandleInternetPermission(const AppSpawnClient *client)
147 {
148 const AppSpawnClientExt *appPropertyExt = reinterpret_cast<const AppSpawnClientExt *>(client);
149 APPSPAWN_CHECK(appPropertyExt != nullptr, return, "Invalid client");
150 APPSPAWN_LOGV("HandleInternetPermission id %{public}d setAllowInternet %hhu allowInternet %hhu",
151 client->id, appPropertyExt->property.setAllowInternet, appPropertyExt->property.allowInternet);
152 if (appPropertyExt->property.setAllowInternet == 1 && appPropertyExt->property.allowInternet == 0) {
153 DisallowInternet();
154 }
155 }
156