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