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_service.h"
16 
17 #include <unistd.h>
18 
19 #include "app_mgr_death_recipient.h"
20 #include "bundle_info.h"
21 #include "bundle_mgr_client.h"
22 #include "hisysevent.h"
23 #include "hitrace_meter.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "sec_comp_enhance_adapter.h"
27 #include "sec_comp_err.h"
28 #include "sec_comp_manager.h"
29 #include "sec_comp_log.h"
30 #include "system_ability_definition.h"
31 
32 namespace OHOS {
33 namespace Security {
34 namespace SecurityComponent {
35 namespace {
36 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompService"};
37 static const int32_t ROOT_UID = 0;
38 static constexpr int32_t BASE_USER_RANGE = 200000;
39 }
40 
41 REGISTER_SYSTEM_ABILITY_BY_ID(SecCompService, SA_ID_SECURITY_COMPONENT_SERVICE, true);
42 
SecCompService(int32_t saId,bool runOnCreate)43 SecCompService::SecCompService(int32_t saId, bool runOnCreate)
44     : SystemAbility(saId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
45 {
46 }
47 
~SecCompService()48 SecCompService::~SecCompService()
49 {
50 }
51 
OnStart()52 void SecCompService::OnStart()
53 {
54     StartTrace(HITRACE_TAG_ACCESS_CONTROL, "SecurityComponentOnStart");
55     if (state_ == ServiceRunningState::STATE_RUNNING) {
56         SC_LOG_INFO(LABEL, "SecCompService has already started!");
57         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
58         return;
59     }
60     SC_LOG_INFO(LABEL, "SecCompService is starting");
61     if (!RegisterAppStateObserver()) {
62         SC_LOG_ERROR(LABEL, "Failed to register app state observer!");
63         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
64         return;
65     }
66     if (!Initialize()) {
67         SC_LOG_ERROR(LABEL, "Failed to initialize");
68         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
69         return;
70     }
71 
72     state_ = ServiceRunningState::STATE_RUNNING;
73     bool ret = Publish(this);
74     if (!ret) {
75         SC_LOG_ERROR(LABEL, "Failed to publish service!");
76         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
77         return;
78     }
79     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "SERVICE_INIT_SUCCESS",
80         HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "PID", getpid());
81     SC_LOG_INFO(LABEL, "Congratulations, SecCompService start successfully!");
82     FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
83 }
84 
OnStop()85 void SecCompService::OnStop()
86 {
87     SC_LOG_INFO(LABEL, "Stop service");
88     state_ = ServiceRunningState::STATE_NOT_START;
89     UnregisterAppStateObserver();
90 }
91 
RegisterAppStateObserver()92 bool SecCompService::RegisterAppStateObserver()
93 {
94     if (appStateObserver_ != nullptr) {
95         SC_LOG_INFO(LABEL, "AppStateObserver instance already create");
96         return true;
97     }
98     appStateObserver_ = new (std::nothrow) AppStateObserver();
99     if (appStateObserver_ == nullptr) {
100         SC_LOG_ERROR(LABEL, "Failed to create AppStateObserver instance");
101         return false;
102     }
103     sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
104     if (samgrClient == nullptr) {
105         SC_LOG_ERROR(LABEL, "Failed to get system ability manager");
106         appStateObserver_ = nullptr;
107         return false;
108     }
109     auto remoteObject = samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID);
110     iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(remoteObject);
111     if (iAppMgr_ == nullptr) {
112         SC_LOG_ERROR(LABEL, "Failed to get ability manager service");
113         appStateObserver_ = nullptr;
114         return false;
115     }
116 
117     if (iAppMgr_->RegisterApplicationStateObserver(appStateObserver_) != ERR_OK) {
118         SC_LOG_ERROR(LABEL, "Failed to Register app state observer");
119         iAppMgr_ = nullptr;
120         appStateObserver_ = nullptr;
121         return false;
122     }
123 
124     sptr<AppMgrDeathRecipient> appMgrDeathRecipient = new (std::nothrow) AppMgrDeathRecipient();
125     if (appMgrDeathRecipient == nullptr) {
126         SC_LOG_ERROR(LABEL, "Alloc appMgr death observer fail");
127         return false;
128     }
129 
130     if (!remoteObject->AddDeathRecipient(appMgrDeathRecipient)) {
131         SC_LOG_ERROR(LABEL, "Add service death observer fail");
132         return false;
133     }
134 
135     std::vector<AppExecFwk::AppStateData> list;
136     if (iAppMgr_->GetForegroundApplications(list) == ERR_OK) {
137         for (auto it = list.begin(); it != list.end(); ++it) {
138             appStateObserver_->AddProcessToForegroundSet(*it);
139         }
140     }
141     SC_LOG_ERROR(LABEL, "Register app state observer success");
142     return true;
143 }
144 
UnregisterAppStateObserver()145 void SecCompService::UnregisterAppStateObserver()
146 {
147     if (iAppMgr_ != nullptr && appStateObserver_ != nullptr) {
148         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
149     }
150 }
151 
GetCallerInfo(SecCompCallerInfo & caller)152 bool SecCompService::GetCallerInfo(SecCompCallerInfo& caller)
153 {
154     AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
155     int32_t pid = IPCSkeleton::GetCallingPid();
156     int32_t uid = IPCSkeleton::GetCallingUid();
157     if ((uid != ROOT_UID) && (AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) != AccessToken::TOKEN_HAP)) {
158         SC_LOG_ERROR(LABEL, "Get caller tokenId invalid");
159         return false;
160     }
161     if ((uid != ROOT_UID) && (!appStateObserver_->IsProcessForeground(pid, uid))) {
162         SC_LOG_ERROR(LABEL, "caller pid is not in foreground");
163         return false;
164     }
165     caller.tokenId = tokenId;
166     caller.pid = pid;
167     caller.uid = uid;
168     return true;
169 }
170 
ParseParams(const std::string & componentInfo,SecCompCallerInfo & caller,nlohmann::json & jsonRes)171 int32_t SecCompService::ParseParams(const std::string& componentInfo,
172     SecCompCallerInfo& caller, nlohmann::json& jsonRes)
173 {
174     if (!GetCallerInfo(caller)) {
175         SC_LOG_ERROR(LABEL, "Check caller failed");
176         return SC_SERVICE_ERROR_VALUE_INVALID;
177     }
178 
179     jsonRes = nlohmann::json::parse(componentInfo, nullptr, false);
180     if (jsonRes.is_discarded()) {
181         SC_LOG_ERROR(LABEL, "component info invalid %{public}s", componentInfo.c_str());
182         return SC_SERVICE_ERROR_VALUE_INVALID;
183     }
184     return SC_OK;
185 }
186 
RegisterSecurityComponent(SecCompType type,const std::string & componentInfo,int32_t & scId)187 int32_t SecCompService::RegisterSecurityComponent(SecCompType type,
188     const std::string& componentInfo, int32_t& scId)
189 {
190     StartTrace(HITRACE_TAG_ACCESS_CONTROL, "SecurityComponentRegister");
191     SecCompCallerInfo caller;
192     caller.tokenId = IPCSkeleton::GetCallingTokenID();
193     caller.pid = IPCSkeleton::GetCallingPid();
194     caller.uid = IPCSkeleton::GetCallingUid();
195     if ((caller.uid != ROOT_UID)
196         && (AccessToken::AccessTokenKit::GetTokenTypeFlag(caller.tokenId) != AccessToken::TOKEN_HAP)) {
197         SC_LOG_ERROR(LABEL, "Get caller tokenId invalid");
198         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
199         return SC_SERVICE_ERROR_VALUE_INVALID;
200     }
201     nlohmann::json jsonRes = nlohmann::json::parse(componentInfo, nullptr, false);
202     if (jsonRes.is_discarded()) {
203         SC_LOG_ERROR(LABEL, "component info invalid %{public}s", componentInfo.c_str());
204         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
205         return SC_SERVICE_ERROR_VALUE_INVALID;
206     }
207 
208     int32_t res = SecCompManager::GetInstance().RegisterSecurityComponent(type, jsonRes, caller, scId);
209     FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
210 
211     int32_t uid = IPCSkeleton::GetCallingUid();
212     OHOS::AppExecFwk::BundleMgrClient bmsClient;
213     std::string bundleName = "";
214     bmsClient.GetNameForUid(uid, bundleName);
215 
216     AppExecFwk::BundleInfo bundleInfo;
217     int32_t userId = uid / BASE_USER_RANGE;
218     bmsClient.GetBundleInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, userId);
219 
220     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "REGISTER_SUCCESS",
221         HiviewDFX::HiSysEvent::EventType::BEHAVIOR, "CALLER_UID", IPCSkeleton::GetCallingUid(),
222         "CALLER_PID", IPCSkeleton::GetCallingRealPid(), "CALLER_BUNDLE_NAME", bundleName, "CALLER_BUNDLE_VERSION",
223         bundleInfo.versionName, "SC_ID", scId, "SC_TYPE", type);
224     return res;
225 }
226 
UpdateSecurityComponent(int32_t scId,const std::string & componentInfo)227 int32_t SecCompService::UpdateSecurityComponent(int32_t scId, const std::string& componentInfo)
228 {
229     SecCompCallerInfo caller;
230     nlohmann::json jsonRes;
231     if (ParseParams(componentInfo, caller, jsonRes) != SC_OK) {
232         return SC_SERVICE_ERROR_VALUE_INVALID;
233     }
234     return SecCompManager::GetInstance().UpdateSecurityComponent(scId, jsonRes, caller);
235 }
236 
UnregisterSecurityComponent(int32_t scId)237 int32_t SecCompService::UnregisterSecurityComponent(int32_t scId)
238 {
239     SecCompCallerInfo caller;
240     caller.tokenId = IPCSkeleton::GetCallingTokenID();
241     caller.pid = IPCSkeleton::GetCallingPid();
242     caller.uid = IPCSkeleton::GetCallingUid();
243 
244     return SecCompManager::GetInstance().UnregisterSecurityComponent(scId, caller);
245 }
246 
ReportSecurityComponentClickEvent(int32_t scId,const std::string & componentInfo,const SecCompClickEvent & clickInfo,sptr<IRemoteObject> callerToken,sptr<IRemoteObject> dialogCallback)247 int32_t SecCompService::ReportSecurityComponentClickEvent(int32_t scId,
248     const std::string& componentInfo, const SecCompClickEvent& clickInfo,
249     sptr<IRemoteObject> callerToken, sptr<IRemoteObject> dialogCallback)
250 {
251     StartTrace(HITRACE_TAG_ACCESS_CONTROL, "SecurityComponentClick");
252     SecCompCallerInfo caller;
253     nlohmann::json jsonRes;
254     if (ParseParams(componentInfo, caller, jsonRes) != SC_OK) {
255         FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
256         return SC_SERVICE_ERROR_VALUE_INVALID;
257     }
258     std::vector<sptr<IRemoteObject>> remoteArr = { callerToken, dialogCallback };
259     int32_t res =
260         SecCompManager::GetInstance().ReportSecurityComponentClickEvent(scId, jsonRes, caller, clickInfo,
261         remoteArr);
262     FinishTrace(HITRACE_TAG_ACCESS_CONTROL);
263     return res;
264 }
265 
PreRegisterSecCompProcess()266 int32_t SecCompService::PreRegisterSecCompProcess()
267 {
268     SecCompCallerInfo caller;
269     if (!GetCallerInfo(caller)) {
270         SC_LOG_ERROR(LABEL, "Check caller failed");
271         return SC_SERVICE_ERROR_VALUE_INVALID;
272     }
273     return SecCompManager::GetInstance().AddSecurityComponentProcess(caller);
274 }
275 
VerifySavePermission(AccessToken::AccessTokenID tokenId)276 bool SecCompService::VerifySavePermission(AccessToken::AccessTokenID tokenId)
277 {
278     return SecCompPermManager::GetInstance().VerifySavePermission(tokenId);
279 }
280 
GetEnhanceRemoteObject()281 sptr<IRemoteObject> SecCompService::GetEnhanceRemoteObject()
282 {
283     return SecCompEnhanceAdapter::GetEnhanceRemoteObject();
284 }
285 
Dump(int fd,const std::vector<std::u16string> & args)286 int SecCompService::Dump(int fd, const std::vector<std::u16string>& args)
287 {
288     if (fd < 0) {
289         return ERR_INVALID_VALUE;
290     }
291 
292     dprintf(fd, "SecCompService Dump:\n");
293     std::string arg0 = ((args.size() == 0)? "" : Str16ToStr8(args.at(0)));
294     if (arg0.compare("-h") == 0) {
295         dprintf(fd, "Usage:\n");
296         dprintf(fd, "       -h: command help\n");
297         dprintf(fd, "       -a: dump all sec component\n");
298         dprintf(fd, "       -p: dump foreground processes\n");
299     } else if (arg0.compare("-p") == 0) {
300         std::string dumpStr;
301         appStateObserver_->DumpProcess(dumpStr);
302         dprintf(fd, "%s\n", dumpStr.c_str());
303     }  else if (arg0.compare("-a") == 0 || arg0 == "") {
304         std::string dumpStr;
305         SecCompManager::GetInstance().DumpSecComp(dumpStr);
306         dprintf(fd, "%s\n", dumpStr.c_str());
307     }
308     return ERR_OK;
309 }
310 
Initialize() const311 bool SecCompService::Initialize() const
312 {
313     return SecCompManager::GetInstance().Initialize();
314 }
315 }  // namespace SecurityComponent
316 }  // namespace Security
317 }  // namespace OHOS
318