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
18 #include <cerrno>
19
20 #include "selinux/selinux.h"
21
22 #include "appspawn_service.h"
23 #ifdef WITH_SELINUX
24 #include "hap_restorecon.h"
25 #endif
26 #include "token_setproc.h"
27 #ifdef WITH_SECCOMP
28 #include "seccomp_policy.h"
29 #include <sys/prctl.h>
30
31 const char* RENDERER_NAME = "renderer";
32 #endif
33
34 #include "tokenid_kit.h"
35 #include "access_token.h"
36 #define NWEBSPAWN_SERVER_NAME "nwebspawn"
37 using namespace OHOS::Security::AccessToken;
38
SetAppAccessToken(struct AppSpawnContent_ * content,AppSpawnClient * client)39 int SetAppAccessToken(struct AppSpawnContent_ *content, AppSpawnClient *client)
40 {
41 AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
42 int32_t ret = 0;
43 uint64_t tokenId = 0;
44 if (content->isNweb) {
45 TokenIdKit tokenIdKit;
46 tokenId = tokenIdKit.GetRenderTokenID(appProperty->property.accessTokenIdEx);
47 if (tokenId == static_cast<uint64_t>(INVALID_TOKENID)) {
48 APPSPAWN_LOGE("AppSpawnServer::Failed to get render token id, renderTokenId =%{public}llu",
49 static_cast<unsigned long long>(tokenId));
50 return -1;
51 }
52 } else {
53 tokenId = appProperty->property.accessTokenIdEx;
54 }
55 ret = SetSelfTokenID(tokenId);
56 if (ret != 0) {
57 APPSPAWN_LOGE("AppSpawnServer::set access token id failed, ret = %{public}d", ret);
58 return -1;
59 }
60
61 APPSPAWN_LOGV("AppSpawnServer::set access token id = %{public}llu, ret = %{public}d %{public}d",
62 static_cast<unsigned long long>(appProperty->property.accessTokenIdEx), ret, getuid());
63 return 0;
64 }
65
SetSelinuxCon(struct AppSpawnContent_ * content,AppSpawnClient * client)66 int SetSelinuxCon(struct AppSpawnContent_ *content, AppSpawnClient *client)
67 {
68 #ifdef WITH_SELINUX
69 if (content->isNweb) {
70 setcon("u:r:isolated_render:s0");
71 } else {
72 UNUSED(content);
73 AppSpawnClientExt *appProperty = reinterpret_cast<AppSpawnClientExt *>(client);
74 HapContext hapContext;
75 HapDomainInfo hapDomainInfo;
76 hapDomainInfo.apl = appProperty->property.apl;
77 hapDomainInfo.packageName = appProperty->property.processName;
78 hapDomainInfo.hapFlags = appProperty->property.hapFlags;
79 if ((appProperty->property.flags & APP_DEBUGGABLE) != 0) {
80 hapDomainInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE;
81 }
82 int32_t ret = hapContext.HapDomainSetcontext(hapDomainInfo);
83 if (ret != 0) {
84 APPSPAWN_LOGE("AppSpawnServer::Failed to hap domain set context, errno = %{public}d %{public}s",
85 errno, appProperty->property.apl);
86 #ifndef APPSPAWN_TEST
87 return -1;
88 #endif
89 } else {
90 APPSPAWN_LOGV("AppSpawnServer::Success to hap domain set context, ret = %{public}d", ret);
91 }
92 }
93 #endif
94 return 0;
95 }
96
SetUidGidFilter(struct AppSpawnContent_ * content)97 void SetUidGidFilter(struct AppSpawnContent_ *content)
98 {
99 #ifdef WITH_SECCOMP
100 bool ret = false;
101 if (content->isNweb) {
102 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
103 APPSPAWN_LOGE("Failed to set no new privs");
104 }
105 ret = SetSeccompPolicyWithName(INDIVIDUAL, NWEBSPAWN_NAME);
106 } else {
107 ret = SetSeccompPolicyWithName(INDIVIDUAL, APPSPAWN_NAME);
108 }
109 if (!ret) {
110 APPSPAWN_LOGE("Failed to set APPSPAWN seccomp filter and exit");
111 #ifndef APPSPAWN_TEST
112 _exit(0x7f);
113 #endif
114 } else {
115 APPSPAWN_LOGI("Success to set APPSPAWN seccomp filter");
116 }
117 #endif
118 }
119
SetSeccompFilter(struct AppSpawnContent_ * content,AppSpawnClient * client)120 int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client)
121 {
122 #ifdef WITH_SECCOMP
123 const char *appName = APP_NAME;
124 SeccompFilterType type = APP;
125 if (content->isNweb) {
126 appName = RENDERER_NAME;
127 type = INDIVIDUAL;
128 }
129 if (!SetSeccompPolicyWithName(type, appName)) {
130 APPSPAWN_LOGE("Failed to set %{public}s seccomp filter and exit", appName);
131 #ifndef APPSPAWN_TEST
132 return -EINVAL;
133 #endif
134 } else {
135 APPSPAWN_LOGI("Success to set %{public}s seccomp filter", appName);
136 }
137 #endif
138 return 0;
139 }
140
HandleInternetPermission(const AppSpawnClient * client)141 void HandleInternetPermission(const AppSpawnClient *client)
142 {
143 const AppSpawnClientExt *appPropertyExt = reinterpret_cast<const AppSpawnClientExt *>(client);
144 APPSPAWN_CHECK(appPropertyExt != nullptr, return, "Invalid client");
145 APPSPAWN_LOGV("HandleInternetPermission id %{public}d setAllowInternet %hhu allowInternet %hhu",
146 client->id, appPropertyExt->property.setAllowInternet, appPropertyExt->property.allowInternet);
147 if (appPropertyExt->property.setAllowInternet == 1 && appPropertyExt->property.allowInternet == 0) {
148 DisallowInternet();
149 }
150 }
151