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