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 "verify_manager_host_impl.h"
17
18 #include <fcntl.h>
19 #include <unistd.h>
20
21 #include "app_log_wrapper.h"
22 #include "appexecfwk_errors.h"
23 #include "bundle_mgr_service.h"
24 #include "bundle_permission_mgr.h"
25 #include "bundle_util.h"
26 #include "installd_client.h"
27 #include "ipc_skeleton.h"
28 #include "verify_util.h"
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 const std::string SEPARATOR = "/";
34 const std::string ABCS_DIR = "abcs";
35
IsFileNameValid(const std::string & fileName)36 bool IsFileNameValid(const std::string &fileName)
37 {
38 if (fileName.find("..") != std::string::npos
39 || fileName.find("/") != std::string::npos
40 || fileName.find("\\") != std::string::npos
41 || fileName.find("%") != std::string::npos) {
42 return false;
43 }
44 return true;
45 }
46
IsValidPath(const std::string & path)47 bool IsValidPath(const std::string &path)
48 {
49 if (path.empty()) {
50 return false;
51 }
52 if (path.find("..") != std::string::npos) {
53 return false;
54 }
55 return true;
56 }
57 }
VerifyManagerHostImpl()58 VerifyManagerHostImpl::VerifyManagerHostImpl()
59 {
60 APP_LOGI("create VerifyManagerHostImpl.");
61 }
62
~VerifyManagerHostImpl()63 VerifyManagerHostImpl::~VerifyManagerHostImpl()
64 {
65 APP_LOGI("destroy VerifyManagerHostImpl.");
66 }
67
Verify(const std::vector<std::string> & abcPaths,const std::vector<std::string> & abcNames,bool flag)68 ErrCode VerifyManagerHostImpl::Verify(const std::vector<std::string> &abcPaths,
69 const std::vector<std::string> &abcNames, bool flag)
70 {
71 ErrCode ret = InnerVerify(abcPaths, abcNames, flag);
72 RemoveTempFiles(abcPaths);
73 return ret;
74 }
75
InnerVerify(const std::vector<std::string> & abcPaths,const std::vector<std::string> & abcNames,bool flag)76 ErrCode VerifyManagerHostImpl::InnerVerify(const std::vector<std::string> &abcPaths,
77 const std::vector<std::string> &abcNames, bool flag)
78 {
79 if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_RUN_DYN_CODE)) {
80 APP_LOGE("verify install permission failed.");
81 return ERR_BUNDLE_MANAGER_VERIFY_PERMISSION_DENIED;
82 }
83
84 if (!CheckFileParam(abcPaths, abcNames)) {
85 APP_LOGE("CheckFile failed.");
86 return ERR_BUNDLE_MANAGER_VERIFY_PARAM_ERROR;
87 }
88
89 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
90 if (dataMgr == nullptr) {
91 APP_LOGE("verify failed, dataMgr is null");
92 return ERR_BUNDLE_MANAGER_VERIFY_VERIFY_ABC_FAILED;
93 }
94
95 int32_t callingUid = IPCSkeleton::GetCallingUid();
96 InnerBundleInfo innerBundleInfo;
97 if (dataMgr->GetInnerBundleInfoByUid(callingUid, innerBundleInfo) != ERR_OK) {
98 APP_LOGE("verify failed, callingUid is %{public}d", callingUid);
99 return ERR_BUNDLE_MANAGER_VERIFY_VERIFY_ABC_FAILED;
100 }
101
102 std::string rootDir;
103 rootDir.append(Constants::BUNDLE_CODE_DIR).append(Constants::PATH_SEPARATOR)
104 .append(innerBundleInfo.GetBundleName()).append(Constants::PATH_SEPARATOR)
105 .append(ABCS_DIR).append(Constants::PATH_SEPARATOR);
106 if (!MoveAbc(abcPaths, abcNames, rootDir)) {
107 APP_LOGE("move abc failed.");
108 return ERR_BUNDLE_MANAGER_VERIFY_VERIFY_ABC_FAILED;
109 }
110
111 if (!VerifyAbc(rootDir, abcNames)) {
112 APP_LOGE("verify abc failed.");
113 Rollback(rootDir, abcNames);
114 return ERR_BUNDLE_MANAGER_VERIFY_VERIFY_ABC_FAILED;
115 }
116
117 APP_LOGI("verify abc success.");
118 return ERR_OK;
119 }
120
CheckFileParam(const std::vector<std::string> & abcPaths,const std::vector<std::string> & abcNames)121 bool VerifyManagerHostImpl::CheckFileParam(
122 const std::vector<std::string> &abcPaths, const std::vector<std::string> &abcNames)
123 {
124 if (abcPaths.empty() || abcNames.empty()) {
125 APP_LOGE("CheckFile abcPath failed due to abcPaths or abcNames is empty");
126 return false;
127 }
128
129 for (const auto &abcPath : abcPaths) {
130 if (!IsValidPath(abcPath)) {
131 APP_LOGE("CheckFile abcPath(%{public}s) failed due to invalid path", abcPath.c_str());
132 return false;
133 }
134 if (!BundleUtil::CheckFileType(abcPath, Constants::ABC_FILE_SUFFIX)) {
135 APP_LOGE("CheckFile abcPath(%{public}s) failed due to not abc suffix.", abcPath.c_str());
136 return false;
137 }
138 if (!BundleUtil::StartWith(abcPath, Constants::HAP_COPY_PATH)) {
139 APP_LOGE("CheckFile abcPath(%{public}s) failed due to prefix error.", abcPath.c_str());
140 return false;
141 }
142 }
143
144 for (const auto abcName : abcNames) {
145 if (!IsValidPath(abcName)) {
146 APP_LOGE("CheckFile abcName(%{public}s) failed due to invalid path", abcName.c_str());
147 return false;
148 }
149 if (!BundleUtil::CheckFileType(abcName, Constants::ABC_FILE_SUFFIX)) {
150 APP_LOGE("CheckFile abcName(%{public}s) failed due to not abc suffix.", abcName.c_str());
151 return false;
152 }
153 }
154
155 return true;
156 }
157
VerifyAbc(const std::string & rootDir,const std::vector<std::string> & names)158 bool VerifyManagerHostImpl::VerifyAbc(
159 const std::string &rootDir, const std::vector<std::string> &names)
160 {
161 std::vector<std::string> paths;
162 for (const auto &name : names) {
163 paths.emplace_back(rootDir + name);
164 }
165
166 return VerifyAbc(paths);
167 }
168
VerifyAbc(const std::vector<std::string> & abcPaths)169 bool VerifyManagerHostImpl::VerifyAbc(const std::vector<std::string> &abcPaths)
170 {
171 for (const auto &abcPath : abcPaths) {
172 if (!BundleUtil::IsExistFile(abcPath)) {
173 APP_LOGE("abcPath is not exist: %{public}s.", abcPath.c_str());
174 return false;
175 }
176
177 if (!VerifyUtil::VerifyAbc(abcPath)) {
178 APP_LOGE("verify abc failed.");
179 return false;
180 }
181 }
182
183 return true;
184 }
185
RemoveTempFiles(const std::vector<std::string> & paths)186 void VerifyManagerHostImpl::RemoveTempFiles(const std::vector<std::string> &paths)
187 {
188 APP_LOGI("RemoveTempFiles.");
189 for (const auto &path : paths) {
190 if (!BundleUtil::DeleteDir(path)) {
191 APP_LOGW("RemoveFile %{private}s failed.", path.c_str());
192 }
193 }
194 }
195
GetFileName(const std::string & sourcePath,std::string & fileName)196 bool VerifyManagerHostImpl::GetFileName(const std::string &sourcePath, std::string &fileName)
197 {
198 size_t pos = sourcePath.find_last_of(SEPARATOR);
199 if (pos == std::string::npos) {
200 APP_LOGE("invalid sourcePath.");
201 return false;
202 }
203
204 fileName = sourcePath.substr(pos + 1);
205 return !fileName.empty();
206 }
207
GetFileDir(const std::string & sourcePath,std::string & fileDir)208 bool VerifyManagerHostImpl::GetFileDir(const std::string &sourcePath, std::string &fileDir)
209 {
210 size_t pos = sourcePath.find_last_of(SEPARATOR);
211 if (pos == std::string::npos) {
212 APP_LOGE("invalid sourcePath.");
213 return false;
214 }
215
216 fileDir = sourcePath.substr(0, pos);
217 return !fileDir.empty();
218 }
219
MkdirIfNotExist(const std::string & dir)220 ErrCode VerifyManagerHostImpl::MkdirIfNotExist(const std::string &dir)
221 {
222 bool isDirExist = false;
223 ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
224 if (result != ERR_OK) {
225 APP_LOGE("Check if dir exist failed %{public}d", result);
226 return result;
227 }
228
229 if (!isDirExist) {
230 result = InstalldClient::GetInstance()->CreateBundleDir(dir);
231 if (result != ERR_OK) {
232 APP_LOGE("Create dir failed %{public}d", result);
233 return result;
234 }
235 }
236 return result;
237 }
238
MoveAbc(const std::vector<std::string> & abcPaths,const std::vector<std::string> & abcNames,const std::string & rootDir)239 bool VerifyManagerHostImpl::MoveAbc(const std::vector<std::string> &abcPaths,
240 const std::vector<std::string> &abcNames, const std::string &rootDir)
241 {
242 if (abcPaths.size() != abcNames.size()) {
243 APP_LOGE("The number %{public}zu of abcPaths is different from that of abcNames",
244 abcPaths.size());
245 return false;
246 }
247
248 std::vector<std::string> hasMovePaths;
249 ErrCode result = ERR_OK;
250 for (size_t i = 0; i < abcPaths.size(); ++i) {
251 std::string targetPath = rootDir + abcNames[i];
252 std::string fileDir;
253 if (!GetFileDir(targetPath, fileDir)) {
254 APP_LOGE("GetFileDir failed %{public}s", targetPath.c_str());
255 Rollback(hasMovePaths);
256 return false;
257 }
258
259 result = MkdirIfNotExist(fileDir);
260 if (result != ERR_OK) {
261 APP_LOGE("mkdir fileDir %{public}s faild %{public}d", fileDir.c_str(), result);
262 Rollback(hasMovePaths);
263 return false;
264 }
265
266 result = InstalldClient::GetInstance()->MoveFile(abcPaths[i], targetPath);
267 if (result != ERR_OK) {
268 APP_LOGE("move file to real path failed %{public}d", result);
269 Rollback(hasMovePaths);
270 return false;
271 }
272
273 hasMovePaths.emplace_back(targetPath);
274 }
275
276 return true;
277 }
278
Rollback(const std::string & rootDir,const std::vector<std::string> & names)279 void VerifyManagerHostImpl::Rollback(
280 const std::string &rootDir, const std::vector<std::string> &names)
281 {
282 std::vector<std::string> paths;
283 for (const auto &name : names) {
284 paths.emplace_back(rootDir + name);
285 }
286
287 Rollback(paths);
288 }
289
Rollback(const std::vector<std::string> & paths)290 void VerifyManagerHostImpl::Rollback(const std::vector<std::string> &paths)
291 {
292 for (const auto &abcPath : paths) {
293 std::string targetPath;
294 auto result = InstalldClient::GetInstance()->MoveFile(abcPath, targetPath);
295 if (result != ERR_OK) {
296 APP_LOGE("move file to real path failed %{public}d", result);
297 }
298 }
299 }
300
CreateFd(const std::string & fileName,int32_t & fd,std::string & path)301 ErrCode VerifyManagerHostImpl::CreateFd(const std::string &fileName, int32_t &fd, std::string &path)
302 {
303 if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_RUN_DYN_CODE)) {
304 APP_LOGE("verify install permission failed.");
305 return ERR_BUNDLE_MANAGER_VERIFY_PERMISSION_DENIED;
306 }
307
308 if (!BundleUtil::CheckFileType(fileName, Constants::ABC_FILE_SUFFIX)) {
309 APP_LOGE("not abc file.");
310 return ERR_BUNDLE_MANAGER_VERIFY_PARAM_ERROR;
311 }
312
313 if (!IsFileNameValid(fileName)) {
314 APP_LOGE("invalid fileName");
315 return ERR_BUNDLE_MANAGER_VERIFY_PARAM_ERROR;
316 }
317
318 std::string tmpDir = BundleUtil::CreateInstallTempDir(++id_, DirType::ABC_FILE_DIR);
319 if (tmpDir.empty()) {
320 APP_LOGE("create tmp dir failed.");
321 return ERR_BUNDLE_MANAGER_VERIFY_CREATE_TARGET_DIR_FAILED;
322 }
323
324 path = tmpDir + fileName;
325 if ((fd = BundleUtil::CreateFileDescriptor(path, 0)) < 0) {
326 APP_LOGE("create file descriptor failed.");
327 BundleUtil::DeleteDir(tmpDir);
328 return ERR_BUNDLE_MANAGER_VERIFY_CREATE_FD_FAILED;
329 }
330 return ERR_OK;
331 }
332
DeleteAbc(const std::string & path)333 ErrCode VerifyManagerHostImpl::DeleteAbc(const std::string &path)
334 {
335 if (!BundlePermissionMgr::VerifyCallingPermissionForAll(Constants::PERMISSION_RUN_DYN_CODE)) {
336 APP_LOGE("DeleteAbc failed due to permission denied.");
337 return ERR_BUNDLE_MANAGER_VERIFY_PERMISSION_DENIED;
338 }
339 if (!IsValidPath(path)) {
340 APP_LOGE("DeleteAbc failed due to invalid path");
341 return ERR_BUNDLE_MANAGER_DELETE_ABC_PARAM_ERROR;
342 }
343 if (!BundleUtil::CheckFileType(path, Constants::ABC_FILE_SUFFIX)) {
344 APP_LOGE("DeleteAbc failed due to not abc file.");
345 return ERR_BUNDLE_MANAGER_DELETE_ABC_PARAM_ERROR;
346 }
347 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
348 if (dataMgr == nullptr) {
349 APP_LOGE("DeleteAbc failed due to dataMgr is null");
350 return ERR_BUNDLE_MANAGER_DELETE_ABC_FAILED;
351 }
352 int32_t callingUid = IPCSkeleton::GetCallingUid();
353 InnerBundleInfo innerBundleInfo;
354 if (dataMgr->GetInnerBundleInfoByUid(callingUid, innerBundleInfo) != ERR_OK) {
355 APP_LOGE("DeleteAbc failed due to get callingUid failed");
356 return ERR_BUNDLE_MANAGER_DELETE_ABC_FAILED;
357 }
358 std::string realPath;
359 realPath.append(Constants::BUNDLE_CODE_DIR).append(Constants::PATH_SEPARATOR)
360 .append(innerBundleInfo.GetBundleName()).append(Constants::PATH_SEPARATOR)
361 .append(ABCS_DIR).append(Constants::PATH_SEPARATOR).append(path);
362 bool isExist = false;
363 auto result = InstalldClient::GetInstance()->IsExistFile(realPath, isExist);
364 if (result != ERR_OK) {
365 APP_LOGE("DeleteAbc %{public}s failed due to call IsExistFile failed %{public}d",
366 realPath.c_str(), result);
367 return ERR_BUNDLE_MANAGER_DELETE_ABC_FAILED;
368 }
369 if (!isExist) {
370 APP_LOGE("DeleteAbc failed due to path %{public}s is not exist", realPath.c_str());
371 return ERR_BUNDLE_MANAGER_DELETE_ABC_FAILED;
372 }
373 result = InstalldClient::GetInstance()->RemoveDir(realPath);
374 if (result != ERR_OK) {
375 APP_LOGE("DeleteAbc failed due to remove path %{public}s failed %{public}d",
376 realPath.c_str(), result);
377 return ERR_BUNDLE_MANAGER_DELETE_ABC_FAILED;
378 }
379 return ERR_OK;
380 }
381 } // AppExecFwk
382 } // namespace OHOS
383