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_manager.h"
16 
17 #include "bundle_mgr_client.h"
18 #include "delay_exit_task.h"
19 #include "hisysevent.h"
20 #include "i_sec_comp_service.h"
21 #include "ipc_skeleton.h"
22 #include "iservice_registry.h"
23 #include "sec_comp_enhance_adapter.h"
24 #include "sec_comp_err.h"
25 #include "sec_comp_info.h"
26 #include "sec_comp_info_helper.h"
27 #include "sec_comp_log.h"
28 
29 namespace OHOS {
30 namespace Security {
31 namespace SecurityComponent {
32 namespace {
33 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompManager"};
34 static constexpr int32_t SC_ID_START = 1000;
35 static constexpr int32_t MAX_INT_NUM = 0x7fffffff;
36 static constexpr int32_t MAX_SINGLE_PROC_COMP_SIZE = 500;
37 static constexpr unsigned long REPORT_REMOTE_OBJECT_SIZE = 2UL;
38 }
39 
SecCompManager()40 SecCompManager::SecCompManager()
41 {
42     scIdStart_ = SC_ID_START;
43 }
44 
GetInstance()45 SecCompManager& SecCompManager::GetInstance()
46 {
47     static SecCompManager instance;
48     return instance;
49 }
50 
CreateScId()51 int32_t SecCompManager::CreateScId()
52 {
53     std::lock_guard<std::mutex> lock(scIdMtx_);
54     if (scIdStart_ == MAX_INT_NUM) {
55         scIdStart_ = SC_ID_START;
56     } else {
57         scIdStart_++;
58     }
59     return scIdStart_;
60 }
61 
AddSecurityComponentToList(int32_t pid,AccessToken::AccessTokenID tokenId,std::shared_ptr<SecCompEntity> newEntity)62 int32_t SecCompManager::AddSecurityComponentToList(int32_t pid,
63     AccessToken::AccessTokenID tokenId, std::shared_ptr<SecCompEntity> newEntity)
64 {
65     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
66     if (isSaExit_) {
67         SC_LOG_ERROR(LABEL, "SA is exiting, retry...");
68         return SC_SERVICE_ERROR_SERVICE_NOT_EXIST;
69     }
70 
71     auto iter = componentMap_.find(pid);
72     if (iter != componentMap_.end()) {
73         if (iter->second.compList.size() > MAX_SINGLE_PROC_COMP_SIZE) {
74             SC_LOG_ERROR(LABEL, "single proccess has too many component.");
75             return SC_SERVICE_ERROR_VALUE_INVALID;
76         }
77         iter->second.isForeground = true;
78         iter->second.compList.emplace_back(newEntity);
79         SecCompEnhanceAdapter::EnableInputEnhance();
80         DelayExitTask::GetInstance().Stop();
81         return SC_OK;
82     }
83 
84     ProcessCompInfos newProcess;
85     newProcess.isForeground = true;
86     newProcess.tokenId = tokenId;
87     newProcess.compList.emplace_back(newEntity);
88     componentMap_[pid] = newProcess;
89     SecCompEnhanceAdapter::EnableInputEnhance();
90     DelayExitTask::GetInstance().Stop();
91     return SC_OK;
92 }
93 
DeleteSecurityComponentFromList(int32_t pid,int32_t scId)94 int32_t SecCompManager::DeleteSecurityComponentFromList(int32_t pid, int32_t scId)
95 {
96     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
97     auto iter = componentMap_.find(pid);
98     if (iter == componentMap_.end()) {
99         SC_LOG_ERROR(LABEL, "Can not find registered process");
100         return SC_SERVICE_ERROR_COMPONENT_NOT_EXIST;
101     }
102     auto& list = iter->second.compList;
103     for (auto it = list.begin(); it != list.end(); ++it) {
104         std::shared_ptr<SecCompEntity> sc = *it;
105         if (sc == nullptr) {
106             SC_LOG_ERROR(LABEL, "Secomp entity is nullptr");
107             continue;
108         }
109         if (sc->scId_ == scId) {
110             list.erase(it);
111             if (!IsForegroundCompExist()) {
112                 SecCompEnhanceAdapter::DisableInputEnhance();
113             }
114             DelayExitTask::GetInstance().Start();
115             return SC_OK;
116         }
117     }
118     SC_LOG_ERROR(LABEL, "Can not find component");
119     return SC_SERVICE_ERROR_COMPONENT_NOT_EXIST;
120 }
121 
TransformCallBackResult(enum SCErrCode error)122 static std::string TransformCallBackResult(enum SCErrCode error)
123 {
124     std::string errMsg = "";
125     switch (error) {
126         case SC_ENHANCE_ERROR_NOT_EXIST_ENHANCE:
127             errMsg = "enhance do not exist";
128             break;
129         case SC_ENHANCE_ERROR_VALUE_INVALID:
130             errMsg = "value is invalid";
131             break;
132         case SC_ENHANCE_ERROR_CALLBACK_NOT_EXIST:
133             errMsg = "callback do not exist";
134             break;
135         case SC_ENHANCE_ERROR_CALLBACK_OPER_FAIL:
136             errMsg = "callback operate fail";
137             break;
138         case SC_SERVICE_ERROR_COMPONENT_INFO_INVALID:
139             errMsg = "component info invalid";
140             break;
141         case SC_ENHANCE_ERROR_CALLBACK_CHECK_FAIL:
142             errMsg = "callback check fail";
143             break;
144         default:
145             errMsg = "unknown error";
146             break;
147     }
148     return errMsg;
149 }
150 
GetSecurityComponentFromList(int32_t pid,int32_t scId)151 std::shared_ptr<SecCompEntity> SecCompManager::GetSecurityComponentFromList(int32_t pid, int32_t scId)
152 {
153     auto iter = componentMap_.find(pid);
154     if (iter == componentMap_.end()) {
155         return nullptr;
156     }
157     auto& list = iter->second.compList;
158     for (auto it = list.begin(); it != list.end(); ++it) {
159         std::shared_ptr<SecCompEntity> sc = *it;
160         if (sc == nullptr) {
161             SC_LOG_ERROR(LABEL, "Secomp entity is nullptr");
162             continue;
163         }
164         if (sc->scId_ == scId) {
165             return *it;
166         }
167     }
168     return nullptr;
169 }
170 
IsForegroundCompExist()171 bool SecCompManager::IsForegroundCompExist()
172 {
173     return std::any_of(componentMap_.begin(), componentMap_.end(), [](const auto & iter) {
174         return (iter.second.isForeground) && (iter.second.compList.size() > 0);
175     });
176 }
177 
IsCompExist()178 bool SecCompManager::IsCompExist()
179 {
180     return std::any_of(componentMap_.begin(), componentMap_.end(), [](const auto & iter) {
181         return (iter.second.compList.size() > 0);
182     });
183 }
184 
NotifyProcessForeground(int32_t pid)185 void SecCompManager::NotifyProcessForeground(int32_t pid)
186 {
187     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
188     auto iter = componentMap_.find(pid);
189     if (iter == componentMap_.end()) {
190         return;
191     }
192     SecCompPermManager::GetInstance().CancelAppRevokingPermisions(iter->second.tokenId);
193     iter->second.isForeground = true;
194     if (IsForegroundCompExist()) {
195         SecCompEnhanceAdapter::EnableInputEnhance();
196     }
197 
198     SC_LOG_INFO(LABEL, "App pid %{public}d to foreground", pid);
199 }
200 
NotifyProcessBackground(int32_t pid)201 void SecCompManager::NotifyProcessBackground(int32_t pid)
202 {
203     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
204     auto iter = componentMap_.find(pid);
205     if (iter == componentMap_.end()) {
206         return;
207     }
208 
209     SecCompPermManager::GetInstance().RevokeAppPermisionsDelayed(iter->second.tokenId);
210     iter->second.isForeground = false;
211     if (!IsForegroundCompExist()) {
212         SecCompEnhanceAdapter::DisableInputEnhance();
213     }
214     SC_LOG_INFO(LABEL, "App pid %{public}d to background", pid);
215 }
216 
NotifyProcessDied(int32_t pid)217 void SecCompManager::NotifyProcessDied(int32_t pid)
218 {
219     // notify enhance process died.
220     SecCompEnhanceAdapter::NotifyProcessDied(pid);
221 
222     malicious_.RemoveAppFromMaliciousAppList(pid);
223     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
224     auto iter = componentMap_.find(pid);
225     if (iter == componentMap_.end()) {
226         return;
227     }
228 
229     FirstUseDialog::GetInstance().RemoveDialogWaitEntitys(pid);
230 
231     SC_LOG_INFO(LABEL, "App pid %{public}d died", pid);
232     iter->second.compList.clear();
233     SecCompPermManager::GetInstance().RevokeAppPermissions(iter->second.tokenId);
234     SecCompPermManager::GetInstance().RevokeTempSavePermission(iter->second.tokenId);
235     componentMap_.erase(pid);
236 
237     if (!IsForegroundCompExist()) {
238         SecCompEnhanceAdapter::DisableInputEnhance();
239     }
240 
241     DelayExitTask::GetInstance().Start();
242 }
243 
ExitSaProcess()244 void SecCompManager::ExitSaProcess()
245 {
246     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
247     if (IsCompExist()) {
248         SC_LOG_INFO(LABEL, "Apps using security component still exist, no exit sa");
249         return;
250     }
251 
252     isSaExit_ = true;
253     SecCompEnhanceAdapter::DisableInputEnhance();
254     SecCompEnhanceAdapter::ExitEnhanceService();
255 
256     SC_LOG_INFO(LABEL, "All processes using security component died, start sa exit");
257     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
258     if (systemAbilityMgr == nullptr) {
259         SC_LOG_ERROR(LABEL, "Failed to get SystemAbilityManager.");
260         return;
261     }
262     int32_t ret = systemAbilityMgr->UnloadSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE);
263     if (ret != SC_OK) {
264         SC_LOG_ERROR(LABEL, "Failed to UnloadSystemAbility service! errcode=%{public}d", ret);
265         return;
266     }
267     SC_LOG_INFO(LABEL, "UnloadSystemAbility successfully!");
268 }
269 
ExitWhenAppMgrDied()270 void SecCompManager::ExitWhenAppMgrDied()
271 {
272     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
273     for (auto iter = componentMap_.begin(); iter != componentMap_.end(); ++iter) {
274         iter->second.compList.clear();
275         SecCompPermManager::GetInstance().RevokeAppPermissions(iter->second.tokenId);
276         SecCompPermManager::GetInstance().RevokeTempSavePermission(iter->second.tokenId);
277     }
278     componentMap_.clear();
279 
280     // no need exit enhance service, only disable input enhance.
281     SecCompEnhanceAdapter::DisableInputEnhance();
282     isSaExit_ = true;
283 
284     SC_LOG_INFO(LABEL, "app mgr died, start sa exit");
285     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
286     if (systemAbilityMgr == nullptr) {
287         SC_LOG_ERROR(LABEL, "failed to get SystemAbilityManager.");
288         return;
289     }
290     int32_t ret = systemAbilityMgr->UnloadSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE);
291     if (ret != SC_OK) {
292         SC_LOG_ERROR(LABEL, "failed to UnloadSystemAbility service! errcode=%{public}d", ret);
293         return;
294     }
295     SC_LOG_INFO(LABEL, "UnloadSystemAbility successfully!");
296 }
297 
SendCheckInfoEnhanceSysEvent(int32_t scId,SecCompType type,const std::string & scene,int32_t res)298 void SecCompManager::SendCheckInfoEnhanceSysEvent(int32_t scId,
299     SecCompType type, const std::string& scene, int32_t res)
300 {
301     int32_t uid = IPCSkeleton::GetCallingUid();
302     OHOS::AppExecFwk::BundleMgrClient bmsClient;
303     std::string bundleName = "";
304     bmsClient.GetNameForUid(uid, bundleName);
305     if (res == SC_ENHANCE_ERROR_CHALLENGE_CHECK_FAIL) {
306         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "CHALLENGE_CHECK_FAILED",
307             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
308             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "SC_TYPE", type, "CALL_SCENE",
309             scene);
310     } else {
311         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "CALLBACK_FAILED",
312             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
313             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_TYPE", type,
314             "CALL_SCENE", scene, "REASON", TransformCallBackResult(static_cast<enum SCErrCode>(res)));
315     }
316 }
317 
AddSecurityComponentProcess(const SecCompCallerInfo & caller)318 int32_t SecCompManager::AddSecurityComponentProcess(const SecCompCallerInfo& caller)
319 {
320     DelayExitTask::GetInstance().Stop();
321     {
322         OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
323         if (isSaExit_) {
324             SC_LOG_ERROR(LABEL, "SA is exiting, retry...");
325             return SC_SERVICE_ERROR_SERVICE_NOT_EXIST;
326         }
327 
328         auto iter = componentMap_.find(caller.pid);
329         if (iter == componentMap_.end()) {
330             ProcessCompInfos newProcess;
331             newProcess.isForeground = true;
332             newProcess.tokenId = caller.tokenId;
333             componentMap_[caller.pid] = newProcess;
334         }
335         SecCompEnhanceAdapter::EnableInputEnhance();
336     }
337     SecCompEnhanceAdapter::AddSecurityComponentProcess(caller.pid);
338     return SC_OK;
339 }
340 
RegisterSecurityComponent(SecCompType type,const nlohmann::json & jsonComponent,const SecCompCallerInfo & caller,int32_t & scId)341 int32_t SecCompManager::RegisterSecurityComponent(SecCompType type,
342     const nlohmann::json& jsonComponent, const SecCompCallerInfo& caller, int32_t& scId)
343 {
344     SC_LOG_DEBUG(LABEL, "PID: %{public}d, register security component", caller.pid);
345     if (malicious_.IsInMaliciousAppList(caller.pid, caller.uid)) {
346         SC_LOG_ERROR(LABEL, "app is in MaliciousAppList, never allow it");
347         return SC_ENHANCE_ERROR_IN_MALICIOUS_LIST;
348     }
349 
350     SecCompBase* componentPtr = SecCompInfoHelper::ParseComponent(type, jsonComponent);
351     std::shared_ptr<SecCompBase> component(componentPtr);
352     if (component == nullptr) {
353         SC_LOG_ERROR(LABEL, "Parse component info invalid");
354         int32_t uid = IPCSkeleton::GetCallingUid();
355         OHOS::AppExecFwk::BundleMgrClient bmsClient;
356         std::string bundleName = "";
357         bmsClient.GetNameForUid(uid, bundleName);
358         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "COMPONENT_INFO_CHECK_FAILED",
359             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
360             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "CALL_SCENE", "REGITSTER", "SC_TYPE", type);
361         return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID;
362     }
363 
364     int32_t enhanceRes =
365         SecCompEnhanceAdapter::CheckComponentInfoEnhance(caller.pid, component, jsonComponent);
366     if (enhanceRes != SC_OK) {
367         SendCheckInfoEnhanceSysEvent(INVALID_SC_ID, type, "REGISTER", enhanceRes);
368         SC_LOG_ERROR(LABEL, "enhance check failed");
369         malicious_.AddAppToMaliciousAppList(caller.pid);
370         return enhanceRes;
371     }
372 
373     int32_t registerId = CreateScId();
374     std::shared_ptr<SecCompEntity> entity =
375         std::make_shared<SecCompEntity>(component, caller.tokenId, registerId, caller.pid, caller.uid);
376     int32_t ret = AddSecurityComponentToList(caller.pid, caller.tokenId, entity);
377     if (ret == SC_OK) {
378         scId = registerId;
379     } else {
380         SC_LOG_ERROR(LABEL, "Register security component failed");
381         scId = INVALID_SC_ID;
382     }
383     return ret;
384 }
385 
UpdateSecurityComponent(int32_t scId,const nlohmann::json & jsonComponent,const SecCompCallerInfo & caller)386 int32_t SecCompManager::UpdateSecurityComponent(int32_t scId, const nlohmann::json& jsonComponent,
387     const SecCompCallerInfo& caller)
388 {
389     SC_LOG_DEBUG(LABEL, "PID: %{public}d, update security component", caller.pid);
390     if (malicious_.IsInMaliciousAppList(caller.pid, caller.uid)) {
391         SC_LOG_ERROR(LABEL, "app is in MaliciousAppList, never allow it");
392         return SC_ENHANCE_ERROR_IN_MALICIOUS_LIST;
393     }
394 
395     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
396     std::shared_ptr<SecCompEntity> sc = GetSecurityComponentFromList(caller.pid, scId);
397     if (sc == nullptr) {
398         SC_LOG_ERROR(LABEL, "Can not find target component");
399         return SC_SERVICE_ERROR_COMPONENT_NOT_EXIST;
400     }
401     SecCompBase* report = SecCompInfoHelper::ParseComponent(sc->GetType(), jsonComponent);
402     std::shared_ptr<SecCompBase> reportComponentInfo(report);
403     if (reportComponentInfo == nullptr) {
404         SC_LOG_ERROR(LABEL, "Update component info invalid");
405         int32_t uid = IPCSkeleton::GetCallingUid();
406         OHOS::AppExecFwk::BundleMgrClient bmsClient;
407         std::string bundleName = "";
408         bmsClient.GetNameForUid(uid, bundleName);
409         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "COMPONENT_INFO_CHECK_FAILED",
410             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
411             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "CALL_SCENE", "UPDATE",
412             "SC_TYPE", sc->GetType());
413         return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID;
414     }
415 
416     int32_t enhanceRes =
417         SecCompEnhanceAdapter::CheckComponentInfoEnhance(caller.pid, reportComponentInfo, jsonComponent);
418     if (enhanceRes != SC_OK) {
419         SendCheckInfoEnhanceSysEvent(scId, sc->GetType(), "UPDATE", enhanceRes);
420         SC_LOG_ERROR(LABEL, "enhance check failed");
421         malicious_.AddAppToMaliciousAppList(caller.pid);
422         return enhanceRes;
423     }
424 
425     sc->componentInfo_ = reportComponentInfo;
426     return SC_OK;
427 }
428 
UnregisterSecurityComponent(int32_t scId,const SecCompCallerInfo & caller)429 int32_t SecCompManager::UnregisterSecurityComponent(int32_t scId, const SecCompCallerInfo& caller)
430 {
431     SC_LOG_DEBUG(LABEL, "PID: %{public}d, unregister security component", caller.pid);
432     if (scId < 0) {
433         SC_LOG_ERROR(LABEL, "ScId is invalid");
434         return SC_SERVICE_ERROR_VALUE_INVALID;
435     }
436     return DeleteSecurityComponentFromList(caller.pid, scId);
437 }
438 
CheckClickSecurityComponentInfo(std::shared_ptr<SecCompEntity> sc,int32_t scId,const nlohmann::json & jsonComponent,const SecCompCallerInfo & caller)439 int32_t SecCompManager::CheckClickSecurityComponentInfo(std::shared_ptr<SecCompEntity> sc, int32_t scId,
440     const nlohmann::json& jsonComponent, const SecCompCallerInfo& caller)
441 {
442     SC_LOG_DEBUG(LABEL, "PID: %{public}d, Check security component", caller.pid);
443     SecCompBase* report = SecCompInfoHelper::ParseComponent(sc->GetType(), jsonComponent);
444     std::shared_ptr<SecCompBase> reportComponentInfo(report);
445     int32_t uid = IPCSkeleton::GetCallingUid();
446     OHOS::AppExecFwk::BundleMgrClient bmsClient;
447     std::string bundleName = "";
448     bmsClient.GetNameForUid(uid, bundleName);
449     if ((reportComponentInfo == nullptr) || (!reportComponentInfo->GetValid())) {
450         SC_LOG_ERROR(LABEL, "report component info invalid");
451         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "COMPONENT_INFO_CHECK_FAILED",
452             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
453             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "CALL_SCENE", "CLICK", "SC_TYPE",
454             sc->GetType());
455         return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID;
456     }
457     if (report && (report->isClipped_)) {
458         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "CLIP_CHECK_FAILED",
459             HiviewDFX::HiSysEvent::EventType::SECURITY,
460             "CALLER_BUNDLE_NAME", bundleName, "COMPONENT_INFO", jsonComponent.dump().c_str());
461     }
462 
463     if ((!SecCompInfoHelper::CheckRectValid(reportComponentInfo->rect_, reportComponentInfo->windowRect_))) {
464         SC_LOG_ERROR(LABEL, "compare component info failed.");
465         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "COMPONENT_INFO_CHECK_FAILED",
466             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
467             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "CALL_SCENE", "CLICK", "SC_TYPE",
468             sc->GetType());
469         return SC_SERVICE_ERROR_COMPONENT_INFO_INVALID;
470     }
471     int32_t enhanceRes =
472         SecCompEnhanceAdapter::CheckComponentInfoEnhance(caller.pid, reportComponentInfo, jsonComponent);
473     if (enhanceRes != SC_OK) {
474         SendCheckInfoEnhanceSysEvent(scId, sc->GetType(), "CLICK", enhanceRes);
475         SC_LOG_ERROR(LABEL, "enhance check failed");
476         malicious_.AddAppToMaliciousAppList(caller.pid);
477         return enhanceRes;
478     }
479 
480     sc->componentInfo_ = reportComponentInfo;
481     return SC_OK;
482 }
483 
ReportEvent(std::string eventName,HiviewDFX::HiSysEvent::EventType eventType,int32_t scId,SecCompType scType)484 static void ReportEvent(std::string eventName, HiviewDFX::HiSysEvent::EventType eventType, int32_t scId,
485     SecCompType scType)
486 {
487     int32_t uid = IPCSkeleton::GetCallingUid();
488     OHOS::AppExecFwk::BundleMgrClient bmsClient;
489     std::string bundleName = "";
490     bmsClient.GetNameForUid(uid, bundleName);
491     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, eventName,
492         eventType, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
493         "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "SC_TYPE", scType);
494 }
495 
ReportSecurityComponentClickEvent(int32_t scId,const nlohmann::json & jsonComponent,const SecCompCallerInfo & caller,const SecCompClickEvent & clickInfo,const std::vector<sptr<IRemoteObject>> & remote)496 int32_t SecCompManager::ReportSecurityComponentClickEvent(int32_t scId,
497     const nlohmann::json& jsonComponent, const SecCompCallerInfo& caller,
498     const SecCompClickEvent& clickInfo, const std::vector<sptr<IRemoteObject>>& remote)
499 {
500     if (remote.size() < REPORT_REMOTE_OBJECT_SIZE) {
501         return SC_SERVICE_ERROR_VALUE_INVALID;
502     }
503     auto callerToken = remote[0];
504     auto dialogCallback = remote[1];
505 
506     if (malicious_.IsInMaliciousAppList(caller.pid, caller.uid)) {
507         SC_LOG_ERROR(LABEL, "app is in MaliciousAppList, never allow it");
508         return SC_ENHANCE_ERROR_IN_MALICIOUS_LIST;
509     }
510 
511     OHOS::Utils::UniqueReadGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
512     std::shared_ptr<SecCompEntity> sc = GetSecurityComponentFromList(caller.pid, scId);
513     if (sc == nullptr) {
514         SC_LOG_ERROR(LABEL, "Can not find target component");
515         return SC_SERVICE_ERROR_COMPONENT_NOT_EXIST;
516     }
517 
518     int32_t res = CheckClickSecurityComponentInfo(sc, scId, jsonComponent, caller);
519     if (res != SC_OK) {
520         return res;
521     }
522 
523     res = sc->CheckClickInfo(clickInfo);
524     if (res != SC_OK) {
525         ReportEvent("CLICK_INFO_CHECK_FAILED", HiviewDFX::HiSysEvent::EventType::SECURITY,
526             scId, sc->GetType());
527         if (res == SC_ENHANCE_ERROR_CLICK_EXTRA_CHECK_FAIL) {
528             malicious_.AddAppToMaliciousAppList(caller.pid);
529         }
530 
531         return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
532     }
533 
534     if (FirstUseDialog::GetInstance().NotifyFirstUseDialog(sc, callerToken, dialogCallback) ==
535         SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE) {
536         SC_LOG_INFO(LABEL, "start dialog, onclick will be trap after dialog closed.");
537         return SC_SERVICE_ERROR_WAIT_FOR_DIALOG_CLOSE;
538     }
539 
540     res = sc->GrantTempPermission();
541     if (res != SC_OK) {
542         ReportEvent("TEMP_GRANT_FAILED", HiviewDFX::HiSysEvent::EventType::FAULT,
543             scId, sc->GetType());
544         return res;
545     }
546     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "TEMP_GRANT_SUCCESS",
547         HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "CALLER_UID", IPCSkeleton::GetCallingUid(),
548         "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId, "SC_TYPE", sc->GetType());
549     return res;
550 }
551 
DumpSecComp(std::string & dumpStr)552 void SecCompManager::DumpSecComp(std::string& dumpStr)
553 {
554     OHOS::Utils::UniqueReadGuard<OHOS::Utils::RWLock> lk(this->componentInfoLock_);
555     for (auto iter = componentMap_.begin(); iter != componentMap_.end(); ++iter) {
556         AccessToken::AccessTokenID tokenId = iter->second.tokenId;
557         bool locationPerm = SecCompPermManager::GetInstance().VerifyPermission(tokenId, LOCATION_COMPONENT);
558         bool pastePerm = SecCompPermManager::GetInstance().VerifyPermission(tokenId, PASTE_COMPONENT);
559         bool savePerm = SecCompPermManager::GetInstance().VerifyPermission(tokenId, SAVE_COMPONENT);
560         dumpStr.append("pid:" + std::to_string(iter->first) + ", tokenId:" + std::to_string(pastePerm) +
561             ", locationPerm:" + std::to_string(locationPerm) + ", pastePerm:" + std::to_string(pastePerm) +
562             ", savePerm:" + std::to_string(savePerm) + " \n");
563         for (auto compIter = iter->second.compList.begin(); compIter != iter->second.compList.end(); ++compIter) {
564             nlohmann::json json;
565             std::shared_ptr<SecCompEntity> sc = *compIter;
566             if (sc == nullptr || sc->componentInfo_ == nullptr) {
567                 continue;
568             }
569 
570             sc->componentInfo_->ToJson(json);
571             dumpStr.append("    scId:" + std::to_string(sc->scId_) +
572                 ", isGrant:" + std::to_string(sc->IsGrant()) + ", " + json.dump() + "\n");
573         }
574     }
575 }
576 
Initialize()577 bool SecCompManager::Initialize()
578 {
579     SC_LOG_DEBUG(LABEL, "Initialize!!");
580     SecCompEnhanceAdapter::StartEnhanceService();
581 
582     secRunner_ = AppExecFwk::EventRunner::Create(true, AppExecFwk::ThreadMode::FFRT);
583     if (!secRunner_) {
584         SC_LOG_ERROR(LABEL, "failed to create a recvRunner.");
585         return false;
586     }
587 
588     secHandler_ = std::make_shared<SecEventHandler>(secRunner_);
589     DelayExitTask::GetInstance().Init(secHandler_);
590     FirstUseDialog::GetInstance().Init(secHandler_);
591     SecCompEnhanceAdapter::EnableInputEnhance();
592     SecCompPermManager::GetInstance().InitEventHandler(secHandler_);
593     DelayExitTask::GetInstance().Start();
594 
595     return true;
596 }
597 }  // namespace SecurityComponent
598 }  // namespace Security
599 }  // namespace OHOS
600