• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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