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 "scriptmanager_fuzzer.h" 17fb299fa2Sopenharmony_ci 18fb299fa2Sopenharmony_ci#include <fcntl.h> 19fb299fa2Sopenharmony_ci#include <iostream> 20fb299fa2Sopenharmony_ci#include <sys/mman.h> 21fb299fa2Sopenharmony_ci#include <unistd.h> 22fb299fa2Sopenharmony_ci#include <vector> 23fb299fa2Sopenharmony_ci#include "hash_data_verifier.h" 24fb299fa2Sopenharmony_ci#include "log.h" 25fb299fa2Sopenharmony_ci#include "pkg_stream.h" 26fb299fa2Sopenharmony_ci#include "pkg_utils.h" 27fb299fa2Sopenharmony_ci#include "scope_guard.h" 28fb299fa2Sopenharmony_ci#include "script_instructionhelper.h" 29fb299fa2Sopenharmony_ci#include "script_manager_impl.h" 30fb299fa2Sopenharmony_ci#include "script_manager.h" 31fb299fa2Sopenharmony_ci#include "script_unittest.h" 32fb299fa2Sopenharmony_ci#include "script_utils.h" 33fb299fa2Sopenharmony_ci#include "utils.h" 34fb299fa2Sopenharmony_ci 35fb299fa2Sopenharmony_ciusing namespace Hpackage; 36fb299fa2Sopenharmony_ciusing namespace Uscript; 37fb299fa2Sopenharmony_ciusing namespace Updater; 38fb299fa2Sopenharmony_ci 39fb299fa2Sopenharmony_cinamespace OHOS { 40fb299fa2Sopenharmony_ciconstexpr int32_t SCRIPT_TEST_PRIORITY_NUM = 3; 41fb299fa2Sopenharmony_ciconstexpr int32_t SCRIPT_TEST_LAST_PRIORITY = 2; 42fb299fa2Sopenharmony_ciconst std::string FUZZ_TEST_PATH_FROM = "/data/fuzz/test/"; 43fb299fa2Sopenharmony_ci 44fb299fa2Sopenharmony_ciclass TestPkgManager : public TestScriptPkgManager { 45fb299fa2Sopenharmony_cipublic: 46fb299fa2Sopenharmony_ci const FileInfo *GetFileInfo(const std::string &fileId) override 47fb299fa2Sopenharmony_ci { 48fb299fa2Sopenharmony_ci static FileInfo fileInfo {}; 49fb299fa2Sopenharmony_ci static std::vector<std::string> testFileNames = { 50fb299fa2Sopenharmony_ci "loadScript.us", 51fb299fa2Sopenharmony_ci "test_function.us", 52fb299fa2Sopenharmony_ci "test_if.us", 53fb299fa2Sopenharmony_ci "test_logic.us", 54fb299fa2Sopenharmony_ci "testscript.us", 55fb299fa2Sopenharmony_ci "test_math.us", 56fb299fa2Sopenharmony_ci "test_native.us", 57fb299fa2Sopenharmony_ci "Verse-script.us", 58fb299fa2Sopenharmony_ci "test_script.us" 59fb299fa2Sopenharmony_ci }; 60fb299fa2Sopenharmony_ci if (std::find(testFileNames.begin(), testFileNames.end(), fileId) != testFileNames.end()) { 61fb299fa2Sopenharmony_ci return &fileInfo; 62fb299fa2Sopenharmony_ci } 63fb299fa2Sopenharmony_ci if (fileId == "hash_signed_data") { 64fb299fa2Sopenharmony_ci fileInfo.unpackedSize = GetFileSize(FUZZ_TEST_PATH_FROM + fileId); 65fb299fa2Sopenharmony_ci return &fileInfo; 66fb299fa2Sopenharmony_ci } 67fb299fa2Sopenharmony_ci return nullptr; 68fb299fa2Sopenharmony_ci } 69fb299fa2Sopenharmony_ci int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer) override 70fb299fa2Sopenharmony_ci { 71fb299fa2Sopenharmony_ci PKG_LOGI("create pkg stream success for %s ", fileName.c_str()); 72fb299fa2Sopenharmony_ci stream = new MemoryMapStream(this, fileName, buffer, PkgStream::PkgStreamType_Buffer); 73fb299fa2Sopenharmony_ci return PKG_SUCCESS; 74fb299fa2Sopenharmony_ci } 75fb299fa2Sopenharmony_ci int32_t ExtractFile(const std::string &fileId, StreamPtr output) override 76fb299fa2Sopenharmony_ci { 77fb299fa2Sopenharmony_ci if (fileId != "hash_signed_data") { 78fb299fa2Sopenharmony_ci return PKG_SUCCESS; 79fb299fa2Sopenharmony_ci } 80fb299fa2Sopenharmony_ci if (output == nullptr) { 81fb299fa2Sopenharmony_ci return PKG_INVALID_STREAM; 82fb299fa2Sopenharmony_ci } 83fb299fa2Sopenharmony_ci auto fd = open((FUZZ_TEST_PATH_FROM + fileId).c_str(), O_RDWR); 84fb299fa2Sopenharmony_ci if (fd == -1) { 85fb299fa2Sopenharmony_ci PKG_LOGE("file %s not existed", (FUZZ_TEST_PATH_FROM + fileId).c_str()); 86fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 87fb299fa2Sopenharmony_ci } 88fb299fa2Sopenharmony_ci ON_SCOPE_EXIT(close) { 89fb299fa2Sopenharmony_ci close(fd); 90fb299fa2Sopenharmony_ci }; 91fb299fa2Sopenharmony_ci std::string content {}; 92fb299fa2Sopenharmony_ci if (!Utils::ReadFileToString(fd, content)) { 93fb299fa2Sopenharmony_ci PKG_LOGE("read file to string failed"); 94fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 95fb299fa2Sopenharmony_ci } 96fb299fa2Sopenharmony_ci auto stream = static_cast<MemoryMapStream *>(output); 97fb299fa2Sopenharmony_ci PkgBuffer buffer = {}; 98fb299fa2Sopenharmony_ci stream->GetBuffer(buffer); 99fb299fa2Sopenharmony_ci if (content.size() + 1 != buffer.length) { 100fb299fa2Sopenharmony_ci PKG_LOGE("content size is not valid, %u != %u", content.size(), buffer.data.size()); 101fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 102fb299fa2Sopenharmony_ci } 103fb299fa2Sopenharmony_ci std::copy(content.begin(), content.end(), buffer.buffer); 104fb299fa2Sopenharmony_ci return PKG_SUCCESS; 105fb299fa2Sopenharmony_ci } 106fb299fa2Sopenharmony_ci int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, 107fb299fa2Sopenharmony_ci size_t size, int32_t type) override 108fb299fa2Sopenharmony_ci { 109fb299fa2Sopenharmony_ci FILE *file = nullptr; 110fb299fa2Sopenharmony_ci std::string realFileName = fileName; 111fb299fa2Sopenharmony_ci auto pos = fileName.rfind('/'); 112fb299fa2Sopenharmony_ci if (pos != std::string::npos) { 113fb299fa2Sopenharmony_ci realFileName = fileName.substr(pos + 1); 114fb299fa2Sopenharmony_ci } 115fb299fa2Sopenharmony_ci char realPath[PATH_MAX + 1] = {}; 116fb299fa2Sopenharmony_ci if (realpath((FUZZ_TEST_PATH_FROM + realFileName).c_str(), realPath) == nullptr) { 117fb299fa2Sopenharmony_ci LOG(ERROR) << (FUZZ_TEST_PATH_FROM + realFileName) << " realpath failed"; 118fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 119fb299fa2Sopenharmony_ci } 120fb299fa2Sopenharmony_ci file = fopen(realPath, "rb"); 121fb299fa2Sopenharmony_ci if (file != nullptr) { 122fb299fa2Sopenharmony_ci stream = new FileStream(this, realFileName, file, PkgStream::PkgStreamType_Read); 123fb299fa2Sopenharmony_ci return USCRIPT_SUCCESS; 124fb299fa2Sopenharmony_ci } 125fb299fa2Sopenharmony_ci PKG_LOGE("Fail to open file %s ", realFileName.c_str()); 126fb299fa2Sopenharmony_ci return PKG_INVALID_FILE; 127fb299fa2Sopenharmony_ci } 128fb299fa2Sopenharmony_ci void ClosePkgStream(StreamPtr &stream) override 129fb299fa2Sopenharmony_ci { 130fb299fa2Sopenharmony_ci delete stream; 131fb299fa2Sopenharmony_ci } 132fb299fa2Sopenharmony_ci}; 133fb299fa2Sopenharmony_ci 134fb299fa2Sopenharmony_ciclass FuzzTestScriptInstructionSparseImageWrite : public Uscript::UScriptInstruction { 135fb299fa2Sopenharmony_cipublic: 136fb299fa2Sopenharmony_ci FuzzTestScriptInstructionSparseImageWrite() {} 137fb299fa2Sopenharmony_ci virtual ~FuzzTestScriptInstructionSparseImageWrite() {} 138fb299fa2Sopenharmony_ci int32_t Execute(Uscript::UScriptEnv &env, Uscript::UScriptContext &context) override 139fb299fa2Sopenharmony_ci { 140fb299fa2Sopenharmony_ci std::string partitionName = {}; 141fb299fa2Sopenharmony_ci int32_t ret = context.GetParam(0, partitionName); 142fb299fa2Sopenharmony_ci if (ret != USCRIPT_SUCCESS) { 143fb299fa2Sopenharmony_ci LOG(ERROR) << "Error to get param"; 144fb299fa2Sopenharmony_ci return ret; 145fb299fa2Sopenharmony_ci } 146fb299fa2Sopenharmony_ci LOG(INFO) << "UScriptInstructionSparseImageWrite::Execute " << partitionName; 147fb299fa2Sopenharmony_ci if (env.GetPkgManager() != nullptr) { 148fb299fa2Sopenharmony_ci return ret; 149fb299fa2Sopenharmony_ci } 150fb299fa2Sopenharmony_ci LOG(ERROR) << "Error to get pkg manager"; 151fb299fa2Sopenharmony_ci return USCRIPT_ERROR_EXECUTE; 152fb299fa2Sopenharmony_ci } 153fb299fa2Sopenharmony_ci}; 154fb299fa2Sopenharmony_ci 155fb299fa2Sopenharmony_ciclass FuzzTestScriptInstructionFactory : public UScriptInstructionFactory { 156fb299fa2Sopenharmony_cipublic: 157fb299fa2Sopenharmony_ci virtual int32_t CreateInstructionInstance(UScriptInstructionPtr& instr, const std::string& name) 158fb299fa2Sopenharmony_ci { 159fb299fa2Sopenharmony_ci if (name == "sparse_image_write") { 160fb299fa2Sopenharmony_ci instr = new (std::nothrow) FuzzTestScriptInstructionSparseImageWrite(); 161fb299fa2Sopenharmony_ci } 162fb299fa2Sopenharmony_ci return USCRIPT_SUCCESS; 163fb299fa2Sopenharmony_ci } 164fb299fa2Sopenharmony_ci virtual void DestoryInstructionInstance(UScriptInstructionPtr& instr) 165fb299fa2Sopenharmony_ci { 166fb299fa2Sopenharmony_ci delete instr; 167fb299fa2Sopenharmony_ci instr = nullptr; 168fb299fa2Sopenharmony_ci } 169fb299fa2Sopenharmony_ci FuzzTestScriptInstructionFactory() {} 170fb299fa2Sopenharmony_ci virtual ~FuzzTestScriptInstructionFactory() {} 171fb299fa2Sopenharmony_ci}; 172fb299fa2Sopenharmony_ci 173fb299fa2Sopenharmony_ciclass FuzzTestScriptEnv : public UScriptEnv { 174fb299fa2Sopenharmony_cipublic: 175fb299fa2Sopenharmony_ci explicit FuzzTestScriptEnv(Hpackage::PkgManager::PkgManagerPtr pkgManager) : UScriptEnv(pkgManager) {} 176fb299fa2Sopenharmony_ci ~FuzzTestScriptEnv() 177fb299fa2Sopenharmony_ci { 178fb299fa2Sopenharmony_ci if (factory_ != nullptr) { 179fb299fa2Sopenharmony_ci delete factory_; 180fb299fa2Sopenharmony_ci factory_ = nullptr; 181fb299fa2Sopenharmony_ci } 182fb299fa2Sopenharmony_ci } 183fb299fa2Sopenharmony_ci 184fb299fa2Sopenharmony_ci virtual UScriptInstructionFactoryPtr GetInstructionFactory() 185fb299fa2Sopenharmony_ci { 186fb299fa2Sopenharmony_ci if (factory_ == nullptr) { 187fb299fa2Sopenharmony_ci factory_ = new FuzzTestScriptInstructionFactory(); 188fb299fa2Sopenharmony_ci } 189fb299fa2Sopenharmony_ci return factory_; 190fb299fa2Sopenharmony_ci } 191fb299fa2Sopenharmony_ci 192fb299fa2Sopenharmony_ci virtual void PostMessage(const std::string &cmd, std::string content) {} 193fb299fa2Sopenharmony_ci 194fb299fa2Sopenharmony_ci virtual const std::vector<std::string> GetInstructionNames() const 195fb299fa2Sopenharmony_ci { 196fb299fa2Sopenharmony_ci return {"sparse_image_write"}; 197fb299fa2Sopenharmony_ci } 198fb299fa2Sopenharmony_ci 199fb299fa2Sopenharmony_ci virtual bool IsRetry() const 200fb299fa2Sopenharmony_ci { 201fb299fa2Sopenharmony_ci return isRetry; 202fb299fa2Sopenharmony_ci } 203fb299fa2Sopenharmony_ci 204fb299fa2Sopenharmony_ci virtual PostMessageFunction GetPostmsgFunc() 205fb299fa2Sopenharmony_ci { 206fb299fa2Sopenharmony_ci return nullptr; 207fb299fa2Sopenharmony_ci } 208fb299fa2Sopenharmony_ci UScriptInstructionFactory *factory_ = nullptr; 209fb299fa2Sopenharmony_ciprivate: 210fb299fa2Sopenharmony_ci bool isRetry = false; 211fb299fa2Sopenharmony_ci}; 212fb299fa2Sopenharmony_ci 213fb299fa2Sopenharmony_ciclass FuzzScriptTest { 214fb299fa2Sopenharmony_cipublic: 215fb299fa2Sopenharmony_ci FuzzScriptTest() 216fb299fa2Sopenharmony_ci { 217fb299fa2Sopenharmony_ci InitUpdaterLogger("UPDATER", "updater_log.log", "updater_status.log", "error_code.log"); 218fb299fa2Sopenharmony_ci } 219fb299fa2Sopenharmony_ci 220fb299fa2Sopenharmony_ci ~FuzzScriptTest() 221fb299fa2Sopenharmony_ci { 222fb299fa2Sopenharmony_ci ScriptManager::ReleaseScriptManager(); 223fb299fa2Sopenharmony_ci } 224fb299fa2Sopenharmony_ci 225fb299fa2Sopenharmony_ci int TestUscriptExecute(std::string &path) 226fb299fa2Sopenharmony_ci { 227fb299fa2Sopenharmony_ci int32_t ret {}; 228fb299fa2Sopenharmony_ci TestPkgManager packageManager; 229fb299fa2Sopenharmony_ci auto env = std::make_unique<FuzzTestScriptEnv>(&packageManager); 230fb299fa2Sopenharmony_ci HashDataVerifier verifier {&packageManager}; 231fb299fa2Sopenharmony_ci verifier.LoadHashDataAndPkcs7(path); 232fb299fa2Sopenharmony_ci ScriptManager *manager = ScriptManager::GetScriptManager(env.get(), &verifier); 233fb299fa2Sopenharmony_ci if (manager == nullptr) { 234fb299fa2Sopenharmony_ci USCRIPT_LOGI("create manager fail ret:%d", ret); 235fb299fa2Sopenharmony_ci return USCRIPT_INVALID_SCRIPT; 236fb299fa2Sopenharmony_ci } 237fb299fa2Sopenharmony_ci for (auto priority : {SCRIPT_TEST_PRIORITY_NUM, 0, 1, SCRIPT_TEST_LAST_PRIORITY}) { 238fb299fa2Sopenharmony_ci ret = manager->ExecuteScript(priority); 239fb299fa2Sopenharmony_ci USCRIPT_LOGI("ExecuteScript ret:%d", ret); 240fb299fa2Sopenharmony_ci } 241fb299fa2Sopenharmony_ci ScriptManager::ReleaseScriptManager(); 242fb299fa2Sopenharmony_ci return ret; 243fb299fa2Sopenharmony_ci } 244fb299fa2Sopenharmony_ci 245fb299fa2Sopenharmony_ciprotected: 246fb299fa2Sopenharmony_ci void SetUp() {} 247fb299fa2Sopenharmony_ci void TearDown() {} 248fb299fa2Sopenharmony_ci void TestBody() {} 249fb299fa2Sopenharmony_ci 250fb299fa2Sopenharmony_ciprivate: 251fb299fa2Sopenharmony_ci std::vector<std::string> testFileNames_ = { 252fb299fa2Sopenharmony_ci "loadScript.us", 253fb299fa2Sopenharmony_ci "registerCmd.us", 254fb299fa2Sopenharmony_ci "test_function.us", 255fb299fa2Sopenharmony_ci "test_math.us", 256fb299fa2Sopenharmony_ci "test_logic.us", 257fb299fa2Sopenharmony_ci "test_native.us", 258fb299fa2Sopenharmony_ci "test_script.us" 259fb299fa2Sopenharmony_ci "test_if.us", 260fb299fa2Sopenharmony_ci "testscript.us", 261fb299fa2Sopenharmony_ci "Verse-script.us", 262fb299fa2Sopenharmony_ci }; 263fb299fa2Sopenharmony_ci}; 264fb299fa2Sopenharmony_ci 265fb299fa2Sopenharmony_civoid FuzzScriptManager(const uint8_t *data, size_t size) 266fb299fa2Sopenharmony_ci{ 267fb299fa2Sopenharmony_ci FuzzScriptTest test; 268fb299fa2Sopenharmony_ci std::string path = std::string(reinterpret_cast<const char*>(data), size); 269fb299fa2Sopenharmony_ci test.TestUscriptExecute(path); 270fb299fa2Sopenharmony_ci} 271fb299fa2Sopenharmony_ci} 272fb299fa2Sopenharmony_ci 273fb299fa2Sopenharmony_ci/* Fuzzer entry point */ 274fb299fa2Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 275fb299fa2Sopenharmony_ci{ 276fb299fa2Sopenharmony_ci /* Run your code on data */ 277fb299fa2Sopenharmony_ci OHOS::FuzzScriptManager(data, size); 278fb299fa2Sopenharmony_ci return 0; 279fb299fa2Sopenharmony_ci} 280fb299fa2Sopenharmony_ci 281