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