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 "privacy_sec_comp_enhance_agent.h"
16 
17 #include "access_token.h"
18 #include "accesstoken_kit.h"
19 #include "accesstoken_log.h"
20 #include "app_manager_access_client.h"
21 #include "ipc_skeleton.h"
22 #include "privacy_error.h"
23 #include "securec.h"
24 
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
30     LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacySecCompEnhanceAgent"
31 };
32 std::recursive_mutex g_instanceMutex;
33 }
OnProcessDied(const ProcessData & processData)34 void PrivacyAppUsingSecCompStateObserver::OnProcessDied(const ProcessData &processData)
35 {
36     ACCESSTOKEN_LOG_INFO(LABEL, "OnProcessDied pid %{public}d", processData.pid);
37     PrivacySecCompEnhanceAgent::GetInstance().RemoveSecCompEnhance(processData.pid);
38 }
39 
NotifyAppManagerDeath()40 void PrivacySecCompAppManagerDeathCallback::NotifyAppManagerDeath()
41 {
42     ACCESSTOKEN_LOG_INFO(LABEL, "AppManagerDeath called");
43 
44     PrivacySecCompEnhanceAgent::GetInstance().OnAppMgrRemoteDiedHandle();
45 }
46 
GetInstance()47 PrivacySecCompEnhanceAgent& PrivacySecCompEnhanceAgent::GetInstance()
48 {
49     static PrivacySecCompEnhanceAgent* instance = nullptr;
50     if (instance == nullptr) {
51         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
52         if (instance == nullptr) {
53             instance = new PrivacySecCompEnhanceAgent();
54         }
55     }
56     return *instance;
57 }
58 
InitAppObserver()59 void PrivacySecCompEnhanceAgent::InitAppObserver()
60 {
61     if (observer_ != nullptr) {
62         return;
63     }
64     observer_ = new (std::nothrow) PrivacyAppUsingSecCompStateObserver();
65     if (observer_ == nullptr) {
66         ACCESSTOKEN_LOG_ERROR(LABEL, "New observer failed.");
67         return;
68     }
69     if (AppManagerAccessClient::GetInstance().RegisterApplicationStateObserver(observer_) != 0) {
70         ACCESSTOKEN_LOG_ERROR(LABEL, "Register observer failed.");
71         observer_ = nullptr;
72         return;
73     }
74     if (appManagerDeathCallback_ == nullptr) {
75         appManagerDeathCallback_ = std::make_shared<PrivacySecCompAppManagerDeathCallback>();
76         AppManagerAccessClient::GetInstance().RegisterDeathCallback(appManagerDeathCallback_);
77     }
78 }
79 
PrivacySecCompEnhanceAgent()80 PrivacySecCompEnhanceAgent::PrivacySecCompEnhanceAgent()
81 {
82     InitAppObserver();
83 }
84 
~PrivacySecCompEnhanceAgent()85 PrivacySecCompEnhanceAgent::~PrivacySecCompEnhanceAgent()
86 {
87     if (observer_ != nullptr) {
88         AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(observer_);
89         observer_ = nullptr;
90     }
91 }
92 
OnAppMgrRemoteDiedHandle()93 void PrivacySecCompEnhanceAgent::OnAppMgrRemoteDiedHandle()
94 {
95     ACCESSTOKEN_LOG_INFO(LABEL, "OnAppMgrRemoteDiedHandle.");
96     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
97     secCompEnhanceData_.clear();
98     observer_ = nullptr;
99 }
100 
RemoveSecCompEnhance(int pid)101 void PrivacySecCompEnhanceAgent::RemoveSecCompEnhance(int pid)
102 {
103     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
104     for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
105         if (iter->pid == pid) {
106             secCompEnhanceData_.erase(iter);
107             ACCESSTOKEN_LOG_INFO(LABEL, "Remove pid %{public}d data.", pid);
108             return;
109         }
110     }
111     ACCESSTOKEN_LOG_ERROR(LABEL, "Not found pid %{public}d data.", pid);
112     return;
113 }
114 
RegisterSecCompEnhance(const SecCompEnhanceData & enhanceData)115 int32_t PrivacySecCompEnhanceAgent::RegisterSecCompEnhance(const SecCompEnhanceData& enhanceData)
116 {
117     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
118     InitAppObserver();
119     int pid = IPCSkeleton::GetCallingPid();
120     if (std::any_of(secCompEnhanceData_.begin(), secCompEnhanceData_.end(),
121         [pid](const auto& e) { return e.pid == pid; })) {
122             ACCESSTOKEN_LOG_ERROR(LABEL, "Register sec comp enhance exist, pid %{public}d.", pid);
123             return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
124     }
125     SecCompEnhanceData enhance;
126     enhance.callback = enhanceData.callback;
127     enhance.pid = pid;
128     enhance.token = IPCSkeleton::GetCallingTokenID();
129     enhance.challenge = enhanceData.challenge;
130     enhance.sessionId = enhanceData.sessionId;
131     enhance.seqNum = enhanceData.seqNum;
132     if (memcpy_s(enhance.key, AES_KEY_STORAGE_LEN, enhanceData.key, AES_KEY_STORAGE_LEN) != EOK) {
133         return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
134     }
135     secCompEnhanceData_.emplace_back(enhance);
136     ACCESSTOKEN_LOG_INFO(LABEL, "Register sec comp enhance success, pid %{public}d, total %{public}u.",
137         pid, static_cast<uint32_t>(secCompEnhanceData_.size()));
138     return RET_SUCCESS;
139 }
140 
UpdateSecCompEnhance(int32_t pid,uint32_t seqNum)141 int32_t PrivacySecCompEnhanceAgent::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum)
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             iter->seqNum = seqNum;
148             ACCESSTOKEN_LOG_INFO(LABEL, "Update pid=%{public}d data successful.", pid);
149             return RET_SUCCESS;
150         }
151     }
152     return ERR_PARAM_INVALID;
153 }
154 
GetSecCompEnhance(int32_t pid,SecCompEnhanceData & enhanceData)155 int32_t PrivacySecCompEnhanceAgent::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhanceData)
156 {
157     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
158     InitAppObserver();
159     for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); ++iter) {
160         if (iter->pid == pid) {
161             enhanceData = *iter;
162             ACCESSTOKEN_LOG_INFO(LABEL, "Get pid %{public}d data.", pid);
163             return RET_SUCCESS;
164         }
165     }
166     return ERR_PARAM_INVALID;
167 }
168 
GetSpecialSecCompEnhance(const std::string & bundleName,std::vector<SecCompEnhanceData> & enhanceList)169 int32_t PrivacySecCompEnhanceAgent::GetSpecialSecCompEnhance(const std::string& bundleName,
170     std::vector<SecCompEnhanceData>& enhanceList)
171 {
172     std::lock_guard<std::mutex> lock(secCompEnhanceMutex_);
173     for (auto iter = secCompEnhanceData_.begin(); iter != secCompEnhanceData_.end(); iter++) {
174         HapTokenInfo info;
175         if (AccessTokenKit::GetHapTokenInfo(iter->token, info) == AccessTokenKitRet::RET_SUCCESS) {
176             if (bundleName == info.bundleName) {
177                 enhanceList.emplace_back(*iter);
178             }
179         }
180     }
181     return RET_SUCCESS;
182 }
183 } // namespace AccessToken
184 } // namespace Security
185 } // namespace OHOS
186