• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "nlohmann/json.hpp"
17 #include "system_ability_manager.h"
18 #include "system_ability_manager_util.h"
19 #include "parameter.h"
20 #include "parameters.h"
21 #include "accesstoken_kit.h"
22 #include "ipc_skeleton.h"
23 #include "string_ex.h"
24 #include "tools.h"
25 #include "sam_log.h"
26 
27 namespace OHOS {
28 namespace fs = std::filesystem;
29 using namespace std;
30 #ifdef SUPPORT_PENGLAI_MODE
31 using PenglaiFunc = bool (*)(const int32_t, const int32_t);
32 constexpr const char* PENGLAI_SO_PATH = "libpenglai_client.z.so";
33 constexpr const char* PENGLAI_SYM = "IsLaunchAllowedByUid";
34 void* SamgrUtil::penglaiFunc_ = InitPenglaiFunc();
35 #endif
36 constexpr int32_t MAX_NAME_SIZE = 200;
37 constexpr int32_t SPLIT_NAME_VECTOR_SIZE = 2;
38 constexpr int32_t UID_ROOT = 0;
39 constexpr int32_t UID_SYSTEM = 1000;
40 constexpr int32_t SHFIT_BIT = 32;
41 
42 constexpr const char* EVENT_TYPE = "eventId";
43 constexpr const char* EVENT_NAME = "name";
44 constexpr const char* EVENT_VALUE = "value";
45 constexpr const char* EVENT_EXTRA_DATA_ID = "extraDataId";
46 constexpr const char* MODULE_UPDATE_PARAM = "persist.samgr.moduleupdate";
47 constexpr const char* PENG_LAI_PARAM = "ohos.boot.minisys.mode";
48 constexpr const char* PENG_LAI = "penglai";
49 constexpr const char* PENGLAI_PATH = "profile/penglai";
50 std::shared_ptr<FFRTHandler> SamgrUtil::setParmHandler_ = make_shared<FFRTHandler>("setParmHandler");
51 
IsNameInValid(const std::u16string & name)52 bool SamgrUtil::IsNameInValid(const std::u16string& name)
53 {
54     HILOGD("%{public}s called:name = %{public}s", __func__, Str16ToStr8(name).c_str());
55     bool ret = false;
56     if (name.empty() || name.size() > MAX_NAME_SIZE || DeleteBlank(name).empty()) {
57         ret = true;
58     }
59 
60     return ret;
61 }
62 
ParseRemoteSaName(const std::u16string & name,std::string & deviceId,std::u16string & saName)63 void SamgrUtil::ParseRemoteSaName(const std::u16string& name, std::string& deviceId,
64     std::u16string& saName)
65 {
66     vector<string> strVector;
67     SplitStr(Str16ToStr8(name), "_", strVector);
68     if (strVector.size() == SPLIT_NAME_VECTOR_SIZE) {
69         deviceId = strVector[0];
70         saName = Str8ToStr16(strVector[1]);
71     }
72 }
73 
CheckDistributedPermission()74 bool SamgrUtil::CheckDistributedPermission()
75 {
76     auto callingUid = IPCSkeleton::GetCallingUid();
77     if (callingUid != UID_ROOT && callingUid != UID_SYSTEM) {
78         return false;
79     }
80     return true;
81 }
82 
IsSameEvent(const OnDemandEvent & event,std::list<OnDemandEvent> & enableOnceList)83 bool SamgrUtil::IsSameEvent(const OnDemandEvent& event, std::list<OnDemandEvent>& enableOnceList)
84 {
85     for (auto iter = enableOnceList.begin(); iter != enableOnceList.end(); iter++) {
86         if (event.eventId == iter->eventId && event.name == iter->name && event.value == iter->value) {
87             HILOGI("event already exits in enable-once list");
88             return true;
89         }
90     }
91     return false;
92 }
93 
EventToStr(const OnDemandEvent & event)94 std::string SamgrUtil::EventToStr(const OnDemandEvent& event)
95 {
96     nlohmann::json eventJson;
97     eventJson[EVENT_TYPE] = event.eventId;
98     eventJson[EVENT_NAME] = event.name;
99     eventJson[EVENT_VALUE] = event.value;
100     eventJson[EVENT_EXTRA_DATA_ID] = event.extraDataId;
101     std::string eventStr = eventJson.dump();
102     return eventStr;
103 }
104 
TransformDeviceId(const std::string & deviceId,int32_t type,bool isPrivate)105 std::string SamgrUtil::TransformDeviceId(const std::string& deviceId, int32_t type, bool isPrivate)
106 {
107     return isPrivate ? std::string() : deviceId;
108 }
109 
CheckCallerProcess(const CommonSaProfile & saProfile)110 bool SamgrUtil::CheckCallerProcess(const CommonSaProfile& saProfile)
111 {
112     if (!CheckCallerProcess(Str16ToStr8(saProfile.process))) {
113         HILOGE("can't operate SA: %{public}d by proc:%{public}s",
114             saProfile.saId, Str16ToStr8(saProfile.process).c_str());
115         return false;
116     }
117     return true;
118 }
119 
CheckCallerProcess(const std::string & callProcess)120 bool SamgrUtil::CheckCallerProcess(const std::string& callProcess)
121 {
122     uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
123     Security::AccessToken::NativeTokenInfo nativeTokenInfo;
124     int32_t tokenInfoResult = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
125     if (tokenInfoResult != ERR_OK) {
126         HILOGE("get token info failed");
127         return false;
128     }
129 
130     if (nativeTokenInfo.processName != callProcess) {
131         HILOGE("can't operate by proc:%{public}s", nativeTokenInfo.processName.c_str());
132         return false;
133     }
134     return true;
135 }
136 
CheckAllowUpdate(OnDemandPolicyType type,const CommonSaProfile & saProfile)137 bool SamgrUtil::CheckAllowUpdate(OnDemandPolicyType type, const CommonSaProfile& saProfile)
138 {
139     if (type == OnDemandPolicyType::START_POLICY && saProfile.startAllowUpdate) {
140         return true;
141     } else if (type == OnDemandPolicyType::STOP_POLICY && saProfile.stopAllowUpdate) {
142         return true;
143     }
144     return false;
145 }
146 
ConvertToOnDemandEvent(const SystemAbilityOnDemandEvent & from,OnDemandEvent & to)147 void SamgrUtil::ConvertToOnDemandEvent(const SystemAbilityOnDemandEvent& from, OnDemandEvent& to)
148 {
149     to.eventId = static_cast<int32_t>(from.eventId);
150     to.name = from.name;
151     to.value = from.value;
152     to.persistence = from.persistence;
153     for (auto& item : from.conditions) {
154         OnDemandCondition condition;
155         condition.eventId = static_cast<int32_t>(item.eventId);
156         condition.name = item.name;
157         condition.value = item.value;
158         to.conditions.push_back(condition);
159     }
160     to.enableOnce = from.enableOnce;
161 }
162 
ConvertToSystemAbilityOnDemandEvent(const OnDemandEvent & from,SystemAbilityOnDemandEvent & to)163 void SamgrUtil::ConvertToSystemAbilityOnDemandEvent(const OnDemandEvent& from,
164     SystemAbilityOnDemandEvent& to)
165 {
166     to.eventId = static_cast<OnDemandEventId>(from.eventId);
167     to.name = from.name;
168     to.value = from.value;
169     to.persistence = from.persistence;
170     for (auto& item : from.conditions) {
171         SystemAbilityOnDemandCondition condition;
172         condition.eventId = static_cast<OnDemandEventId>(item.eventId);
173         condition.name = item.name;
174         condition.value = item.value;
175         to.conditions.push_back(condition);
176     }
177     to.enableOnce = from.enableOnce;
178 }
179 
GenerateFreKey(int32_t uid,int32_t saId)180 uint64_t SamgrUtil::GenerateFreKey(int32_t uid, int32_t saId)
181 {
182     uint32_t uSaid = static_cast<uint32_t>(saId);
183     uint64_t key = static_cast<uint64_t>(uid);
184     return (key << SHFIT_BIT) | uSaid;
185 }
186 
GetCacheCommonEventSa(const OnDemandEvent & event,const std::list<SaControlInfo> & saControlList)187 std::list<int32_t> SamgrUtil::GetCacheCommonEventSa(const OnDemandEvent& event,
188     const std::list<SaControlInfo>& saControlList)
189 {
190     std::list<int32_t> saList;
191     if (event.eventId != COMMON_EVENT || event.extraDataId == -1) {
192         return saList;
193     }
194     for (auto& item : saControlList) {
195         if (item.cacheCommonEvent) {
196             saList.emplace_back(item.saId);
197         }
198     }
199     return saList;
200 }
201 
SetModuleUpdateParam(const std::string & key,const std::string & value)202 void SamgrUtil::SetModuleUpdateParam(const std::string& key, const std::string& value)
203 {
204     auto SetParamTask = [=] () {
205         int ret = SetParameter(key.c_str(), value.c_str());
206         if (ret != 0) {
207             HILOGE("SetModuleUpdateParam SetParameter error:%{public}d!", ret);
208             return;
209         }
210     };
211     setParmHandler_->PostTask(SetParamTask);
212 }
213 
SendUpdateSaState(int32_t systemAbilityId,const std::string & updateSaState)214 void SamgrUtil::SendUpdateSaState(int32_t systemAbilityId, const std::string& updateSaState)
215 {
216     if (SystemAbilityManager::GetInstance()->IsModuleUpdate(systemAbilityId)) {
217         std::string startKey = std::string(MODULE_UPDATE_PARAM) + ".start";
218         std::string saKey = std::string(MODULE_UPDATE_PARAM) + "." + std::to_string(systemAbilityId);
219         SamgrUtil::SetModuleUpdateParam(startKey, "true");
220         SamgrUtil::SetModuleUpdateParam(saKey, updateSaState);
221     }
222 }
223 
InvalidateSACache()224 void SamgrUtil::InvalidateSACache()
225 {
226     auto invalidateCacheTask = [] () {
227         SystemAbilityManager::GetInstance()->InvalidateCache();
228     };
229     setParmHandler_->PostTask(invalidateCacheTask);
230 }
231 
FilterCommonSaProfile(const SaProfile & oldProfile,CommonSaProfile & newProfile)232 void SamgrUtil::FilterCommonSaProfile(const SaProfile& oldProfile, CommonSaProfile& newProfile)
233 {
234     newProfile.process = oldProfile.process;
235     newProfile.saId = oldProfile.saId;
236     newProfile.moduleUpdate = oldProfile.moduleUpdate;
237     newProfile.distributed = oldProfile.distributed;
238     newProfile.cacheCommonEvent = oldProfile.cacheCommonEvent;
239     newProfile.startAllowUpdate = oldProfile.startOnDemand.allowUpdate;
240     newProfile.stopAllowUpdate = oldProfile.stopOnDemand.allowUpdate;
241     newProfile.recycleStrategy = oldProfile.recycleStrategy;
242     newProfile.extension.assign(oldProfile.extension.begin(), oldProfile.extension.end());
243 }
244 
CheckPengLai()245 bool SamgrUtil::CheckPengLai()
246 {
247     std::string defaultValue = "";
248     std::string paramValue = system::GetParameter(PENG_LAI_PARAM, defaultValue);
249     return paramValue == PENG_LAI;
250 }
251 
252 #ifdef SUPPORT_PENGLAI_MODE
InitPenglaiFunc()253 void* SamgrUtil::InitPenglaiFunc()
254 {
255     if (!CheckPengLai()) {
256         HILOGI("InitPenglaiFunc not penglai");
257         return nullptr;
258     }
259     DlHandle handle = dlopen(PENGLAI_SO_PATH, RTLD_NOW);
260     if (handle == nullptr) {
261         HILOGE("InitPenglaiFunc dlopen %{public}s so failed.", PENGLAI_SO_PATH);
262         return nullptr;
263     }
264     void* func = dlsym(handle, PENGLAI_SYM);
265     if (func == nullptr) {
266         HILOGE("InitPenglaiFunc dlsym %{public}s symbol failed.", PENGLAI_SYM);
267         dlclose(handle);
268         return nullptr;
269     }
270     HILOGI("InitPenglaiFunc success.");
271     return func;
272 }
273 
CheckPengLaiPermission(int32_t systemAbilityId)274 bool SamgrUtil::CheckPengLaiPermission(int32_t systemAbilityId)
275 {
276     auto callingUid = IPCSkeleton::GetCallingUid();
277 
278     if (penglaiFunc_ == nullptr) {
279         return true;
280     }
281     PenglaiFunc IsLaunchAllowedByUid = (PenglaiFunc)penglaiFunc_;
282     bool isAllow = IsLaunchAllowedByUid(callingUid, systemAbilityId);
283     if (!isAllow) {
284         HILOGE("IsLaunchAllowedByUid failed. callingUid:%{public}d, SA:%{public}d", callingUid, systemAbilityId);
285         return false;
286     }
287     HILOGD("CheckPengLaiPerm suc. cUid:%{public}d,SA:%{public}d", callingUid, systemAbilityId);
288     return isAllow;
289 }
290 #endif
291 
GetFilesFromPath(const std::string & path,std::map<std::string,std::string> & fileNamesMap)292 void SamgrUtil::GetFilesFromPath(const std::string& path, std::map<std::string, std::string>& fileNamesMap)
293 {
294     CfgFiles* filePaths = GetCfgFiles(path.c_str());
295     for (int i = 0; filePaths && i < MAX_CFG_POLICY_DIRS_CNT; i++) {
296         if (filePaths->paths[i] == nullptr) {
297             continue;
298         }
299         HILOGI("GetFilesByPriority filePaths : %{public}s!", filePaths->paths[i]);
300         std::vector<std::string> files;
301         GetDirFiles(filePaths->paths[i], files);
302         for (const auto& file : files) {
303             HILOGD("GetFilesByPriority file : %{public}s!", file.c_str());
304             fileNamesMap[fs::path(file).filename().string()] = file;
305         }
306     }
307     FreeCfgFiles(filePaths);
308 }
309 
GetFilesByPriority(const std::string & path,std::vector<std::string> & fileNames)310 void SamgrUtil::GetFilesByPriority(const std::string& path, std::vector<std::string>& fileNames)
311 {
312     std::map<std::string, std::string> fileNamesMap;
313 
314     GetFilesFromPath(path, fileNamesMap);
315 
316     if (SamgrUtil::CheckPengLai()) {
317         HILOGI("GetFilesByPriority penglai!");
318         GetFilesFromPath(PENGLAI_PATH, fileNamesMap);
319     }
320 
321     for (const auto& pair : fileNamesMap) {
322         HILOGD("GetFilesByPriority files : %{public}s!", pair.second.c_str());
323         fileNames.push_back(pair.second);
324     }
325 }
326 }
327