1/* 2 * Copyright (c) 2021 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 "UpdaterStartUpdaterProc_fuzzer.h" 17 18#include <array> 19#include <cstddef> 20#include <cstdint> 21#include <iostream> 22#include <string> 23#include <vector> 24#include "pkg_algorithm.h" 25#include "pkg_algo_digest.h" 26#include "pkg_utils.h" 27#include "updater.h" 28#include "updater_ui.h" 29 30using namespace Updater; 31using namespace Hpackage; 32 33const static std::string TEST_PATH_TO = "/data/fuzz/test/"; 34 35static inline std::string GetTestCertName() 36{ 37 std::string name = TEST_PATH_TO; 38 name += "signing_cert.crt"; 39 return name; 40} 41 42static inline std::string GetTestPrivateKeyName() 43{ 44 std::string name = TEST_PATH_TO; 45 name += "rsa_private_key2048.pem"; 46 return name; 47} 48 49static int32_t BuildFileDigest(uint8_t &digest, size_t size, const std::string &packagePath) 50{ 51 PkgManager::StreamPtr stream = nullptr; 52 PkgManager::PkgManagerPtr packageManager = PkgManager::CreatePackageInstance(); 53 54 int32_t ret = packageManager->CreatePkgStream(stream, packagePath, 0, PkgStream::PkgStreamType_Read); 55 if (ret != PKG_SUCCESS) { 56 PKG_LOGE("Create input stream fail %s", packagePath.c_str()); 57 packageManager->ClosePkgStream(stream); 58 PkgManager::ReleasePackageInstance(packageManager); 59 return ret; 60 } 61 size_t fileLen = stream->GetFileLength(); 62 if (fileLen <= 0 || fileLen > SIZE_MAX) { 63 PKG_LOGE("Invalid file len %zu to load %s", fileLen, stream->GetFileName().c_str()); 64 packageManager->ClosePkgStream(stream); 65 PkgManager::ReleasePackageInstance(packageManager); 66 return PKG_INVALID_FILE; 67 } 68 69 size_t buffSize = 4096; 70 PkgBuffer buff(buffSize); 71 // 整包检查 72 DigestAlgorithm::DigestAlgorithmPtr algorithm = PkgAlgorithmFactory::GetDigestAlgorithm(PKG_DIGEST_TYPE_SHA256); 73 if (algorithm == nullptr) { 74 PKG_LOGE("Invalid file %s", stream->GetFileName().c_str()); 75 packageManager->ClosePkgStream(stream); 76 PkgManager::ReleasePackageInstance(packageManager); 77 return PKG_NOT_EXIST_ALGORITHM; 78 } 79 algorithm->Init(); 80 81 size_t offset = 0; 82 size_t readLen = 0; 83 while (offset < fileLen) { 84 ret = stream->Read(buff, offset, buffSize, readLen); 85 if (ret != PKG_SUCCESS) { 86 PKG_LOGE("read buffer fail %s", stream->GetFileName().c_str()); 87 packageManager->ClosePkgStream(stream); 88 PkgManager::ReleasePackageInstance(packageManager); 89 return ret; 90 } 91 algorithm->Update(buff, readLen); 92 93 offset += readLen; 94 readLen = 0; 95 } 96 PkgBuffer signBuffer(&digest, size); 97 algorithm->Final(signBuffer); 98 packageManager->ClosePkgStream(stream); 99 PkgManager::ReleasePackageInstance(packageManager); 100 return PKG_SUCCESS; 101} 102 103static int CreatePackageZip(const std::vector<std::string> &fstabFile) 104{ 105 int32_t ret = PKG_SUCCESS; 106 uint32_t updateFileVersion = 1000; 107 uint32_t componentInfoIdBase = 100; 108 uint8_t componentInfoFlags = 22; 109 std::string testPackageName = "test_package.zip"; 110 111 PKG_LOGI("\n\n ************* CreatePackageZip %s \r\n", testPackageName.c_str()); 112 UpgradePkgInfoExt pkgInfo; 113 pkgInfo.softwareVersion = strdup("100.100.100.100"); 114 pkgInfo.date = strdup("2021-07-16"); 115 pkgInfo.time = strdup("13:14:00"); 116 pkgInfo.productUpdateId = strdup("555.555.100.555"); 117 pkgInfo.entryCount = fstabFile.size(); 118 pkgInfo.updateFileVersion = updateFileVersion; 119 pkgInfo.digestMethod = PKG_DIGEST_TYPE_SHA256; 120 pkgInfo.signMethod = PKG_SIGN_METHOD_RSA; 121 pkgInfo.pkgType = PKG_PACK_TYPE_ZIP; 122 std::string filePath; 123 std::vector<ComponentInfoExt> comp(fstabFile.size()); 124 for (size_t i = 0; i < fstabFile.size(); i++) { 125 comp[i].componentAddr = strdup(fstabFile[i].c_str()); 126 filePath = TEST_PATH_TO; 127 filePath += fstabFile[i].c_str(); 128 comp[i].filePath = strdup(filePath.c_str()); 129 comp[i].version = strdup("55555555"); 130 131 ret = BuildFileDigest(*comp[i].digest, sizeof(comp[i].digest), filePath); 132 comp[i].size = GetFileSize(filePath); 133 comp[i].originalSize = comp[i].size; 134 comp[i].id = componentInfoIdBase; 135 comp[i].resType = 1; 136 comp[i].type = 1; 137 comp[i].flags = componentInfoFlags; 138 filePath.clear(); 139 } 140 141 std::string packagePath = TEST_PATH_TO; 142 packagePath += testPackageName; 143 ret = CreatePackage(&pkgInfo, comp, packagePath.c_str(), GetTestPrivateKeyName().c_str()); 144 if (ret == 0) { 145 PKG_LOGI("CreatePackage success offset"); 146 } 147 for (size_t i = 0; i < fstabFile.size(); i++) { 148 free(comp[i].componentAddr); 149 free(comp[i].filePath); 150 free(comp[i].version); 151 } 152 free(pkgInfo.productUpdateId); 153 free(pkgInfo.softwareVersion); 154 free(pkgInfo.date); 155 free(pkgInfo.time); 156 return ret; 157} 158 159static int StartUpdaterProcFun(const std::string &patch) 160{ 161 UpdaterStatus status; 162 std::vector<std::string> components; 163 PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance(); 164 165 pkgManager->LoadPackage(patch, GetTestCertName(), components); 166 UpdaterParams upParams; 167 upParams.updatePackage.push_back(patch); 168 upParams.retryCount = 0; 169 status = StartUpdaterProc(pkgManager, upParams); 170 LOG(INFO) << "[fuzz] status " << status; 171 PkgManager::ReleasePackageInstance(pkgManager); 172 return status; 173} 174 175namespace OHOS { 176 void FuzzStartUpdaterProc(const uint8_t* data, size_t size) 177 { 178 FILE *pFile; 179 std::vector<std::string> fstabFile = { 180 "build_tools.zip", 181 "updater.txt" 182 }; 183 184 pFile = fopen("updater.txt", "w+"); 185 if (pFile == nullptr) { 186 LOG(ERROR) << "[fuzz]open file failed"; 187 return; 188 } 189 190 fwrite(data, 1, size, pFile); 191 fclose(pFile); 192 193 CreatePackageZip(fstabFile); 194 StartUpdaterProcFun(TEST_PATH_TO + "test_package.zip"); 195 196 remove("updater.txt"); 197 remove("test_package.zip"); 198 } 199} 200 201/* Fuzzer entry point */ 202extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 203{ 204 /* Run your code on data */ 205 OHOS::FuzzStartUpdaterProc(data, size); 206 return 0; 207} 208 209