1 /*
2 * Copyright (c) 2023 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 #include "sec_comp_service.h"
16
17 #include <unistd.h>
18
19 #include "app_mgr_death_recipient.h"
20 #include "bundle_info.h"
21 #include "bundle_mgr_client.h"
22 #include "hisysevent.h"
23 #include "hitrace_meter.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "sec_comp_enhance_adapter.h"
27 #include "sec_comp_err.h"
28 #include "sec_comp_manager.h"
29 #include "sec_comp_log.h"
30 #include "system_ability_definition.h"
31
32 namespace OHOS {
33 namespace Security {
34 namespace SecurityComponent {
35 namespace {
36 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompService"};
37 static const int32_t ROOT_UID = 0;
38 static constexpr int32_t BASE_USER_RANGE = 200000;
39 }
40
41 REGISTER_SYSTEM_ABILITY_BY_ID(SecCompService, SA_ID_SECURITY_COMPONENT_SERVICE, true);
42
SecCompService(int32_t saId,bool runOnCreate)43 SecCompService::SecCompService(int32_t saId, bool runOnCreate)
44 : SystemAbility(saId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
45 {
46 }
47
~SecCompService()48 SecCompService::~SecCompService()
49 {
50 }
51
OnStart()52 void SecCompService::OnStart()
53 {
54 StartTrace(HITRACE_TAG_ACCESS_CONTROL, "SecurityComponentOnStart");
55 if (state_ == ServiceRunningState::STATE_RUNNING) {
56 SC_LOG_INFO(LABEL, "SecCompService has already started!");
57 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
58 return;
59 }
60 SC_LOG_INFO(LABEL, "SecCompService is starting");
61 if (!RegisterAppStateObserver()) {
62 SC_LOG_ERROR(LABEL, "Failed to register app state observer!");
63 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
64 return;
65 }
66 if (!Initialize()) {
67 SC_LOG_ERROR(LABEL, "Failed to initialize");
68 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
69 return;
70 }
71
72 state_ = ServiceRunningState::STATE_RUNNING;
73 bool ret = Publish(this);
74 if (!ret) {
75 SC_LOG_ERROR(LABEL, "Failed to publish service!");
76 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
77 return;
78 }
79 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "SERVICE_INIT_SUCCESS",
80 HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PID", getpid());
81 SC_LOG_INFO(LABEL, "Congratulations, SecCompService start successfully!");
82 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
83 }
84
OnStop()85 void SecCompService::OnStop()
86 {
87 SC_LOG_INFO(LABEL, "Stop service");
88 state_ = ServiceRunningState::STATE_NOT_START;
89 UnregisterAppStateObserver();
90 }
91
RegisterAppStateObserver()92 bool SecCompService::RegisterAppStateObserver()
93 {
94 if (appStateObserver_ != nullptr) {
95 SC_LOG_INFO(LABEL, "AppStateObserver instance already create");
96 return true;
97 }
98 appStateObserver_ = new (std::nothrow) AppStateObserver();
99 if (appStateObserver_ == nullptr) {
100 SC_LOG_ERROR(LABEL, "Failed to create AppStateObserver instance");
101 return false;
102 }
103 sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
104 if (samgrClient == nullptr) {
105 SC_LOG_ERROR(LABEL, "Failed to get system ability manager");
106 appStateObserver_ = nullptr;
107 return false;
108 }
109 auto remoteObject = samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID);
110 iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(remoteObject);
111 if (iAppMgr_ == nullptr) {
112 SC_LOG_ERROR(LABEL, "Failed to get ability manager service");
113 appStateObserver_ = nullptr;
114 return false;
115 }
116
117 if (iAppMgr_->RegisterApplicationStateObserver(appStateObserver_) != ERR_OK) {
118 SC_LOG_ERROR(LABEL, "Failed to Register app state observer");
119 iAppMgr_ = nullptr;
120 appStateObserver_ = nullptr;
121 return false;
122 }
123
124 sptr<AppMgrDeathRecipient> appMgrDeathRecipient = new (std::nothrow) AppMgrDeathRecipient();
125 if (appMgrDeathRecipient == nullptr) {
126 SC_LOG_ERROR(LABEL, "Alloc appMgr death observer fail");
127 return false;
128 }
129
130 if (!remoteObject->AddDeathRecipient(appMgrDeathRecipient)) {
131 SC_LOG_ERROR(LABEL, "Add service death observer fail");
132 return false;
133 }
134
135 std::vector<AppExecFwk::AppStateData> list;
136 if (iAppMgr_->GetForegroundApplications(list) == ERR_OK) {
137 for (auto it = list.begin(); it != list.end(); ++it) {
138 appStateObserver_->AddProcessToForegroundSet(*it);
139 }
140 }
141 SC_LOG_ERROR(LABEL, "Register app state observer success");
142 return true;
143 }
144
UnregisterAppStateObserver()145 void SecCompService::UnregisterAppStateObserver()
146 {
147 if (iAppMgr_ != nullptr && appStateObserver_ != nullptr) {
148 iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
149 }
150 }
151
GetCallerInfo(SecCompCallerInfo & caller)152 bool SecCompService::GetCallerInfo(SecCompCallerInfo& caller)
153 {
154 AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
155 int32_t pid = IPCSkeleton::GetCallingPid();
156 int32_t uid = IPCSkeleton::GetCallingUid();
157 if ((uid != ROOT_UID) && (AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) != AccessToken::TOKEN_HAP)) {
158 SC_LOG_ERROR(LABEL, "Get caller tokenId invalid");
159 return false;
160 }
161 if ((uid != ROOT_UID) && (!appStateObserver_->IsProcessForeground(pid, uid))) {
162 SC_LOG_ERROR(LABEL, "caller pid is not in foreground");
163 return false;
164 }
165 caller.tokenId = tokenId;
166 caller.pid = pid;
167 caller.uid = uid;
168 return true;
169 }
170
ParseParams(const std::string & componentInfo,SecCompCallerInfo & caller,nlohmann::json & jsonRes)171 int32_t SecCompService::ParseParams(const std::string& componentInfo,
172 SecCompCallerInfo& caller, nlohmann::json& jsonRes)
173 {
174 if (!GetCallerInfo(caller)) {
175 SC_LOG_ERROR(LABEL, "Check caller failed");
176 return SC_SERVICE_ERROR_VALUE_INVALID;
177 }
178
179 jsonRes = nlohmann::json::parse(componentInfo, nullptr, false);
180 if (jsonRes.is_discarded()) {
181 SC_LOG_ERROR(LABEL, "component info invalid %{public}s", componentInfo.c_str());
182 return SC_SERVICE_ERROR_VALUE_INVALID;
183 }
184 return SC_OK;
185 }
186
RegisterSecurityComponent(SecCompType type,const std::string & componentInfo,int32_t & scId)187 int32_t SecCompService::RegisterSecurityComponent(SecCompType type,
188 const std::string& componentInfo, int32_t& scId)
189 {
190 StartTrace(HITRACE_TAG_ACCESS_CONTROL, "SecurityComponentRegister");
191 SecCompCallerInfo caller;
192 caller.tokenId = IPCSkeleton::GetCallingTokenID();
193 caller.pid = IPCSkeleton::GetCallingPid();
194 caller.uid = IPCSkeleton::GetCallingUid();
195 if ((caller.uid != ROOT_UID)
196 && (AccessToken::AccessTokenKit::GetTokenTypeFlag(caller.tokenId) != AccessToken::TOKEN_HAP)) {
197 SC_LOG_ERROR(LABEL, "Get caller tokenId invalid");
198 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
199 return SC_SERVICE_ERROR_VALUE_INVALID;
200 }
201 nlohmann::json jsonRes = nlohmann::json::parse(componentInfo, nullptr, false);
202 if (jsonRes.is_discarded()) {
203 SC_LOG_ERROR(LABEL, "component info invalid %{public}s", componentInfo.c_str());
204 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
205 return SC_SERVICE_ERROR_VALUE_INVALID;
206 }
207
208 int32_t res = SecCompManager::GetInstance().RegisterSecurityComponent(type, jsonRes, caller, scId);
209 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
210
211 int32_t uid = IPCSkeleton::GetCallingUid();
212 OHOS::AppExecFwk::BundleMgrClient bmsClient;
213 std::string bundleName = "";
214 bmsClient.GetNameForUid(uid, bundleName);
215
216 AppExecFwk::BundleInfo bundleInfo;
217 int32_t userId = uid / BASE_USER_RANGE;
218 bmsClient.GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, userId);
219
220 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "REGISTER_SUCCESS",
221 HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "CALLER_UID", IPCSkeleton::GetCallingUid(),
222 "CALLER_PID", IPCSkeleton::GetCallingRealPid(), "CALLER_BUNDLE_NAME", bundleName, "CALLER_BUNDLE_VERSION",
223 bundleInfo.versionName, "SC_ID", scId, "SC_TYPE", type);
224 return res;
225 }
226
UpdateSecurityComponent(int32_t scId,const std::string & componentInfo)227 int32_t SecCompService::UpdateSecurityComponent(int32_t scId, const std::string& componentInfo)
228 {
229 SecCompCallerInfo caller;
230 nlohmann::json jsonRes;
231 if (ParseParams(componentInfo, caller, jsonRes) != SC_OK) {
232 return SC_SERVICE_ERROR_VALUE_INVALID;
233 }
234 return SecCompManager::GetInstance().UpdateSecurityComponent(scId, jsonRes, caller);
235 }
236
UnregisterSecurityComponent(int32_t scId)237 int32_t SecCompService::UnregisterSecurityComponent(int32_t scId)
238 {
239 SecCompCallerInfo caller;
240 caller.tokenId = IPCSkeleton::GetCallingTokenID();
241 caller.pid = IPCSkeleton::GetCallingPid();
242 caller.uid = IPCSkeleton::GetCallingUid();
243
244 return SecCompManager::GetInstance().UnregisterSecurityComponent(scId, caller);
245 }
246
ReportSecurityComponentClickEvent(int32_t scId,const std::string & componentInfo,const SecCompClickEvent & clickInfo,sptr<IRemoteObject> callerToken,sptr<IRemoteObject> dialogCallback)247 int32_t SecCompService::ReportSecurityComponentClickEvent(int32_t scId,
248 const std::string& componentInfo, const SecCompClickEvent& clickInfo,
249 sptr<IRemoteObject> callerToken, sptr<IRemoteObject> dialogCallback)
250 {
251 StartTrace(HITRACE_TAG_ACCESS_CONTROL, "SecurityComponentClick");
252 SecCompCallerInfo caller;
253 nlohmann::json jsonRes;
254 if (ParseParams(componentInfo, caller, jsonRes) != SC_OK) {
255 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
256 return SC_SERVICE_ERROR_VALUE_INVALID;
257 }
258 std::vector<sptr<IRemoteObject>> remoteArr = { callerToken, dialogCallback };
259 int32_t res =
260 SecCompManager::GetInstance().ReportSecurityComponentClickEvent(scId, jsonRes, caller, clickInfo,
261 remoteArr);
262 FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
263 return res;
264 }
265
PreRegisterSecCompProcess()266 int32_t SecCompService::PreRegisterSecCompProcess()
267 {
268 SecCompCallerInfo caller;
269 if (!GetCallerInfo(caller)) {
270 SC_LOG_ERROR(LABEL, "Check caller failed");
271 return SC_SERVICE_ERROR_VALUE_INVALID;
272 }
273 return SecCompManager::GetInstance().AddSecurityComponentProcess(caller);
274 }
275
VerifySavePermission(AccessToken::AccessTokenID tokenId)276 bool SecCompService::VerifySavePermission(AccessToken::AccessTokenID tokenId)
277 {
278 return SecCompPermManager::GetInstance().VerifySavePermission(tokenId);
279 }
280
GetEnhanceRemoteObject()281 sptr<IRemoteObject> SecCompService::GetEnhanceRemoteObject()
282 {
283 return SecCompEnhanceAdapter::GetEnhanceRemoteObject();
284 }
285
Dump(int fd,const std::vector<std::u16string> & args)286 int SecCompService::Dump(int fd, const std::vector<std::u16string>& args)
287 {
288 if (fd < 0) {
289 return ERR_INVALID_VALUE;
290 }
291
292 dprintf(fd, "SecCompService Dump:\n");
293 std::string arg0 = ((args.size() == 0)? "" : Str16ToStr8(args.at(0)));
294 if (arg0.compare("-h") == 0) {
295 dprintf(fd, "Usage:\n");
296 dprintf(fd, " -h: command help\n");
297 dprintf(fd, " -a: dump all sec component\n");
298 dprintf(fd, " -p: dump foreground processes\n");
299 } else if (arg0.compare("-p") == 0) {
300 std::string dumpStr;
301 appStateObserver_->DumpProcess(dumpStr);
302 dprintf(fd, "%s\n", dumpStr.c_str());
303 } else if (arg0.compare("-a") == 0 || arg0 == "") {
304 std::string dumpStr;
305 SecCompManager::GetInstance().DumpSecComp(dumpStr);
306 dprintf(fd, "%s\n", dumpStr.c_str());
307 }
308 return ERR_OK;
309 }
310
Initialize() const311 bool SecCompService::Initialize() const
312 {
313 return SecCompManager::GetInstance().Initialize();
314 }
315 } // namespace SecurityComponent
316 } // namespace Security
317 } // namespace OHOS
318