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