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 #include "backupext_fuzzer.h"
16 #include <cstring>
17
18 #include "ext_backup.h"
19 #include "ext_extension.h"
20 #include "message_parcel.h"
21
22 namespace OHOS {
23 using namespace std;
24 using namespace OHOS::FileManagement::Backup;
25
26 template <class T>
TypeCast(const uint8_t * data,int * pos=nullptr)27 T TypeCast(const uint8_t *data, int *pos = nullptr)
28 {
29 if (pos) {
30 *pos += sizeof(T);
31 }
32 return *(reinterpret_cast<const T *>(data));
33 }
34
InitFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)35 bool InitFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
36 {
37 (void)data;
38 shared_ptr<AbilityRuntime::AbilityLocalRecord> record = nullptr;
39 shared_ptr<AbilityRuntime::OHOSApplication> application = nullptr;
40 shared_ptr<AbilityRuntime::AbilityHandler> handler = nullptr;
41 const sptr<IRemoteObject> token = nullptr;
42 backup->Init(record, application, handler, token);
43 return true;
44 }
45
OnCommandFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)46 bool OnCommandFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
47 {
48 if (data == nullptr || size < sizeof(bool) + sizeof(int)) {
49 return true;
50 }
51
52 int pos = 0;
53 bool restart = TypeCast<bool>(data, &pos);
54 int startId = TypeCast<int>(data + pos, &pos);
55 int len = (size - pos) >> 1;
56 AAFwk::Want want;
57 want.SetElementName(string(reinterpret_cast<const char *>(data + pos), len),
58 string(reinterpret_cast<const char *>(data + pos + len), len));
59
60 backup->OnCommand(want, restart, startId);
61 return true;
62 }
63
OnConnectFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)64 bool OnConnectFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
65 {
66 int len = size >> 1;
67 AAFwk::Want want;
68 want.SetElementName(string(reinterpret_cast<const char *>(data), len),
69 string(reinterpret_cast<const char *>(data + len), size - len));
70
71 backup->OnConnect(want);
72 return true;
73 }
74
CreateFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)75 bool CreateFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
76 {
77 (void)data;
78 unique_ptr<AbilityRuntime::Runtime> runtime = nullptr;
79 backup->Create(runtime);
80 return true;
81 }
82
GetExtensionActionFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)83 bool GetExtensionActionFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
84 {
85 (void)data;
86 backup->GetExtensionAction();
87 return true;
88 }
89
OnRestoreFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)90 bool OnRestoreFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
91 {
92 function<void(ErrCode, string)> callback = [data](ErrCode, string) {};
93 function<void(ErrCode, const string)> callbackEx;
94 backup->OnRestore(callback, callbackEx);
95 return true;
96 }
97
GetBackupInfoFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)98 bool GetBackupInfoFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
99 {
100 function<void(ErrCode, string)> callback = [data](ErrCode, string) {};
101 backup->GetBackupInfo(callback);
102 return true;
103 }
104
WasFromSpecialVersionFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)105 bool WasFromSpecialVersionFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
106 {
107 (void)data;
108 backup->WasFromSpecialVersion();
109 return true;
110 }
111
SpecialVersionForCloneAndCloudFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)112 bool SpecialVersionForCloneAndCloudFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
113 {
114 (void)data;
115 backup->SpecialVersionForCloneAndCloud();
116 return true;
117 }
118
RestoreDataReadyFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)119 bool RestoreDataReadyFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
120 {
121 (void)data;
122 backup->RestoreDataReady();
123 return true;
124 }
125
InvokeAppExtMethodFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)126 bool InvokeAppExtMethodFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
127 {
128 string result = string(reinterpret_cast<const char *>(data), size);
129 backup->InvokeAppExtMethod(BError(BError::Codes::OK), result);
130 return true;
131 }
132
SetCreatorFuzzTest(shared_ptr<ExtBackup> backup,const uint8_t * data,size_t size)133 bool SetCreatorFuzzTest(shared_ptr<ExtBackup> backup, const uint8_t *data, size_t size)
134 {
135 (void)data;
136 CreatorFunc creator;
137 backup->SetCreator(creator);
138 return true;
139 }
140
CmdGetFileHandleFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)141 bool CmdGetFileHandleFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
142 {
143 MessageParcel msg;
144 MessageParcel reply;
145 MessageOption option;
146 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_GET_FILE_HANDLE_WITH_UNIQUE_FD);
147 msg.WriteString(string(reinterpret_cast<const char *>(data), size));
148 if (extension == nullptr) {
149 return false;
150 }
151 extension->OnRemoteRequest(code, msg, reply, option);
152 return true;
153 }
154
CmdHandleClearFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)155 bool CmdHandleClearFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
156 {
157 MessageParcel msg;
158 MessageParcel reply;
159 MessageOption option;
160 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_HANDLE_CLEAR);
161 msg.WriteBuffer(data, size);
162 if (extension == nullptr) {
163 return false;
164 }
165 extension->OnRemoteRequest(code, msg, reply, option);
166 return true;
167 }
168
CmdHandleUser0BackupFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)169 bool CmdHandleUser0BackupFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
170 {
171 MessageParcel msg;
172 MessageParcel reply;
173 MessageOption option;
174 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_USER0_ON_BACKUP);
175 msg.WriteBuffer(data, size);
176 if (extension == nullptr) {
177 return false;
178 }
179 extension->OnRemoteRequest(code, msg, reply, option);
180 return true;
181 }
182
CmdHandleBackupFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)183 bool CmdHandleBackupFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
184 {
185 if (data == nullptr || size < sizeof(bool)) {
186 return true;
187 }
188
189 MessageParcel msg;
190 MessageParcel reply;
191 MessageOption option;
192 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_HANDLE_BACKUP);
193 msg.WriteBool(*reinterpret_cast<const bool *>(data));
194 if (extension == nullptr) {
195 return false;
196 }
197 extension->OnRemoteRequest(code, msg, reply, option);
198 return true;
199 }
200
CmdPublishFileFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)201 bool CmdPublishFileFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
202 {
203 MessageParcel msg;
204 MessageParcel reply;
205 MessageOption option;
206 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_PUBLISH_FILE);
207 msg.WriteString(string(reinterpret_cast<const char *>(data), size));
208 if (extension == nullptr) {
209 return false;
210 }
211 extension->OnRemoteRequest(code, msg, reply, option);
212 return true;
213 }
214
CmdHandleRestoreFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)215 bool CmdHandleRestoreFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
216 {
217 if (data == nullptr || size < sizeof(bool)) {
218 return true;
219 }
220
221 MessageParcel msg;
222 MessageParcel reply;
223 MessageOption option;
224 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_HANDLE_RESTORE);
225 msg.WriteBool(*reinterpret_cast<const bool *>(data));
226 if (extension == nullptr) {
227 return false;
228 }
229 extension->OnRemoteRequest(code, msg, reply, option);
230 return true;
231 }
232
CmdGetIncrementalFileHandleFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)233 bool CmdGetIncrementalFileHandleFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
234 {
235 MessageParcel msg;
236 MessageParcel reply;
237 MessageOption option;
238 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_GET_INCREMENTAL_FILE_HANDLE);
239 msg.WriteString(string(reinterpret_cast<const char *>(data), size));
240 if (extension == nullptr) {
241 return false;
242 }
243 extension->OnRemoteRequest(code, msg, reply, option);
244 return true;
245 }
246
CmdPublishIncrementalFileFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)247 bool CmdPublishIncrementalFileFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
248 {
249 MessageParcel msg;
250 MessageParcel reply;
251 MessageOption option;
252 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_PUBLISH_INCREMENTAL_FILE);
253 msg.WriteString(string(reinterpret_cast<const char *>(data), size));
254 if (extension == nullptr) {
255 return false;
256 }
257 extension->OnRemoteRequest(code, msg, reply, option);
258 return true;
259 }
260
CmdHandleIncrementalBackupFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)261 bool CmdHandleIncrementalBackupFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
262 {
263 if (data == nullptr || size < sizeof(int) + sizeof(int)) {
264 return true;
265 }
266
267 MessageParcel msg;
268 MessageParcel reply;
269 MessageOption option;
270 int pos = 0;
271 int incrementalFd = TypeCast<int>(data, &pos);
272 int manifestFd = TypeCast<int>(data + pos);
273 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_HANDLE_INCREMENTAL_BACKUP);
274 msg.WriteFileDescriptor(incrementalFd);
275 msg.WriteFileDescriptor(manifestFd);
276 if (extension == nullptr) {
277 return false;
278 }
279 extension->OnRemoteRequest(code, msg, reply, option);
280 return true;
281 }
282
CmdIncrementalOnBackupFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)283 bool CmdIncrementalOnBackupFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
284 {
285 if (data == nullptr || size < sizeof(bool)) {
286 return true;
287 }
288
289 MessageParcel msg;
290 MessageParcel reply;
291 MessageOption option;
292 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_INCREMENTAL_ON_BACKUP);
293 msg.WriteBool(*reinterpret_cast<const bool *>(data));
294 if (extension == nullptr) {
295 return false;
296 }
297 extension->OnRemoteRequest(code, msg, reply, option);
298 return true;
299 }
300
CmdGetIncrementalBackupFileHandleFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)301 bool CmdGetIncrementalBackupFileHandleFuzzTest(OHOS::sptr<BackupExtExtension> extension,
302 const uint8_t *data,
303 size_t size)
304 {
305 MessageParcel msg;
306 MessageParcel reply;
307 MessageOption option;
308 uint32_t code = static_cast<uint32_t>(IExtensionIpcCode::COMMAND_GET_INCREMENTAL_BACKUP_FILE_HANDLE);
309 msg.WriteBuffer(data, size);
310 if (extension == nullptr) {
311 return false;
312 }
313 extension->OnRemoteRequest(code, msg, reply, option);
314 return true;
315 }
316
OnRemoteRequestFuzzTest(OHOS::sptr<BackupExtExtension> extension,const uint8_t * data,size_t size)317 bool OnRemoteRequestFuzzTest(OHOS::sptr<BackupExtExtension> extension, const uint8_t *data, size_t size)
318 {
319 uint32_t codeMax = 17;
320 for (uint32_t code = 1; code < codeMax; code++) {
321 MessageParcel datas;
322 MessageParcel reply;
323 MessageOption option;
324
325 datas.WriteInterfaceToken(ExtensionStub::GetDescriptor());
326 datas.WriteBuffer(reinterpret_cast<const char*>(data), size);
327 datas.RewindRead(0);
328 if (extension == nullptr) {
329 return false;
330 }
331 try {
332 extension->OnRemoteRequest(code, datas, reply, option);
333 } catch (OHOS::FileManagement::Backup::BError &err) {
334 HILOGE("BackupSaFuzzTest error");
335 } catch (...) {
336 HILOGE("BackupSaFuzzTest exception");
337 }
338 }
339 return true;
340 }
341 } // namespace OHOS
342
343 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)344 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
345 {
346 /* Run your code on data */
347 auto extBackup = std::make_shared<OHOS::FileManagement::Backup::ExtBackup>();
348 auto extension = OHOS::sptr<OHOS::FileManagement::Backup::BackupExtExtension>(
349 new OHOS::FileManagement::Backup::BackupExtExtension(extBackup, ""));
350
351 OHOS::OnRemoteRequestFuzzTest(extension, data, size);
352 OHOS::InitFuzzTest(extBackup, data, size);
353 OHOS::OnCommandFuzzTest(extBackup, data, size);
354 OHOS::OnConnectFuzzTest(extBackup, data, size);
355 OHOS::CreateFuzzTest(extBackup, data, size);
356 OHOS::GetExtensionActionFuzzTest(extBackup, data, size);
357 OHOS::OnRestoreFuzzTest(extBackup, data, size);
358 OHOS::GetBackupInfoFuzzTest(extBackup, data, size);
359 OHOS::WasFromSpecialVersionFuzzTest(extBackup, data, size);
360 OHOS::SpecialVersionForCloneAndCloudFuzzTest(extBackup, data, size);
361 OHOS::RestoreDataReadyFuzzTest(extBackup, data, size);
362 OHOS::InvokeAppExtMethodFuzzTest(extBackup, data, size);
363 OHOS::SetCreatorFuzzTest(extBackup, data, size);
364
365 try {
366 OHOS::CmdGetFileHandleFuzzTest(extension, data, size);
367 OHOS::CmdHandleClearFuzzTest(extension, data, size);
368 OHOS::CmdHandleUser0BackupFuzzTest(extension, data, size);
369 OHOS::CmdHandleBackupFuzzTest(extension, data, size);
370 OHOS::CmdPublishFileFuzzTest(extension, data, size);
371 OHOS::CmdHandleRestoreFuzzTest(extension, data, size);
372 OHOS::CmdGetIncrementalFileHandleFuzzTest(extension, data, size);
373 OHOS::CmdPublishIncrementalFileFuzzTest(extension, data, size);
374 OHOS::CmdHandleIncrementalBackupFuzzTest(extension, data, size);
375 OHOS::CmdIncrementalOnBackupFuzzTest(extension, data, size);
376 OHOS::CmdGetIncrementalBackupFileHandleFuzzTest(extension, data, size);
377 } catch (OHOS::FileManagement::Backup::BError &err) {
378 // Only filter BError errors, Other results are not expected.
379 }
380 return 0;
381 }
382