1 /*
2 * Copyright (c) 2022 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 "bundle_sandbox_data_mgr.h"
17
18 #include "bundle_mgr_service.h"
19
20 namespace OHOS {
21 namespace AppExecFwk {
BundleSandboxDataMgr()22 BundleSandboxDataMgr::BundleSandboxDataMgr()
23 {
24 APP_LOGI("BundleSandboxDataMgr instance is created");
25 sandboxManagerDb_ = std::make_shared<SandboxManagerRdb>();
26 if (sandboxManagerDb_ == nullptr) {
27 APP_LOGE("create sandboxManagerDb_ failed");
28 return;
29 }
30 if (!RestoreSandboxPersistentInnerBundleInfo()) {
31 APP_LOGW("RestoreSandboxPersistentInnerBundleInfo failed");
32 }
33 }
34
~BundleSandboxDataMgr()35 BundleSandboxDataMgr::~BundleSandboxDataMgr()
36 {
37 APP_LOGI("BundleSandboxDataMgr instance is destroyed");
38 }
39
SaveSandboxAppInfo(const InnerBundleInfo & info,const int32_t & appIndex)40 void BundleSandboxDataMgr::SaveSandboxAppInfo(const InnerBundleInfo &info, const int32_t &appIndex)
41 {
42 APP_LOGI("SaveSandboxAppInfo begin");
43 std::string bundleName = info.GetBundleName();
44 if (bundleName.empty()) {
45 APP_LOGE("SaveSandboxAppInfo bundleName is empty");
46 return;
47 }
48 std::string key = std::to_string(appIndex) + Constants::FILE_UNDERLINE + bundleName;
49 std::unique_lock<std::shared_mutex> lock(sandboxAppMutex_);
50 sandboxAppInfos_[key] = info;
51 APP_LOGD("save sandbox app %{public}s info successfully", key.c_str());
52 }
53
DeleteSandboxAppInfo(const std::string & bundleName,const int32_t & appIndex)54 void BundleSandboxDataMgr::DeleteSandboxAppInfo(const std::string &bundleName, const int32_t &appIndex)
55 {
56 APP_LOGI("DeleteSandboxAppInfo begin");
57 if (bundleName.empty()) {
58 APP_LOGE("DeleteSandboxAppInfo bundleName is empty");
59 return;
60 }
61 auto key = std::to_string(appIndex) + Constants::FILE_UNDERLINE + bundleName;
62 std::unique_lock<std::shared_mutex> lock(sandboxAppMutex_);
63 auto ret = sandboxAppInfos_.erase(key);
64 if (ret == 0) {
65 APP_LOGE("delete sandbox app info failed due to no sandbox app in the dataMgr");
66 return;
67 }
68 APP_LOGD("delete sandbox app %{public}s info successfully", key.c_str());
69 }
70
GetSandboxAppInfo(const std::string & bundleName,const int32_t & appIndex,int32_t & userId,InnerBundleInfo & info) const71 ErrCode BundleSandboxDataMgr::GetSandboxAppInfo(
72 const std::string &bundleName, const int32_t &appIndex, int32_t &userId, InnerBundleInfo &info) const
73 {
74 APP_LOGI("GetSandboxAppInfo begin");
75 if (bundleName.empty()) {
76 APP_LOGE("GetSandboxAppInfo bundleName is empty");
77 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
78 }
79 if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX) {
80 APP_LOGE("GetSandboxAppInfo appIndex is invalid");
81 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
82 }
83 if (userId < Constants::DEFAULT_USERID) {
84 APP_LOGE("userId(%{public}d) is invalid", userId);
85 return ERR_APPEXECFWK_SANDBOX_INSTALL_PARAM_ERROR;
86 }
87
88 auto key = std::to_string(appIndex) + Constants::FILE_UNDERLINE + bundleName;
89
90 {
91 std::shared_lock<std::shared_mutex> lock(sandboxAppMutex_);
92 auto it = sandboxAppInfos_.find(key);
93 if (it == sandboxAppInfos_.end()) {
94 APP_LOGE("GetSandboxAppInfo no sandbox app info can be found");
95 return ERR_APPEXECFWK_SANDBOX_INSTALL_NO_SANDBOX_APP_INFO;
96 }
97
98 InnerBundleUserInfo userInfo;
99 if (!(it->second).GetInnerBundleUserInfo(userId, userInfo)) {
100 APP_LOGE("the sandbox app is not installed at this user %{public}d", userId);
101 return ERR_APPEXECFWK_SANDBOX_INSTALL_NOT_INSTALLED_AT_SPECIFIED_USERID;
102 }
103 info = it->second;
104 }
105
106 APP_LOGI("GetSandboxAppInfo successfully");
107 return ERR_OK;
108 }
109
GetSandboxAppBundleInfo(const std::string & bundleName,const int32_t & appIndex,const int32_t & userId,BundleInfo & info) const110 ErrCode BundleSandboxDataMgr::GetSandboxAppBundleInfo(
111 const std::string &bundleName, const int32_t &appIndex, const int32_t &userId, BundleInfo &info) const
112 {
113 APP_LOGI("GetSandboxAppBundleInfo begin");
114 InnerBundleInfo innerBundleInfo;
115 int32_t requestUserId = userId;
116 ErrCode result = ERR_OK;
117 if ((result = GetSandboxAppInfo(bundleName, appIndex, requestUserId, innerBundleInfo)) != ERR_OK) {
118 APP_LOGE("GetSandboxAppBundleInfo get sandbox app info failed");
119 return result;
120 }
121 InnerBundleUserInfo userInfo;
122 if (!innerBundleInfo.GetInnerBundleUserInfo(requestUserId, userInfo)) {
123 APP_LOGE("the origin application is not installed at current user");
124 return ERR_APPEXECFWK_SANDBOX_INSTALL_NOT_INSTALLED_AT_SPECIFIED_USERID;
125 }
126
127 innerBundleInfo.GetBundleInfo(
128 BundleFlag::GET_BUNDLE_DEFAULT |
129 BundleFlag::GET_BUNDLE_WITH_ABILITIES |
130 BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION |
131 BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO |
132 BundleFlag::GET_BUNDLE_WITH_HASH_VALUE, info, requestUserId);
133 APP_LOGI("GetSandboxAppBundleInfo successfully");
134 return ERR_OK;
135 }
136
GenerateSandboxAppIndex(const std::string & bundleName)137 int32_t BundleSandboxDataMgr::GenerateSandboxAppIndex(const std::string &bundleName)
138 {
139 APP_LOGI("GenerateSandboxAppIndex begin");
140 if (bundleName.empty()) {
141 APP_LOGE("GenerateSandboxAppIndex bundleName is empty");
142 return Constants::INITIAL_SANDBOX_APP_INDEX;
143 }
144 std::unique_lock<std::mutex> lock(sandboxAppIndexMapMutex_);
145 auto firstIterator = sandboxAppIndexMap_.find(bundleName);
146 if (firstIterator == sandboxAppIndexMap_.end()) {
147 std::set<int32_t> innerSet { Constants::INITIAL_SANDBOX_APP_INDEX + 1 };
148 sandboxAppIndexMap_.emplace(bundleName, innerSet);
149 APP_LOGD("GenerateSandboxAppIndex successfully");
150 return Constants::INITIAL_SANDBOX_APP_INDEX + 1;
151 }
152
153 if (firstIterator->second.empty()) {
154 firstIterator->second.insert(Constants::INITIAL_SANDBOX_APP_INDEX + 1);
155 APP_LOGD("GenerateSandboxAppIndex successfully");
156 return Constants::INITIAL_SANDBOX_APP_INDEX + 1;
157 }
158
159 int32_t pre = Constants::INITIAL_SANDBOX_APP_INDEX;
160 for (const auto &item : firstIterator->second) {
161 if (item == pre + 1) {
162 pre++;
163 continue;
164 }
165 break;
166 }
167
168 int32_t newAppIndex = pre + 1;
169 if (newAppIndex > Constants::MAX_SANDBOX_APP_INDEX) {
170 APP_LOGE("GenerateSandboxAppIndex failed due to exceed limitation of maximum appIndex");
171 return Constants::INITIAL_SANDBOX_APP_INDEX;
172 }
173 firstIterator->second.insert(newAppIndex);
174 APP_LOGD("GenerateSandboxAppIndex successfully with appIndex %{public}d", newAppIndex);
175 return newAppIndex;
176 }
177
DeleteSandboxAppIndex(const std::string & bundleName,int32_t appIndex)178 bool BundleSandboxDataMgr::DeleteSandboxAppIndex(const std::string &bundleName, int32_t appIndex)
179 {
180 APP_LOGI("DeleteSandboxAppIndex begin");
181 if (bundleName.empty()) {
182 APP_LOGE("DeleteSandboxAppIndex bundleName is empty");
183 return false;
184 }
185 std::unique_lock<std::mutex> lock(sandboxAppIndexMapMutex_);
186 auto it = sandboxAppIndexMap_.find(bundleName);
187 if (it == sandboxAppIndexMap_.end() || it->second.empty()) {
188 APP_LOGE("no sandbox app can be found %{public}s", bundleName.c_str());
189 return false;
190 }
191
192 auto ret = it->second.erase(appIndex);
193 if (ret == 0) {
194 APP_LOGE("no sandbox app index can be found %{public}d", appIndex);
195 return false;
196 }
197
198 if (it->second.empty()) {
199 sandboxAppIndexMap_.erase(bundleName);
200 }
201 APP_LOGI("DeleteSandboxAppIndex successfully");
202 return true;
203 }
204
GetSandboxAppInfoMap() const205 std::unordered_map<std::string, InnerBundleInfo> BundleSandboxDataMgr::GetSandboxAppInfoMap() const
206 {
207 std::shared_lock<std::shared_mutex> lock(sandboxAppMutex_);
208 return sandboxAppInfos_;
209 }
210
GetSandboxHapModuleInfo(const AbilityInfo & abilityInfo,int32_t appIndex,int32_t userId,HapModuleInfo & hapModuleInfo) const211 ErrCode BundleSandboxDataMgr::GetSandboxHapModuleInfo(const AbilityInfo &abilityInfo, int32_t appIndex, int32_t userId,
212 HapModuleInfo &hapModuleInfo) const
213 {
214 APP_LOGD("GetSandboxHapModuleInfo %{public}s", abilityInfo.bundleName.c_str());
215 // check appIndex
216 if (appIndex <= Constants::INITIAL_SANDBOX_APP_INDEX || appIndex > Constants::MAX_SANDBOX_APP_INDEX) {
217 APP_LOGE("the appIndex %{public}d is invalid", appIndex);
218 return ERR_APPEXECFWK_SANDBOX_QUERY_PARAM_ERROR;
219 }
220 std::shared_lock<std::shared_mutex> lock(sandboxAppMutex_);
221 auto key = std::to_string(appIndex) + Constants::FILE_UNDERLINE + abilityInfo.bundleName;
222 auto infoItem = sandboxAppInfos_.find(key);
223 if (infoItem == sandboxAppInfos_.end()) {
224 APP_LOGE("no sandbox app can be found %{public}s", abilityInfo.bundleName.c_str());
225 return ERR_APPEXECFWK_SANDBOX_QUERY_NO_SANDBOX_APP;
226 }
227
228 const InnerBundleInfo &innerBundleInfo = infoItem->second;
229 int32_t responseUserId = innerBundleInfo.GetResponseUserId(userId);
230 auto module = innerBundleInfo.FindHapModuleInfo(abilityInfo.package, responseUserId);
231 if (!module) {
232 APP_LOGE("can not find module %{public}s", abilityInfo.package.c_str());
233 return ERR_APPEXECFWK_SANDBOX_QUERY_NO_MODULE_INFO;
234 }
235 hapModuleInfo = *module;
236 return ERR_OK;
237 }
238
GetInnerBundleInfoByUid(const int32_t & uid,InnerBundleInfo & innerBundleInfo) const239 ErrCode BundleSandboxDataMgr::GetInnerBundleInfoByUid(const int32_t &uid, InnerBundleInfo &innerBundleInfo) const
240 {
241 APP_LOGD("GetInnerBundleInfoByUid with uid is %{public}d", uid);
242 if (uid < Constants::BASE_APP_UID) {
243 APP_LOGD("the uid(%{public}d) is not an application", uid);
244 return ERR_APPEXECFWK_SANDBOX_QUERY_NO_SANDBOX_APP;
245 }
246 int32_t userId = BundleUtil::GetUserIdByUid(uid);
247 APP_LOGD("GetInnerBundleInfoByUid with userId is %{public}d", userId);
248
249 {
250 std::shared_lock<std::shared_mutex> lock(sandboxAppMutex_);
251 if (!sandboxAppInfos_.empty()) {
252 for (const auto &item : sandboxAppInfos_) {
253 const InnerBundleInfo &info = item.second;
254 auto innerUid = info.GetUid(userId);
255 APP_LOGD("GetInnerBundleInfoByUid with innerUid is %{public}d", innerUid);
256 if (innerUid == uid) {
257 innerBundleInfo = info;
258 return ERR_OK;
259 }
260 }
261 }
262 }
263 return ERR_APPEXECFWK_SANDBOX_QUERY_NO_SANDBOX_APP;
264 }
265
SaveSandboxPersistentInfo(const std::string & bundleName,const InnerBundleInfo & innerBundleInfo)266 bool BundleSandboxDataMgr::SaveSandboxPersistentInfo(const std::string &bundleName,
267 const InnerBundleInfo &innerBundleInfo)
268 {
269 APP_LOGD("SaveSandboxPersistentInfo for bundleName %{public}s", bundleName.c_str());
270 std::unique_lock<std::shared_mutex> lock(sandboxDbMutex_);
271 if (sandboxManagerDb_ == nullptr) {
272 APP_LOGE("error sandboxManagerDb_ is nullptr");
273 return false;
274 }
275 return sandboxManagerDb_->SaveSandboxInnerBundleInfo(bundleName, innerBundleInfo);
276 }
277
RemoveSandboxPersistentInfo(const std::string & bundleName)278 bool BundleSandboxDataMgr::RemoveSandboxPersistentInfo(const std::string &bundleName)
279 {
280 APP_LOGD("RemoveSandboxPersistentInfo for bundleName %{public}s", bundleName.c_str());
281 std::unique_lock<std::shared_mutex> lock(sandboxDbMutex_);
282 if (sandboxManagerDb_ == nullptr) {
283 APP_LOGE("error sandboxManagerDb_ is nullptr");
284 return false;
285 }
286 return sandboxManagerDb_->DeleteSandboxInnerBundleInfo(bundleName);
287 }
288
RestoreSandboxPersistentInnerBundleInfo()289 bool BundleSandboxDataMgr::RestoreSandboxPersistentInnerBundleInfo()
290 {
291 APP_LOGD("start to RestoreSandboxPersistentInnerBundleInfo");
292 std::unique_lock<std::shared_mutex> lockDbMutex(sandboxDbMutex_);
293 if (sandboxManagerDb_ == nullptr) {
294 APP_LOGE("error sandboxManagerDb_ is nullptr");
295 return false;
296 }
297 std::unique_lock<std::shared_mutex> lockAppMutex(sandboxAppMutex_);
298 if (!sandboxManagerDb_->QueryAllSandboxInnerBundleInfo(sandboxAppInfos_)) {
299 APP_LOGE("QueryAllSandboxInnerBundleInfo failed");
300 return false;
301 }
302 for (const auto &sandboxInfo : sandboxAppInfos_) {
303 auto fileUnderlinePos = sandboxInfo.first.find(Constants::FILE_UNDERLINE);
304 if (fileUnderlinePos == std::string::npos) {
305 APP_LOGW("invalid bundleName_appIndex");
306 continue;
307 }
308 std::string appIndexStr = sandboxInfo.first.substr(0, fileUnderlinePos);
309 std::string bundleName = sandboxInfo.first.substr(fileUnderlinePos + 1);
310 int32_t appIndex = 0;
311 if (!OHOS::StrToInt(appIndexStr, appIndex)) {
312 APP_LOGW("invalid appIndex %{public}s", appIndexStr.c_str());
313 continue;
314 }
315 if (!RestoreSandboxAppIndex(bundleName, appIndex)) {
316 APP_LOGW("RestoreSandboxAppIndex appIndex failed");
317 }
318 }
319 return true;
320 }
321
RestoreSandboxAppIndex(const std::string & bundleName,int32_t appIndex)322 bool BundleSandboxDataMgr::RestoreSandboxAppIndex(const std::string &bundleName, int32_t appIndex)
323 {
324 APP_LOGD("RestoreSandboxAppIndex begin");
325 if (bundleName.empty()) {
326 APP_LOGE("RestoreSandboxAppIndex bundleName is empty");
327 return false;
328 }
329 std::unique_lock<std::mutex> lock(sandboxAppIndexMapMutex_);
330 auto firstIterator = sandboxAppIndexMap_.find(bundleName);
331 if (firstIterator == sandboxAppIndexMap_.end()) {
332 std::set<int32_t> innerSet { appIndex };
333 sandboxAppIndexMap_.emplace(bundleName, innerSet);
334 APP_LOGD("RestoreSandboxAppIndex successfully");
335 return true;
336 }
337
338 firstIterator->second.insert(appIndex);
339 APP_LOGD("RestoreSandboxAppIndex finish");
340 return true;
341 }
342
RestoreSandboxUidAndGid(std::map<int32_t,std::string> & bundleIdMap)343 void BundleSandboxDataMgr::RestoreSandboxUidAndGid(std::map<int32_t, std::string> &bundleIdMap)
344 {
345 APP_LOGD("RestoreSandboxUidAndGid begin");
346 std::unique_lock<std::shared_mutex> lock(sandboxAppMutex_);
347 for (const auto &info : sandboxAppInfos_) {
348 for (auto infoItem : info.second.GetInnerBundleUserInfos()) {
349 auto innerBundleUserInfo = infoItem.second;
350 int32_t bundleId = innerBundleUserInfo.uid -
351 innerBundleUserInfo.bundleUserInfo.userId * Constants::BASE_USER_RANGE;
352 auto item = bundleIdMap.find(bundleId);
353 if (item == bundleIdMap.end()) {
354 bundleIdMap.emplace(bundleId, info.first);
355 } else {
356 bundleIdMap[bundleId] = info.first;
357 }
358 BundleUtil::MakeFsConfig(info.first, bundleId, ServiceConstants::HMDFS_CONFIG_PATH);
359 BundleUtil::MakeFsConfig(info.first, bundleId, ServiceConstants::SHAREFS_CONFIG_PATH);
360 }
361 }
362 APP_LOGD("RestoreSandboxUidAndGid finish");
363 }
364 } // AppExecFwk
365 } // OHOS
366