1fb299fa2Sopenharmony_ci/*
2fb299fa2Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at
6fb299fa2Sopenharmony_ci *
7fb299fa2Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb299fa2Sopenharmony_ci *
9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and
13fb299fa2Sopenharmony_ci * limitations under the License.
14fb299fa2Sopenharmony_ci */
15fb299fa2Sopenharmony_ci
16fb299fa2Sopenharmony_ci#include "updatermain_fuzzer.h"
17fb299fa2Sopenharmony_ci
18fb299fa2Sopenharmony_ci#include <array>
19fb299fa2Sopenharmony_ci#include <cstddef>
20fb299fa2Sopenharmony_ci#include <cstdint>
21fb299fa2Sopenharmony_ci#include <iostream>
22fb299fa2Sopenharmony_ci#include <string>
23fb299fa2Sopenharmony_ci#include <vector>
24fb299fa2Sopenharmony_ci#include <sys/stat.h>
25fb299fa2Sopenharmony_ci#include <sys/types.h>
26fb299fa2Sopenharmony_ci#include "log/log.h"
27fb299fa2Sopenharmony_ci#include "updater_main.h"
28fb299fa2Sopenharmony_ci#include "misc_info/misc_info.h"
29fb299fa2Sopenharmony_ci#include "updater/updater_const.h"
30fb299fa2Sopenharmony_ci#include "securec.h"
31fb299fa2Sopenharmony_ci#include "utils.h"
32fb299fa2Sopenharmony_ci#include "updater/updater.h"
33fb299fa2Sopenharmony_ci#include "updater_ui_stub.h"
34fb299fa2Sopenharmony_ci
35fb299fa2Sopenharmony_ciusing namespace Updater;
36fb299fa2Sopenharmony_ciusing namespace std;
37fb299fa2Sopenharmony_ciconstexpr uint32_t MAX_ARG_SIZE = 10;
38fb299fa2Sopenharmony_ci
39fb299fa2Sopenharmony_cistatic void ParseParamsFuzzTest()
40fb299fa2Sopenharmony_ci{
41fb299fa2Sopenharmony_ci    UpdateMessage boot {};
42fb299fa2Sopenharmony_ci    const std::string commandFile = "/data/updater/command";
43fb299fa2Sopenharmony_ci    auto fp = std::unique_ptr<FILE, decltype(&fclose)>(fopen(commandFile.c_str(), "wb"), fclose);
44fb299fa2Sopenharmony_ci    if (fp == nullptr) {
45fb299fa2Sopenharmony_ci        return;
46fb299fa2Sopenharmony_ci    }
47fb299fa2Sopenharmony_ci    const std::string commandMsg = "boot_updater";
48fb299fa2Sopenharmony_ci    if (strncpy_s(boot.command, sizeof(boot.command) - 1, commandMsg.c_str(), commandMsg.size()) != 0) {
49fb299fa2Sopenharmony_ci        return;
50fb299fa2Sopenharmony_ci    }
51fb299fa2Sopenharmony_ci    if (strncpy_s(boot.update, sizeof(boot.update), "", sizeof(boot.update)) != 0) {
52fb299fa2Sopenharmony_ci        return;
53fb299fa2Sopenharmony_ci    }
54fb299fa2Sopenharmony_ci    WriteUpdaterMessage(commandFile, boot);
55fb299fa2Sopenharmony_ci    char **argv = new char *[1];
56fb299fa2Sopenharmony_ci    argv[0] = new char[MAX_ARG_SIZE];
57fb299fa2Sopenharmony_ci    if (strncpy_s(argv[0], MAX_ARG_SIZE, "./main", MAX_ARG_SIZE) != 0) {
58fb299fa2Sopenharmony_ci        return;
59fb299fa2Sopenharmony_ci    }
60fb299fa2Sopenharmony_ci    int argc = 1;
61fb299fa2Sopenharmony_ci    Utils::ParseParams(argc, argv);
62fb299fa2Sopenharmony_ci    PostUpdater(true);
63fb299fa2Sopenharmony_ci    delete argv[0];
64fb299fa2Sopenharmony_ci    delete []argv;
65fb299fa2Sopenharmony_ci}
66fb299fa2Sopenharmony_ci
67fb299fa2Sopenharmony_cistatic void MianUpdaterFuzzTest()
68fb299fa2Sopenharmony_ci{
69fb299fa2Sopenharmony_ci    int argsSize = 24;
70fb299fa2Sopenharmony_ci    UpdateMessage boot {};
71fb299fa2Sopenharmony_ci    if (access("/data/updater/", 0)) {
72fb299fa2Sopenharmony_ci        int ret = mkdir("/data/updater/", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
73fb299fa2Sopenharmony_ci        if (ret != 0) {
74fb299fa2Sopenharmony_ci            return;
75fb299fa2Sopenharmony_ci        }
76fb299fa2Sopenharmony_ci    }
77fb299fa2Sopenharmony_ci    const std::string commandFile = "/data/updater/command";
78fb299fa2Sopenharmony_ci    auto fp = std::unique_ptr<FILE, decltype(&fclose)>(fopen(commandFile.c_str(), "wb"), fclose);
79fb299fa2Sopenharmony_ci    if (fp == nullptr) {
80fb299fa2Sopenharmony_ci        return;
81fb299fa2Sopenharmony_ci    }
82fb299fa2Sopenharmony_ci
83fb299fa2Sopenharmony_ci    const std::string commandMsg = "boot_updater";
84fb299fa2Sopenharmony_ci    const std::string updateMsg = "--update_package=/data/updater/updater/updater_full.zip";
85fb299fa2Sopenharmony_ci    if (strncpy_s(boot.command, sizeof(boot.command) - 1, commandMsg.c_str(), commandMsg.size()) != 0) {
86fb299fa2Sopenharmony_ci        return;
87fb299fa2Sopenharmony_ci    }
88fb299fa2Sopenharmony_ci    if (strncpy_s(boot.update, sizeof(boot.update) - 1, updateMsg.c_str(), updateMsg.size()) != 0) {
89fb299fa2Sopenharmony_ci        return;
90fb299fa2Sopenharmony_ci    }
91fb299fa2Sopenharmony_ci    bool bRet = WriteUpdaterMessage(commandFile, boot);
92fb299fa2Sopenharmony_ci    if (!bRet) {
93fb299fa2Sopenharmony_ci        return;
94fb299fa2Sopenharmony_ci    }
95fb299fa2Sopenharmony_ci    char **argv = new char* [1];
96fb299fa2Sopenharmony_ci    argv[0] = new char[argsSize];
97fb299fa2Sopenharmony_ci    if (strncpy_s(argv[0], argsSize, "./UpdaterMain", argsSize) != 0) {
98fb299fa2Sopenharmony_ci        return;
99fb299fa2Sopenharmony_ci    }
100fb299fa2Sopenharmony_ci    int argc = 1;
101fb299fa2Sopenharmony_ci
102fb299fa2Sopenharmony_ci    int ret = UpdaterMain(argc, argv);
103fb299fa2Sopenharmony_ci    if (!ret) {
104fb299fa2Sopenharmony_ci        return;
105fb299fa2Sopenharmony_ci    }
106fb299fa2Sopenharmony_ci    delete argv[0];
107fb299fa2Sopenharmony_ci    delete []argv;
108fb299fa2Sopenharmony_ci}
109fb299fa2Sopenharmony_ci
110fb299fa2Sopenharmony_cistatic void SdCardUpdateFuzzTest()
111fb299fa2Sopenharmony_ci{
112fb299fa2Sopenharmony_ci    int argsSize = 24;
113fb299fa2Sopenharmony_ci    UpdateMessage boot {};
114fb299fa2Sopenharmony_ci    if (access("/data/updater/", 0)) {
115fb299fa2Sopenharmony_ci        int ret = mkdir("/data/updater/", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
116fb299fa2Sopenharmony_ci        if (ret != 0) {
117fb299fa2Sopenharmony_ci            return;
118fb299fa2Sopenharmony_ci        }
119fb299fa2Sopenharmony_ci    }
120fb299fa2Sopenharmony_ci    const std::string commandFile = "/data/updater/command";
121fb299fa2Sopenharmony_ci    auto fp = std::unique_ptr<FILE, decltype(&fclose)>(fopen(commandFile.c_str(), "wb"), fclose);
122fb299fa2Sopenharmony_ci    if (fp == nullptr) {
123fb299fa2Sopenharmony_ci        return;
124fb299fa2Sopenharmony_ci    }
125fb299fa2Sopenharmony_ci    const std::string commandMsg = "boot_updater";
126fb299fa2Sopenharmony_ci    const std::string updateMsg = "--sdcard_update";
127fb299fa2Sopenharmony_ci    if (strncpy_s(boot.command, sizeof(boot.command) - 1, commandMsg.c_str(), commandMsg.size()) != 0) {
128fb299fa2Sopenharmony_ci        return;
129fb299fa2Sopenharmony_ci    }
130fb299fa2Sopenharmony_ci    if (strncpy_s(boot.update, sizeof(boot.update) - 1, updateMsg.c_str(), updateMsg.size()) != 0) {
131fb299fa2Sopenharmony_ci        return;
132fb299fa2Sopenharmony_ci    }
133fb299fa2Sopenharmony_ci    bool bRet = WriteUpdaterMessage(commandFile, boot);
134fb299fa2Sopenharmony_ci    if (!bRet) {
135fb299fa2Sopenharmony_ci        return;
136fb299fa2Sopenharmony_ci    }
137fb299fa2Sopenharmony_ci    char **argv = new char* [1];
138fb299fa2Sopenharmony_ci    argv[0] = new char[argsSize];
139fb299fa2Sopenharmony_ci    if (strncpy_s(argv[0], argsSize, "./UpdaterMain", argsSize) != 0) {
140fb299fa2Sopenharmony_ci        return;
141fb299fa2Sopenharmony_ci    }
142fb299fa2Sopenharmony_ci    int argc = 1;
143fb299fa2Sopenharmony_ci    if (UpdaterMain(argc, argv) != 0) {
144fb299fa2Sopenharmony_ci        return;
145fb299fa2Sopenharmony_ci    }
146fb299fa2Sopenharmony_ci    delete argv[0];
147fb299fa2Sopenharmony_ci    delete []argv;
148fb299fa2Sopenharmony_ci}
149fb299fa2Sopenharmony_ci
150fb299fa2Sopenharmony_cistatic void InstallUpdaterPackageFuzzTest()
151fb299fa2Sopenharmony_ci{
152fb299fa2Sopenharmony_ci    UpdaterParams upParams;
153fb299fa2Sopenharmony_ci    upParams.retryCount = 0;
154fb299fa2Sopenharmony_ci    upParams.callbackProgress = [] (float value) { UPDATER_UI_INSTANCE.ShowProgress(value); };
155fb299fa2Sopenharmony_ci    upParams.updatePackage.push_back("/data/updater/updater/updater_full.zip");
156fb299fa2Sopenharmony_ci    Hpackage::PkgManager::PkgManagerPtr pkgManager = Hpackage::PkgManager::CreatePackageInstance();
157fb299fa2Sopenharmony_ci    if (InstallUpdaterPackage(upParams, pkgManager) != UPDATE_ERROR) {
158fb299fa2Sopenharmony_ci        return;
159fb299fa2Sopenharmony_ci    }
160fb299fa2Sopenharmony_ci}
161fb299fa2Sopenharmony_ci
162fb299fa2Sopenharmony_cistatic void DoUpdatePackagesFuzzTest()
163fb299fa2Sopenharmony_ci{
164fb299fa2Sopenharmony_ci    UpdaterParams upParams;
165fb299fa2Sopenharmony_ci    if (DoUpdatePackages(upParams) != UPDATE_CORRUPT) {
166fb299fa2Sopenharmony_ci        return;
167fb299fa2Sopenharmony_ci    }
168fb299fa2Sopenharmony_ci    upParams.updatePackage.push_back("/data/updater/updater/updater_full.zip");
169fb299fa2Sopenharmony_ci    if (DoUpdatePackages(upParams) != UPDATE_CORRUPT) {
170fb299fa2Sopenharmony_ci        return;
171fb299fa2Sopenharmony_ci    }
172fb299fa2Sopenharmony_ci}
173fb299fa2Sopenharmony_ci
174fb299fa2Sopenharmony_cistatic void StartUpdaterEntryFuzzTest()
175fb299fa2Sopenharmony_ci{
176fb299fa2Sopenharmony_ci    UpdaterParams upParams;
177fb299fa2Sopenharmony_ci    upParams.factoryResetMode = "factory_wipe_data";
178fb299fa2Sopenharmony_ci    if (DoUpdatePackages(upParams) != UPDATE_CORRUPT) {
179fb299fa2Sopenharmony_ci        return;
180fb299fa2Sopenharmony_ci    }
181fb299fa2Sopenharmony_ci    upParams.factoryResetMode = "user_wipe_data";
182fb299fa2Sopenharmony_ci    if (DoUpdatePackages(upParams) != UPDATE_CORRUPT) {
183fb299fa2Sopenharmony_ci        return;
184fb299fa2Sopenharmony_ci    }
185fb299fa2Sopenharmony_ci    upParams.factoryResetMode = "menu_wipe_data";
186fb299fa2Sopenharmony_ci    if (DoUpdatePackages(upParams) != UPDATE_CORRUPT) {
187fb299fa2Sopenharmony_ci        return;
188fb299fa2Sopenharmony_ci    }
189fb299fa2Sopenharmony_ci    upParams.factoryResetMode = "";
190fb299fa2Sopenharmony_ci    if (DoUpdatePackages(upParams) != UPDATE_CORRUPT) {
191fb299fa2Sopenharmony_ci        return;
192fb299fa2Sopenharmony_ci    }
193fb299fa2Sopenharmony_ci}
194fb299fa2Sopenharmony_ci
195fb299fa2Sopenharmony_cistatic void ExtractUpdaterBinaryFuzzTest()
196fb299fa2Sopenharmony_ci{
197fb299fa2Sopenharmony_ci    Hpackage::PkgManager::PkgManagerPtr pkgManager = Hpackage::PkgManager::CreatePackageInstance();
198fb299fa2Sopenharmony_ci    std::string path = "xxx";
199fb299fa2Sopenharmony_ci    int32_t ret = ExtractUpdaterBinary(pkgManager, path, UPDATER_BINARY);
200fb299fa2Sopenharmony_ci    if (ret != 1) {
201fb299fa2Sopenharmony_ci        return;
202fb299fa2Sopenharmony_ci    }
203fb299fa2Sopenharmony_ci    path = "/data/updater/updater/updater_full.zip";
204fb299fa2Sopenharmony_ci    ret = ExtractUpdaterBinary(pkgManager, path, UPDATER_BINARY);
205fb299fa2Sopenharmony_ci    Hpackage::PkgManager::ReleasePackageInstance(pkgManager);
206fb299fa2Sopenharmony_ci    if (ret != 1) {
207fb299fa2Sopenharmony_ci        return;
208fb299fa2Sopenharmony_ci    }
209fb299fa2Sopenharmony_ci}
210fb299fa2Sopenharmony_ci
211fb299fa2Sopenharmony_cistatic void IsSpaceCapacitySufficientFuzzTest()
212fb299fa2Sopenharmony_ci{
213fb299fa2Sopenharmony_ci    UpdaterParams upParams {};
214fb299fa2Sopenharmony_ci    UpdaterStatus status = IsSpaceCapacitySufficient(upParams);
215fb299fa2Sopenharmony_ci    if (status != UPDATE_ERROR) {
216fb299fa2Sopenharmony_ci        return;
217fb299fa2Sopenharmony_ci    }
218fb299fa2Sopenharmony_ci    if (CheckStatvfs(0) != 0) {
219fb299fa2Sopenharmony_ci        return;
220fb299fa2Sopenharmony_ci    }
221fb299fa2Sopenharmony_ci    if (IsBatteryCapacitySufficient()) {
222fb299fa2Sopenharmony_ci        return;
223fb299fa2Sopenharmony_ci    }
224fb299fa2Sopenharmony_ci    upParams.updatePackage.push_back("/data/updater/updater/updater_full.zip");
225fb299fa2Sopenharmony_ci    status = IsSpaceCapacitySufficient(upParams);
226fb299fa2Sopenharmony_ci    if (status != UPDATE_SUCCESS) {
227fb299fa2Sopenharmony_ci        return;
228fb299fa2Sopenharmony_ci    }
229fb299fa2Sopenharmony_ci}
230fb299fa2Sopenharmony_ci
231fb299fa2Sopenharmony_cistatic void ProgressFuzzTest()
232fb299fa2Sopenharmony_ci{
233fb299fa2Sopenharmony_ci    int progress = 0;
234fb299fa2Sopenharmony_ci    SetTmpProgressValue(progress);
235fb299fa2Sopenharmony_ci    if (GetTmpProgressValue() != 0) {
236fb299fa2Sopenharmony_ci        return;
237fb299fa2Sopenharmony_ci    }
238fb299fa2Sopenharmony_ci    ProgressSmoothHandler(0, 1);
239fb299fa2Sopenharmony_ci}
240fb299fa2Sopenharmony_ci
241fb299fa2Sopenharmony_cistatic void UtilsFuzzTest(const uint8_t* data, size_t size)
242fb299fa2Sopenharmony_ci{
243fb299fa2Sopenharmony_ci    if (!Utils::IsDirExist(std::string(reinterpret_cast<const char*>(data), size))) {
244fb299fa2Sopenharmony_ci        return;
245fb299fa2Sopenharmony_ci    }
246fb299fa2Sopenharmony_ci    std::vector<std::string> files {};
247fb299fa2Sopenharmony_ci    if (Utils::GetFilesFromDirectory(std::string(reinterpret_cast<const char*>(data), size), files, false) < 0) {
248fb299fa2Sopenharmony_ci        return;
249fb299fa2Sopenharmony_ci    }
250fb299fa2Sopenharmony_ci    std::string filePath = std::string(reinterpret_cast<const char*>(data), size) + "MountForPath_fuzzer.fstable";
251fb299fa2Sopenharmony_ci    if (!Utils::IsFileExist(filePath)) {
252fb299fa2Sopenharmony_ci        return;
253fb299fa2Sopenharmony_ci    }
254fb299fa2Sopenharmony_ci}
255fb299fa2Sopenharmony_ci
256fb299fa2Sopenharmony_cinamespace OHOS {
257fb299fa2Sopenharmony_ci    void FuzzUpdater(const uint8_t* data, size_t size)
258fb299fa2Sopenharmony_ci    {
259fb299fa2Sopenharmony_ci        ParseParamsFuzzTest();
260fb299fa2Sopenharmony_ci        MianUpdaterFuzzTest();
261fb299fa2Sopenharmony_ci        SdCardUpdateFuzzTest();
262fb299fa2Sopenharmony_ci        InstallUpdaterPackageFuzzTest();
263fb299fa2Sopenharmony_ci        DoUpdatePackagesFuzzTest();
264fb299fa2Sopenharmony_ci        StartUpdaterEntryFuzzTest();
265fb299fa2Sopenharmony_ci        ExtractUpdaterBinaryFuzzTest();
266fb299fa2Sopenharmony_ci        IsSpaceCapacitySufficientFuzzTest();
267fb299fa2Sopenharmony_ci        ProgressFuzzTest();
268fb299fa2Sopenharmony_ci        UtilsFuzzTest(data, size);
269fb299fa2Sopenharmony_ci    }
270fb299fa2Sopenharmony_ci}
271fb299fa2Sopenharmony_ci
272fb299fa2Sopenharmony_ci/* Fuzzer entry point */
273fb299fa2Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
274fb299fa2Sopenharmony_ci{
275fb299fa2Sopenharmony_ci    /* Run your code on data */
276fb299fa2Sopenharmony_ci    OHOS::FuzzUpdater(data, size);
277fb299fa2Sopenharmony_ci    return 0;
278fb299fa2Sopenharmony_ci}
279fb299fa2Sopenharmony_ci
280