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 "utils/set_flag_utils.h"
17 #include "utils/file_utils.h"
18
19 #include <fcntl.h>
20 #include <filesystem>
21 #include <regex>
22 #include <sys/ioctl.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25
26 #include "storage_service_log.h"
27
28 namespace OHOS {
29 namespace StorageService {
30 const int START_USER_ID = 100;
31 const int MAX_USER_ID = 10736;
32 #define HMFS_MONITOR_FL 0x00000002
33 #define HMFS_IOCTL_HW_GET_FLAGS _IOR(0XF5, 70, unsigned int)
34 #define HMFS_IOCTL_HW_SET_FLAGS _IOR(0XF5, 71, unsigned int)
35 const std::string PATH_EL0 = "/data/service/el0/storage_daemon/sd";
36 const std::string PATH_EL1 = "/data/service/el1/public/storage_daemon/sd";
37
ParseDirAllPath()38 void SetFlagUtils::ParseDirAllPath()
39 {
40 ParseDirPath(PATH_EL0);
41 ParseDirPath(PATH_EL1);
42 }
43
ParseDirPath(const std::string & path)44 void SetFlagUtils::ParseDirPath(const std::string &path)
45 {
46 std::error_code errCode;
47 if (!std::filesystem::exists(path, errCode)) {
48 LOGE("Invalid file path.");
49 return;
50 }
51 if (!StorageDaemon::IsDir(path)) {
52 LOGE("Input path is not a directory.");
53 return;
54 }
55 if (SetDirDelFlags(path) == false) {
56 LOGE("path not exist.");
57 return;
58 }
59 std::regex pathRegex("/temp");
60 if (std::regex_match(path, pathRegex)) {
61 LOGE("Invalid file path.");
62 return;
63 }
64
65 std::regex idRegex("/storage_daemon/sd/(\\d+)/");
66 std::smatch match;
67 if (std::regex_search(path, match, idRegex)) {
68 int userId = std::atoi(match[1].str().c_str());
69 if (userId < START_USER_ID || userId > MAX_USER_ID) {
70 LOGE("Invalid file path, userid:%{public}d", userId);
71 return;
72 }
73 }
74
75 std::filesystem::directory_iterator pathList(path);
76 for (const auto& resPath : pathList) {
77 if (StorageDaemon::IsDir(resPath.path())) {
78 ParseDirPath(resPath.path().c_str());
79 } else if (StorageDaemon::IsFile(resPath.path())) {
80 SetFileDelFlags(resPath.path().c_str());
81 } else {
82 LOGE("Invalid file path.");
83 }
84 }
85 }
86
SetFileDelFlags(const std::string & filepath)87 bool SetFlagUtils::SetFileDelFlags(const std::string &filepath)
88 {
89 LOGI("SetFlagUtils SetFileDelFlags for filepath=%{public}s start.", filepath.c_str());
90 char absPath[PATH_MAX] = {0};
91 if (realpath(filepath.c_str(), absPath) == nullptr) {
92 LOGE("SetFlagUtils Failed to get file realpath");
93 return false;
94 }
95 int32_t fd = open(absPath, O_RDWR);
96 if (fd < 0) {
97 LOGE("SetFlagUtils Failed to open file, errno: %{public}d", errno);
98 return false;
99 }
100 unsigned int flags = 0;
101 int32_t ret = ioctl(fd, HMFS_IOCTL_HW_GET_FLAGS, &flags);
102 if (ret < 0) {
103 LOGE("SetFlagUtils Failed to get file flags, errno: %{public}d", errno);
104 close(fd);
105 return false;
106 }
107 if (flags & HMFS_MONITOR_FL) {
108 LOGE("SetFlagUtils Delete control flag ia already set");
109 close(fd);
110 return true;
111 }
112 flags |= HMFS_MONITOR_FL;
113 ret = ioctl(fd, HMFS_IOCTL_HW_SET_FLAGS, &flags);
114 if (ret < 0) {
115 LOGE("SetFlagUtils Failed to set file flags, errno: %{public}d", errno);
116 }
117 close(fd);
118 return true;
119 }
120
SetDirDelFlags(const std::string & dirpath)121 bool SetFlagUtils::SetDirDelFlags(const std::string &dirpath)
122 {
123 LOGI("SetFlagUtils SetDirDelFlags for dirpath=%{public}s start.", dirpath.c_str());
124 char absPath[PATH_MAX] = {0};
125 if (realpath(dirpath.c_str(), absPath) == nullptr) {
126 LOGE("SetFlagUtils Failed to get realpath");
127 return false;
128 }
129 int32_t fd = open(absPath, O_DIRECTORY);
130 if (fd < 0) {
131 LOGE("SetFlagUtils Failed to open dir, errno: %{public}d", errno);
132 return false;
133 }
134 unsigned int flags = 0;
135 int32_t ret = ioctl(fd, HMFS_IOCTL_HW_GET_FLAGS, &flags);
136 if (ret < 0) {
137 LOGE("SetFlagUtils Failed to get flags, errno: %{public}d", errno);
138 close(fd);
139 return false;
140 }
141 if (flags & HMFS_MONITOR_FL) {
142 LOGE("SetFlagUtils Delete control flag ia already set");
143 close(fd);
144 return true;
145 }
146 flags |= HMFS_MONITOR_FL;
147 ret = ioctl(fd, HMFS_IOCTL_HW_SET_FLAGS, &flags);
148 if (ret < 0) {
149 LOGE("SetFlagUtils Failed to set flags, errno: %{public}d", errno);
150 }
151 close(fd);
152 return true;
153 }
154 }
155 }