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 35using namespace Updater; 36using namespace std; 37constexpr uint32_t MAX_ARG_SIZE = 10; 38 39static 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 67static 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 110static 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 150static 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 162static 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 174static 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 195static 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 211static 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 231static void ProgressFuzzTest() 232{ 233 int progress = 0; 234 SetTmpProgressValue(progress); 235 if (GetTmpProgressValue() != 0) { 236 return; 237 } 238 ProgressSmoothHandler(0, 1); 239} 240 241static 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 256namespace OHOS { 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 */ 273extern "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