1 /*
2 * Copyright (c) 2025 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 "backupsagetincrementallocalcapabilities_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <cstring>
21 #include <climits>
22 #include <fuzzer/FuzzedDataProvider.h>
23 #include <vector>
24
25 #include "directory_ex.h"
26 #include "message_parcel.h"
27 #include "module_external/storage_manager_service.h"
28 #include "sandbox_helper.h"
29 #include "service.h"
30 #include "service_proxy.h"
31 #include "service_reverse.h"
32 #include "service_stub.h"
33 #include "securec.h"
34 #include "system_ability.h"
35
36 using namespace std;
37 using namespace OHOS::FileManagement::Backup;
38
39 template <class T>
TypeCast(const uint8_t * data,int * pos=nullptr)40 T TypeCast(const uint8_t *data, int *pos = nullptr)
41 {
42 if (pos) {
43 *pos += sizeof(T);
44 }
45 return *(reinterpret_cast<const T *>(data));
46 }
47
48 namespace OHOS {
49 constexpr int32_t SERVICE_ID = 5203;
50 constexpr int32_t NEED_CREATE_THREE_STRING_NUM = 3;
51
GetBundleNamesData(const uint8_t * data,size_t size,vector<BIncrementalData> & bundleNames)52 void GetBundleNamesData(const uint8_t *data, size_t size, vector<BIncrementalData> &bundleNames)
53 {
54 int minLen = sizeof(int64_t) + sizeof(int) + sizeof(int32_t);
55 if (size < minLen + 1) {
56 return;
57 }
58 FuzzedDataProvider fdp(data, size);
59 uint8_t loop = fdp.ConsumeIntegral<uint8_t>();
60 size--;
61 if (loop == 0 || (minLen * loop) > size) {
62 return;
63 }
64 int blob = (size / loop);
65 int len = (blob - minLen) >> 1;
66 for (size_t i = 0, pos = 1; i < loop; i++, pos += blob) {
67 int64_t nTime = fdp.ConsumeIntegral<int64_t>();
68 int fd = fdp.ConsumeIntegral<int>();
69 int32_t priority = fdp.ConsumeIntegral<int32_t>();
70 string name(reinterpret_cast<const char*>(data + pos + minLen), len);
71 string parameters(reinterpret_cast<const char*>(data + pos + len + minLen), len);
72 BIncrementalData incrementaData(name, nTime, fd, parameters, priority);
73 bundleNames.push_back(incrementaData);
74 }
75 }
76
77 template <typename T>
WriteParcelableVector(const std::vector<T> & parcelableVector,Parcel & data)78 void WriteParcelableVector(const std::vector<T> &parcelableVector, Parcel &data)
79 {
80 if (!data.WriteUint32(parcelableVector.size())) {
81 return;
82 }
83
84 for (const auto &parcelable : parcelableVector) {
85 if (!data.WriteParcelable(&parcelable)) {
86 return;
87 }
88 }
89
90 return;
91 }
92
CmdGetLocalCapabilitiesIncrementalFuzzTest(const uint8_t * data,size_t size)93 bool CmdGetLocalCapabilitiesIncrementalFuzzTest(const uint8_t *data, size_t size)
94 {
95 MessageParcel datas;
96 datas.WriteInterfaceToken(ServiceStub::GetDescriptor());
97 if (size >= sizeof(int32_t)) {
98 vector<BIncrementalData> bundleNames;
99 GetBundleNamesData(data, size, bundleNames);
100 WriteParcelableVector(bundleNames, datas);
101 }
102
103 datas.RewindRead(0);
104 MessageParcel reply;
105 MessageOption option;
106
107 sptr service(new Service(SERVICE_ID));
108 uint32_t code = static_cast<uint32_t>(IServiceIpcCode::COMMAND_GET_LOCAL_CAPABILITIES_INCREMENTAL);
109 service->OnRemoteRequest(code, datas, reply, option);
110 return true;
111 }
112
GetStorageRecognizeSandboxPathEl1FuzzTest(const uint8_t * data,size_t size)113 bool GetStorageRecognizeSandboxPathEl1FuzzTest(const uint8_t *data, size_t size)
114 {
115 uint32_t userId = 100;
116 int len = size >> 1;
117 string bundleName(reinterpret_cast<const char*>(data), len);
118 string sandBoxSubpath(reinterpret_cast<const char*>(data + len), len);
119 string fullPath = BASE_EL1 + DEFAULT_PATH_WITH_WILDCARD + sandBoxSubpath;
120 std::vector<std::string> phyIncludes;
121 std::map<std::string, std::string> pathMap;
122 StorageManagerService::GetInstance().RecognizeSandboxWildCard(userId, bundleName, fullPath, phyIncludes, pathMap);
123 return true;
124 }
125
CmdExcludeFilter(const uint8_t * data,size_t size)126 bool CmdExcludeFilter(const uint8_t *data, size_t size)
127 {
128 int len = size / NEED_CREATE_THREE_STRING_NUM;
129 string dirPath(reinterpret_cast<const char*>(data), len);
130 string pathVal1(reinterpret_cast<const char*>(data + len), len);
131 string pathVal2(reinterpret_cast<const char*>(data + len * 2), len);
132 std::map<std::string, bool> excludesMap;
133 excludesMap.insert(std::make_pair(pathVal1, true));
134 excludesMap.insert(std::make_pair(pathVal2, false));
135 StorageManagerService::GetInstance().ExcludeFilter(excludesMap, dirPath);
136 return true;
137 }
138
GetStorageRecognizeSandboxPathEl2FuzzTest(const uint8_t * data,size_t size)139 bool GetStorageRecognizeSandboxPathEl2FuzzTest(const uint8_t *data, size_t size)
140 {
141 uint32_t userId = 100;
142 int len = size >> 1;
143 string bundleName(reinterpret_cast<const char*>(data), len);
144 string sandBoxSubpath(reinterpret_cast<const char*>(data + len), len);
145 string fullPath = BASE_EL2 + DEFAULT_PATH_WITH_WILDCARD + sandBoxSubpath;
146 std::vector<std::string> phyIncludes;
147 std::map<std::string, std::string> pathMap;
148 StorageManagerService::GetInstance().RecognizeSandboxWildCard(userId, bundleName, fullPath, phyIncludes, pathMap);
149 return true;
150 }
151
CmdGetMediaType(const uint8_t * data,size_t size)152 bool CmdGetMediaType(const uint8_t *data, size_t size)
153 {
154 (void)data;
155 std::shared_ptr<DataShare::DataShareResultSet> resultSet = std::make_shared<DataShare::DataShareResultSet>();
156 StorageManager::StorageStats storageStats = {};
157 StorageManagerService::GetInstance().GetMediaTypeAndSize(resultSet, storageStats);
158 return true;
159 }
160
CmdGetFileStorageStats(const uint8_t * data,size_t size)161 bool CmdGetFileStorageStats(const uint8_t *data, size_t size)
162 {
163 (void)data;
164 int32_t userId = 100;
165 StorageManager::StorageStats storageStats = {};
166 StorageManagerService::GetInstance().GetFileStorageStats(userId, storageStats);
167 return true;
168 }
169
170
CmdInitQuotaMounts(const uint8_t * data,size_t size)171 bool CmdInitQuotaMounts(const uint8_t *data, size_t size)
172 {
173 (void)data;
174 StorageManagerService::GetInstance().InitialiseQuotaMounts();
175 return true;
176 }
CmdExcludePathMap(const uint8_t * data,size_t size)177 bool CmdExcludePathMap(const uint8_t *data, size_t size)
178 {
179 string excludePath(reinterpret_cast<const char*>(data), size);
180 std::map<std::string, bool> excludesMap;
181 StorageManagerService::GetInstance().SetExcludePathMap(excludePath, excludesMap);
182 return true;
183 }
184
CmdConvertSandbxRealPath(const uint8_t * data,size_t size)185 bool CmdConvertSandbxRealPath(const uint8_t *data, size_t size)
186 {
187 uint32_t userId = 100;
188 int len = size >> 1;
189 string bundleName(reinterpret_cast<const char*>(data), len);
190 string sandBoxSubpath(reinterpret_cast<const char*>(data + len), len);
191 string fullSandBoxPath = NORMAL_SAND_PREFIX + sandBoxSubpath;
192 std::vector<std::string> realPaths;
193 std::map<std::string, std::string> pathMap;
194 StorageManagerService::GetInstance().ConvertSandboxRealPath(userId, bundleName, fullSandBoxPath,
195 realPaths, pathMap);
196
197 string fullSandBoxFilePath = FILE_SAND_PREFIX + sandBoxSubpath;
198 StorageManagerService::GetInstance().ConvertSandboxRealPath(userId, bundleName, fullSandBoxFilePath,
199 realPaths, pathMap);
200
201 string fullSandBoxMediaPath = MEDIA_SAND_PREFIX + sandBoxSubpath;
202 StorageManagerService::GetInstance().ConvertSandboxRealPath(userId, bundleName, fullSandBoxMediaPath,
203 realPaths, pathMap);
204
205 string fullSandBoxMediaCloudPath = MEDIA_CLOUD_SAND_PREFIX + sandBoxSubpath;
206 StorageManagerService::GetInstance().ConvertSandboxRealPath(userId, bundleName, fullSandBoxMediaCloudPath,
207 realPaths, pathMap);
208 return true;
209 }
210
CmdAddQuterDirInfoFileStateFuzzTest(const uint8_t * data,size_t size)211 bool CmdAddQuterDirInfoFileStateFuzzTest(const uint8_t *data, size_t size)
212 {
213 if (data == nullptr || size < sizeof(int64_t)) {
214 return false;
215 }
216 int64_t lastBackupTime = *(reinterpret_cast<const int64_t*>(data));
217 int len = (size - sizeof(int64_t)) / NEED_CREATE_THREE_STRING_NUM;
218 string dir(reinterpret_cast<const char*>(data), len);
219 string bundleName(reinterpret_cast<const char*>(data + len), len);
220 BundleStatsParas bundleStatsParas = {100, bundleName, lastBackupTime, 0, 0};
221 string sanboxDir(reinterpret_cast<const char*>(data + len * 2), len);
222 std::ofstream statFile;
223 std::map<std::string, bool> excludesMap;
224 StorageManagerService::GetInstance().AddOuterDirIntoFileStat(dir, bundleStatsParas, sanboxDir,
225 statFile, excludesMap);
226 return true;
227 }
228
CmdPhysicalToSanboxPath(const uint8_t * data,size_t size)229 bool CmdPhysicalToSanboxPath(const uint8_t *data, size_t size)
230 {
231 int len = size / NEED_CREATE_THREE_STRING_NUM;
232 string dir(reinterpret_cast<const char*>(data), len);
233 string sandBodDir(reinterpret_cast<const char*>(data + len), len);
234 string path(reinterpret_cast<const char*>(data + len * 2), len);
235 StorageManagerService::GetInstance().PhysicalToSandboxPath(dir, sandBodDir, path);
236 return true;
237 }
238
CmdAddPathMapForPathWildCard(const uint8_t * data,size_t size)239 bool CmdAddPathMapForPathWildCard(const uint8_t *data, size_t size)
240 {
241 uint32_t userId = 100;
242 int len = size >> 1;
243 string bundleName(reinterpret_cast<const char*>(data), len);
244 string phyPath(reinterpret_cast<const char*>(data + len), len);
245 std::map<std::string, std::string> pathMap;
246 StorageManagerService::GetInstance().AddPathMapForPathWildCard(userId, bundleName, phyPath, pathMap);
247 return true;
248 }
249
CheckIfDirForIncludesFuzzTest(const uint8_t * data,size_t size)250 bool CheckIfDirForIncludesFuzzTest(const uint8_t *data, size_t size)
251 {
252 if (data == nullptr || size < sizeof(int64_t) * NEED_CREATE_THREE_STRING_NUM) {
253 return false;
254 }
255 int pos = 0;
256 string bundleName = "com.example.test";
257 BundleStatsParas paras = {
258 .userId = 100,
259 .lastBackupTime = TypeCast<int64_t>(data, &pos),
260 .fileSizeSum = TypeCast<int64_t>(data + pos, &pos),
261 .incFileSizeSum = TypeCast<int64_t>(data + pos, &pos),
262 .bundleName = bundleName
263 };
264
265 string path(reinterpret_cast<const char *>(data + pos), size - pos);
266 map<string, string> pathMap;
267 map<string, bool> execludePathMap;
268 string dir = BACKUP_PATH_PREFIX + std::to_string(paras.userId) + BACKUP_PATH_SURFFIX + bundleName +
269 FILE_SEPARATOR_CHAR;
270 string filePath = dir + BACKUP_STAT_SYMBOL + std::to_string(0);
271 ofstream statFile;
272 ForceCreateDirectory(dir);
273 statFile.open(filePath, std::ios::out | std::ios::trunc);
274 if (!statFile.is_open()) {
275 return false;
276 }
277 statFile << VER_10_LINE1 << std::endl;
278 statFile << VER_10_LINE2 << std::endl;
279 StorageManagerService::GetInstance().CheckIfDirForIncludes(path, paras, pathMap, statFile, execludePathMap);
280 StorageManagerService::GetInstance().GetIncludesFileStats(path, paras, pathMap, statFile, execludePathMap);
281 FileStat fileStat;
282 fileStat.filePath = path;
283 StorageManagerService::GetInstance().WriteFileList(statFile, fileStat, paras);
284 StorageManagerService::GetInstance().AddOuterDirIntoFileStat("/data/test", paras, "/data/test", statFile,
285 execludePathMap);
286 StorageManagerService::GetInstance().InsertStatFile(path, fileStat, statFile, execludePathMap, paras);
287 return true;
288 }
289
GetPathWildCardFuzzTest(const uint8_t * data,size_t size)290 bool GetPathWildCardFuzzTest(const uint8_t *data, size_t size)
291 {
292 uint32_t userId = 100;
293 string bundleName(reinterpret_cast<const char*>(data), size);
294 string includeWildCard = "/data/test/" + WILDCARD_DEFAULT_INCLUDE;
295 std::vector<string> includePathList;
296 std::map<std::string, std::string> pathMap;
297 StorageManagerService::GetInstance().GetPathWildCard(userId, bundleName, includeWildCard, includePathList, pathMap);
298 return true;
299 }
300
CmdCheckOverLongPath(const uint8_t * data,size_t size)301 bool CmdCheckOverLongPath(const uint8_t *data, size_t size)
302 {
303 string filePath(reinterpret_cast<const char*>(data), size);
304 StorageManagerService::GetInstance().CheckOverLongPath(filePath);
305 return true;
306 }
307 } // namespace OHOS
308
309 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)310 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
311 {
312 try {
313 OHOS::CmdGetLocalCapabilitiesIncrementalFuzzTest(data, size);
314 OHOS::GetStorageRecognizeSandboxPathEl1FuzzTest(data, size);
315 OHOS::GetStorageRecognizeSandboxPathEl2FuzzTest(data, size);
316 OHOS::CmdExcludeFilter(data, size);
317 OHOS::CmdGetMediaType(data, size);
318 OHOS::CmdGetFileStorageStats(data, size);
319 OHOS::CmdInitQuotaMounts(data, size);
320 OHOS::CmdExcludePathMap(data, size);
321 OHOS::CmdConvertSandbxRealPath(data, size);
322 OHOS::CmdAddQuterDirInfoFileStateFuzzTest(data, size);
323 OHOS::CmdPhysicalToSanboxPath(data, size);
324 OHOS::CmdAddPathMapForPathWildCard(data, size);
325 OHOS::CheckIfDirForIncludesFuzzTest(data, size);
326 OHOS::GetPathWildCardFuzzTest(data, size);
327 OHOS::CmdCheckOverLongPath(data, size);
328 } catch (OHOS::FileManagement::Backup::BError &err) {
329 HILOGE("BackupSaFuzzTest error");
330 } catch (...) {
331 HILOGE("BackupSaFuzzTest exception");
332 }
333 return 0;
334 }