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
16 #include "user_unlocked_event_subscriber.h"
17
18 #include <sys/stat.h>
19 #include <thread>
20
21 #include "app_control_manager.h"
22 #include "app_log_wrapper.h"
23 #include "bundle_mgr_service.h"
24 #include "common_event_manager.h"
25 #include "common_event_support.h"
26 #if defined (BUNDLE_FRAMEWORK_SANDBOX_APP) && defined (DLP_PERMISSION_ENABLE)
27 #include "dlp_permission_kit.h"
28 #endif
29 #include "installd_client.h"
30
31 namespace OHOS {
32 namespace AppExecFwk {
33 namespace {
34 static constexpr int32_t MODE_BASE = 07777;
35 }
UserUnlockedEventSubscriber(const EventFwk::CommonEventSubscribeInfo & subscribeInfo)36 UserUnlockedEventSubscriber::UserUnlockedEventSubscriber(
37 const EventFwk::CommonEventSubscribeInfo &subscribeInfo) : EventFwk::CommonEventSubscriber(subscribeInfo)
38 {}
39
~UserUnlockedEventSubscriber()40 UserUnlockedEventSubscriber::~UserUnlockedEventSubscriber()
41 {}
42
OnReceiveEvent(const EventFwk::CommonEventData & data)43 void UserUnlockedEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
44 {
45 std::string action = data.GetWant().GetAction();
46 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED) {
47 int32_t userId = data.GetCode();
48 APP_LOGI("UserUnlockedEventSubscriber userId %{public}d is unlocked", userId);
49 std::thread updateDataDirThread(UpdateAppDataMgr::UpdateAppDataDirSelinuxLabel, userId);
50 updateDataDirThread.detach();
51 #ifdef BUNDLE_FRAMEWORK_APP_CONTROL
52 DelayedSingleton<AppControlManager>::GetInstance()->SetAppInstallControlStatus();
53 #endif
54 }
55 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
56 #if defined (BUNDLE_FRAMEWORK_SANDBOX_APP) && defined (DLP_PERMISSION_ENABLE)
57 APP_LOGI("RemoveUnreservedSandbox call ClearUnreservedSandbox");
58 Security::DlpPermission::DlpPermissionKit::ClearUnreservedSandbox();
59 #endif
60 #ifdef BUNDLE_FRAMEWORK_APP_CONTROL
61 DelayedSingleton<AppControlManager>::GetInstance()->SetAppInstallControlStatus();
62 #endif
63 }
64 }
65
CreateBundleDataDir(const BundleInfo & bundleInfo,int32_t userId,const std::string & elDir)66 bool UpdateAppDataMgr::CreateBundleDataDir(
67 const BundleInfo &bundleInfo, int32_t userId, const std::string &elDir)
68 {
69 std::string baseBundleDataDir = Constants::BUNDLE_APP_DATA_BASE_DIR + elDir +
70 Constants::PATH_SEPARATOR + std::to_string(userId) + Constants::DATABASE + bundleInfo.name;
71 bool isExist = false;
72 if (InstalldClient::GetInstance()->IsExistDir(baseBundleDataDir, isExist) != ERR_OK) {
73 APP_LOGE("path: %{public}s IsExistDir failed", baseBundleDataDir.c_str());
74 return false;
75 }
76 if (isExist) {
77 FileStat fileStat;
78 if (InstalldClient::GetInstance()->GetFileStat(baseBundleDataDir, fileStat) != ERR_OK) {
79 APP_LOGE("GetFileStat path(%{public}s) failed", baseBundleDataDir.c_str());
80 return false;
81 }
82 if ((fileStat.uid != bundleInfo.uid) || (fileStat.gid != Constants::DATABASE_DIR_GID) ||
83 ((fileStat.mode & MODE_BASE) != (S_IRWXU | S_IRWXG | S_ISGID))) {
84 APP_LOGW("path: %{public}s uid or gid or mode not same", baseBundleDataDir.c_str());
85 isExist = false;
86 }
87 }
88 if (!isExist) {
89 APP_LOGI("path: %{public}s is not exist, need to create it", baseBundleDataDir.c_str());
90 CreateDirParam createDirParam;
91 createDirParam.userId = userId;
92 createDirParam.bundleName = bundleInfo.name;
93 createDirParam.uid = bundleInfo.uid;
94 createDirParam.gid = bundleInfo.gid;
95 createDirParam.apl = bundleInfo.applicationInfo.appPrivilegeLevel;
96 createDirParam.isPreInstallApp = bundleInfo.isPreInstallApp;
97 createDirParam.debug = bundleInfo.applicationInfo.debug;
98 createDirParam.createDirFlag = CreateDirFlag::CREATE_DIR_UNLOCKED;
99 if (InstalldClient::GetInstance()->CreateBundleDataDir(createDirParam) != ERR_OK) {
100 APP_LOGE("failed to CreateBundleDataDir");
101 return false;
102 }
103 }
104 return true;
105 }
106
UpdateAppDataDirSelinuxLabel(int32_t userId)107 void UpdateAppDataMgr::UpdateAppDataDirSelinuxLabel(int32_t userId)
108 {
109 APP_LOGI("UpdateAppDataDirSelinuxLabel userId:%{public}d start", userId);
110 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
111 if (dataMgr == nullptr) {
112 APP_LOGE("UpdateAppDataDirSelinuxLabel DataMgr is nullptr");
113 return;
114 }
115 std::vector<BundleInfo> bundleInfos;
116 if (!dataMgr->GetBundleInfos(BundleFlag::GET_BUNDLE_DEFAULT, bundleInfos, userId)) {
117 APP_LOGE("UpdateAppDataDirSelinuxLabel GetAllBundleInfos failed");
118 return;
119 }
120
121 ProcessUpdateAppDataDir(userId, bundleInfos, Constants::BUNDLE_EL[1]);
122 #ifdef CHECK_ELDIR_ENABLED
123 ProcessUpdateAppDataDir(userId, bundleInfos, Constants::DIR_EL3);
124 ProcessUpdateAppDataDir(userId, bundleInfos, Constants::DIR_EL4);
125 #endif
126 ProcessUpdateAppLogDir(bundleInfos, userId);
127 ProcessFileManagerDir(bundleInfos, userId);
128 APP_LOGI("UpdateAppDataDirSelinuxLabel userId:%{public}d end", userId);
129 }
130
ProcessUpdateAppDataDir(int32_t userId,const std::vector<BundleInfo> & bundleInfos,const std::string & elDir)131 void UpdateAppDataMgr::ProcessUpdateAppDataDir(
132 int32_t userId, const std::vector<BundleInfo> &bundleInfos, const std::string &elDir)
133 {
134 std::string baseBundleDataDir = Constants::BUNDLE_APP_DATA_BASE_DIR + elDir +
135 Constants::PATH_SEPARATOR + std::to_string(userId);
136 for (const auto &bundleInfo : bundleInfos) {
137 if ((userId != Constants::DEFAULT_USERID && bundleInfo.singleton) ||
138 !CreateBundleDataDir(bundleInfo, userId, elDir)) {
139 continue;
140 }
141 std::string baseDir = baseBundleDataDir + Constants::BASE + bundleInfo.name;
142 if (InstalldClient::GetInstance()->SetDirApl(baseDir, bundleInfo.name,
143 bundleInfo.applicationInfo.appPrivilegeLevel, bundleInfo.isPreInstallApp,
144 bundleInfo.applicationInfo.debug) != ERR_OK) {
145 APP_LOGW("failed to SetDirApl baseDir dir");
146 continue;
147 }
148 std::string baseDataDir = baseBundleDataDir + Constants::DATABASE + bundleInfo.name;
149 if (InstalldClient::GetInstance()->SetDirApl(baseDataDir, bundleInfo.name,
150 bundleInfo.applicationInfo.appPrivilegeLevel, bundleInfo.isPreInstallApp,
151 bundleInfo.applicationInfo.debug) != ERR_OK) {
152 APP_LOGW("failed to SetDirApl baseDataDir dir");
153 }
154 }
155 }
156
ProcessUpdateAppLogDir(const std::vector<BundleInfo> & bundleInfos,int32_t userId)157 void UpdateAppDataMgr::ProcessUpdateAppLogDir(const std::vector<BundleInfo> &bundleInfos, int32_t userId)
158 {
159 for (const auto &bundleInfo : bundleInfos) {
160 if (userId != Constants::DEFAULT_USERID && bundleInfo.singleton) {
161 continue;
162 }
163 if (!CreateBundleLogDir(bundleInfo, userId)) {
164 APP_LOGD("log dir create failed or already exists");
165 }
166 }
167 }
168
CreateBundleLogDir(const BundleInfo & bundleInfo,int32_t userId)169 bool UpdateAppDataMgr::CreateBundleLogDir(const BundleInfo &bundleInfo, int32_t userId)
170 {
171 std::string bundleLogDir = Constants::BUNDLE_APP_DATA_BASE_DIR + Constants::BUNDLE_EL[1] +
172 Constants::PATH_SEPARATOR + std::to_string(userId) + Constants::LOG + bundleInfo.name;
173 bool isExist = false;
174 if (InstalldClient::GetInstance()->IsExistDir(bundleLogDir, isExist) != ERR_OK) {
175 APP_LOGE("path: %{public}s IsExistDir failed", bundleLogDir.c_str());
176 return false;
177 }
178 if (isExist) {
179 APP_LOGD("path: %{public}s is exist", bundleLogDir.c_str());
180 return false;
181 }
182 if (InstalldClient::GetInstance()->Mkdir(
183 bundleLogDir, S_IRWXU | S_IRWXG, bundleInfo.uid, Constants::LOG_DIR_GID) != ERR_OK) {
184 APP_LOGE("CreateBundleLogDir failed");
185 return false;
186 }
187 return true;
188 }
189
ProcessFileManagerDir(const std::vector<BundleInfo> & bundleInfos,int32_t userId)190 void UpdateAppDataMgr::ProcessFileManagerDir(const std::vector<BundleInfo> &bundleInfos, int32_t userId)
191 {
192 for (const auto &bundleInfo : bundleInfos) {
193 if (userId != Constants::DEFAULT_USERID && bundleInfo.singleton) {
194 continue;
195 }
196 if (!CreateBundleCloudDir(bundleInfo, userId)) {
197 APP_LOGW("ProcessFileManageDir failed");
198 }
199 }
200 }
201
CreateBundleCloudDir(const BundleInfo & bundleInfo,int32_t userId)202 bool UpdateAppDataMgr::CreateBundleCloudDir(const BundleInfo &bundleInfo, int32_t userId)
203 {
204 const std::string CLOUD_FILE_PATH = "/data/service/el2/%/hmdfs/cloud/data/";
205 std::string bundleCloudDir = CLOUD_FILE_PATH + bundleInfo.name;
206 bundleCloudDir = bundleCloudDir.replace(bundleCloudDir.find("%"), 1, std::to_string(userId));
207 bool isExist = false;
208 if (InstalldClient::GetInstance()->IsExistDir(bundleCloudDir, isExist) != ERR_OK) {
209 APP_LOGE("path: %{private}s IsExistDir failed", bundleCloudDir.c_str());
210 return false;
211 }
212 if (isExist) {
213 APP_LOGD("path: %{private}s is exist", bundleCloudDir.c_str());
214 return false;
215 }
216 if (!InstalldClient::GetInstance()->Mkdir(bundleCloudDir, S_IRWXU | S_IRWXG | S_ISGID,
217 bundleInfo.uid, Constants::DFS_GID)) {
218 static std::once_flag cloudOnce;
219 std::call_once(cloudOnce, [bundleInfo]() {
220 APP_LOGW("CreateCloudDir failed for bundle %{private}s errno:%{public}d",
221 bundleInfo.name.c_str(), errno);
222 });
223 }
224 return true;
225 }
226 } // namespace AppExecFwk
227 } // namespace OHOS