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