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