1 /*
2  * Copyright (c) 2023 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 "diff_patch/diff_patch_interface.h"
17 
18 #include <array>
19 #include <cstddef>
20 #include <cstdint>
21 #include <iostream>
22 #include <string>
23 #include <vector>
24 #include <fstream>
25 #include <cstdio>
26 #include "log/log.h"
27 #include <fuzzer/FuzzedDataProvider.h>
28 
29 using namespace Updater;
30 namespace OHOS {
WriteDataToFile(const char* data, size_t size, const char* filePath, bool isAppend = false)31     bool WriteDataToFile(const char* data, size_t size, const char* filePath, bool isAppend = false)
32     {
33         std::ofstream ofs;
34         if (isAppend) {
35             ofs.open(filePath, std::ios::app | std::ios::binary);
36         } else {
37             ofs.open(filePath, std::ios::ate | std::ios::binary);
38         }
39         if (!ofs.is_open()) {
40             LOG(ERROR) << "open " << filePath << " failed";
41             return false;
42         }
43         ofs.write(data, size);
44         ofs.close();
45         return true;
46     }
47 
FuzzApplyPatch(const uint8_t* data, size_t size)48     void FuzzApplyPatch(const uint8_t* data, size_t size)
49     {
50         FuzzedDataProvider fdp(data, size);
51         const int magicNumSize = 4;
52         const char* bspatchPath = "/data/applyPatchfuzzBspatch";
53         const char* imgpatchPath = "/data/applyPatchfuzzImgpatch";
54         const char* oldFilePath = "/data/applyPatchfuzzOldFile";
55         const char* newFilePath = "/data/applyPatchfuzzNewFile";
56         bool isPkgFormat = false;
57         bool ret = WriteDataToFile(reinterpret_cast<const char*>(data), size, oldFilePath);
58         isPkgFormat = fdp.ConsumeBool();
59         if (isPkgFormat) {
60             ret &= WriteDataToFile("BSDIFF40", magicNumSize, bspatchPath);
61             ret &= WriteDataToFile(reinterpret_cast<const char*>(data), size, bspatchPath, true);
62             ApplyPatch(bspatchPath, oldFilePath, newFilePath);
63         } else {
64             ret &= WriteDataToFile("PKGDIFF0", magicNumSize, imgpatchPath);
65             ret &= WriteDataToFile(reinterpret_cast<const char*>(data), size, imgpatchPath, true);
66             ApplyPatch(imgpatchPath, oldFilePath, newFilePath);
67         }
68         if (!ret) {
69             LOG(ERROR) << "an invalid fuzztest due to input file creation failure";
70         }
71     }
72 }
73 
74 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)75 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
76 {
77     /* Run your code on data */
78     OHOS::FuzzApplyPatch(data, size);
79     return 0;
80 }
81