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