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