• 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_enhance_agent.h"
16 
17 #include "access_token.h"
18 #include "access_token_error.h"
19 #include "accesstoken_kit.h"
20 #include "accesstoken_common_log.h"
21 #include "accesstoken_info_manager.h"
22 #include "app_manager_access_client.h"
23 #include "ipc_skeleton.h"
24 #include "securec.h"
25 
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 namespace {
30 std::recursive_mutex g_instanceMutex;
31 }
GetInstance()32 SecCompEnhanceAgent& SecCompEnhanceAgent::GetInstance()
33 {
34     static SecCompEnhanceAgent* instance = nullptr;
35     if (instance == nullptr) {
36         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
37         if (instance == nullptr) {
38             SecCompEnhanceAgent* tmp = new (std::nothrow) SecCompEnhanceAgent();
39             instance = std::move(tmp);
40         }
41     }
42     return *instance;
43 }
44 
InitAppObserver()45 void SecCompEnhanceAgent::InitAppObserver()
46 {
47     if (observer_ != nullptr) {
48         return;
49     }
50     observer_ = new (std::nothrow) SecCompUsageObserver();
51     if (observer_ == nullptr) {
52         LOGE(ATM_DOMAIN, ATM_TAG, "New observer failed.");
53         return;
54     }
55     if (AppManagerAccessClient::GetInstance().RegisterApplicationStateObserver(observer_) != 0) {
56         LOGE(ATM_DOMAIN, ATM_TAG, "Register observer failed.");
57         observer_ = nullptr;
58         return;
59     }
60     if (appManagerDeathCallback_ == nullptr) {
61         appManagerDeathCallback_ = std::make_shared<SecCompAppManagerDeathCallback>();
62         AppManagerAccessClient::GetInstance().RegisterDeathCallback(appManagerDeathCallback_);
63     }
64 }
65 
SecCompEnhanceAgent()66 SecCompEnhanceAgent::SecCompEnhanceAgent()
67 {
68     InitAppObserver();
69 }
70 
~SecCompEnhanceAgent()71 SecCompEnhanceAgent::~SecCompEnhanceAgent()
72 {
73     if (observer_ != nullptr) {
74         AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(observer_);
75         observer_ = nullptr;
76     }
77 }
78 
OnAppMgrRemoteDiedHandle()79 void SecCompEnhanceAgent::OnAppMgrRemoteDiedHandle()
80 {
81     LOGI(ATM_DOMAIN, ATM_TAG, "OnAppMgrRemoteDiedHandle.");
82     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
83     secCompEnhanceData_.clear();
84     observer_ = nullptr;
85 }
86 
RemoveSecCompEnhance(int pid)87 void SecCompEnhanceAgent::RemoveSecCompEnhance(int pid)
88 {
89     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
90     for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
91         if (iter->pid == pid) {
92             secCompEnhanceData_.erase(iter);
93             LOGI(ATM_DOMAIN, ATM_TAG, "Remove pid %{public}d data.", pid);
94             return;
95         }
96     }
97     LOGD(ATM_DOMAIN, ATM_TAG, "Not found pid %{public}d data.", pid);
98     return;
99 }
100 
RegisterSecCompEnhance(const SecCompEnhanceData & enhanceData)101 int32_t SecCompEnhanceAgent::RegisterSecCompEnhance(const SecCompEnhanceData& enhanceData)
102 {
103     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
104     InitAppObserver();
105     int pid = IPCSkeleton::GetCallingPid();
106     if (std::any_of(secCompEnhanceData_.begin(), secCompEnhanceData_.end(),
107         [pid](const auto& e) { return e.pid == pid; })) {
108             LOGE(ATM_DOMAIN, ATM_TAG, "Register sec comp enhance exist, pid %{public}d.", pid);
109             return AccessTokenError::ERR_CALLBACK_ALREADY_EXIST;
110     }
111     SecCompEnhanceData enhance;
112     enhance.callback = enhanceData.callback;
113     enhance.pid = pid;
114     enhance.token = IPCSkeleton::GetCallingTokenID();
115     enhance.challenge = enhanceData.challenge;
116     enhance.sessionId = enhanceData.sessionId;
117     enhance.seqNum = enhanceData.seqNum;
118     if (memcpy_s(enhance.key, AES_KEY_STORAGE_LEN, enhanceData.key, AES_KEY_STORAGE_LEN) != EOK) {
119         return AccessTokenError::ERR_CALLBACK_ALREADY_EXIST;
120     }
121     secCompEnhanceData_.emplace_back(enhance);
122     LOGI(ATM_DOMAIN, ATM_TAG, "Register sec comp enhance success, pid %{public}d, total %{public}u.",
123         pid, static_cast<uint32_t>(secCompEnhanceData_.size()));
124     return RET_SUCCESS;
125 }
126 
UpdateSecCompEnhance(int32_t pid,uint32_t seqNum)127 int32_t SecCompEnhanceAgent::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum)
128 {
129     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
130     InitAppObserver();
131     for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
132         if (iter->pid == pid) {
133             iter->seqNum = seqNum;
134             LOGI(ATM_DOMAIN, ATM_TAG, "Update pid=%{public}d data successful.", pid);
135             return RET_SUCCESS;
136         }
137     }
138     return ERR_PARAM_INVALID;
139 }
140 
GetSecCompEnhance(int32_t pid,SecCompEnhanceData & enhanceData)141 int32_t SecCompEnhanceAgent::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhanceData)
142 {
143     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
144     InitAppObserver();
145     for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
146         if (iter->pid == pid) {
147             enhanceData = *iter;
148             LOGI(ATM_DOMAIN, ATM_TAG, "Get pid %{public}d data.", pid);
149             return RET_SUCCESS;
150         }
151     }
152     return ERR_PARAM_INVALID;
153 }
154 } // namespace AccessToken
155 } // namespace Security
156 } // namespace OHOS
157