1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "faultloggerdunwinder_fuzzer.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <cstddef> 19800b99b8Sopenharmony_ci#include <cstdint> 20800b99b8Sopenharmony_ci 21800b99b8Sopenharmony_ci#include "dfx_ark.h" 22800b99b8Sopenharmony_ci#include "dfx_config.h" 23800b99b8Sopenharmony_ci#include "dfx_hap.h" 24800b99b8Sopenharmony_ci#include "dfx_regs.h" 25800b99b8Sopenharmony_ci#include "dfx_xz_utils.h" 26800b99b8Sopenharmony_ci#include "dwarf_op.h" 27800b99b8Sopenharmony_ci#include "faultloggerd_fuzzertest_common.h" 28800b99b8Sopenharmony_ci#include "thread_context.h" 29800b99b8Sopenharmony_ci#include "unwinder.h" 30800b99b8Sopenharmony_ci 31800b99b8Sopenharmony_cinamespace OHOS { 32800b99b8Sopenharmony_cinamespace HiviewDFX { 33800b99b8Sopenharmony_ciconst int FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH = 50; 34800b99b8Sopenharmony_ci 35800b99b8Sopenharmony_civoid TestDfxConfig() 36800b99b8Sopenharmony_ci{ 37800b99b8Sopenharmony_ci DfxConfig::GetConfig(); 38800b99b8Sopenharmony_ci} 39800b99b8Sopenharmony_ci 40800b99b8Sopenharmony_civoid TestGetArkNativeFrameInfo(const uint8_t* data, size_t size) 41800b99b8Sopenharmony_ci{ 42800b99b8Sopenharmony_ci int pid; 43800b99b8Sopenharmony_ci uintptr_t pc; 44800b99b8Sopenharmony_ci uintptr_t fp; 45800b99b8Sopenharmony_ci uintptr_t sp; 46800b99b8Sopenharmony_ci int offsetTotalLength = sizeof(pid) + sizeof(pc) + sizeof(fp) + sizeof(sp); 47800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 48800b99b8Sopenharmony_ci return; 49800b99b8Sopenharmony_ci } 50800b99b8Sopenharmony_ci 51800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pid); 52800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pc); 53800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, fp); 54800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, sp); 55800b99b8Sopenharmony_ci 56800b99b8Sopenharmony_ci const size_t jSFRAME_MAX = 64; 57800b99b8Sopenharmony_ci JsFrame jsFrames[jSFRAME_MAX]; 58800b99b8Sopenharmony_ci 59800b99b8Sopenharmony_ci DfxArk::GetArkNativeFrameInfo(pid, pc, fp, sp, jsFrames, size); 60800b99b8Sopenharmony_ci} 61800b99b8Sopenharmony_ci 62800b99b8Sopenharmony_civoid TestStepArkFrame(const uint8_t* data, size_t size) 63800b99b8Sopenharmony_ci{ 64800b99b8Sopenharmony_ci uintptr_t pc; 65800b99b8Sopenharmony_ci uintptr_t fp; 66800b99b8Sopenharmony_ci uintptr_t sp; 67800b99b8Sopenharmony_ci uintptr_t methodid; 68800b99b8Sopenharmony_ci int offsetTotalLength = sizeof(pc) + sizeof(fp) + sizeof(sp) + sizeof(methodid); 69800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 70800b99b8Sopenharmony_ci return; 71800b99b8Sopenharmony_ci } 72800b99b8Sopenharmony_ci 73800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pc); 74800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, fp); 75800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, sp); 76800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, methodid); 77800b99b8Sopenharmony_ci bool isJsFrame = methodid % 2; 78800b99b8Sopenharmony_ci 79800b99b8Sopenharmony_ci DfxMemory dfxMemory; 80800b99b8Sopenharmony_ci DfxArk::StepArkFrame(&dfxMemory, &(Unwinder::AccessMem), &fp, &sp, &pc, &methodid, &isJsFrame); 81800b99b8Sopenharmony_ci} 82800b99b8Sopenharmony_ci 83800b99b8Sopenharmony_civoid TestStepArkFrameWithJit(const uint8_t* data, size_t size) 84800b99b8Sopenharmony_ci{ 85800b99b8Sopenharmony_ci uintptr_t fp; 86800b99b8Sopenharmony_ci uintptr_t pc; 87800b99b8Sopenharmony_ci uintptr_t sp; 88800b99b8Sopenharmony_ci uintptr_t methodid; 89800b99b8Sopenharmony_ci int offsetTotalLength = sizeof(pc) + sizeof(fp) + sizeof(sp) + sizeof(methodid); 90800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 91800b99b8Sopenharmony_ci return; 92800b99b8Sopenharmony_ci } 93800b99b8Sopenharmony_ci 94800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pc); 95800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, fp); 96800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, sp); 97800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, methodid); 98800b99b8Sopenharmony_ci bool isJsFrame = methodid % 2; 99800b99b8Sopenharmony_ci 100800b99b8Sopenharmony_ci std::vector<uintptr_t> jitCache_ = {}; 101800b99b8Sopenharmony_ci DfxMemory dfxMemory; 102800b99b8Sopenharmony_ci ArkUnwindParam arkParam(&dfxMemory, &(Unwinder::AccessMem), &fp, &sp, &pc, &methodid, &isJsFrame, jitCache_); 103800b99b8Sopenharmony_ci DfxArk::StepArkFrameWithJit(&arkParam); 104800b99b8Sopenharmony_ci} 105800b99b8Sopenharmony_ci 106800b99b8Sopenharmony_civoid TestJitCodeWriteFile(const uint8_t* data, size_t size) 107800b99b8Sopenharmony_ci{ 108800b99b8Sopenharmony_ci int fd; 109800b99b8Sopenharmony_ci uintptr_t jitCacheData; 110800b99b8Sopenharmony_ci int offsetTotalLength = sizeof(fd) + sizeof(jitCacheData); 111800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 112800b99b8Sopenharmony_ci return; 113800b99b8Sopenharmony_ci } 114800b99b8Sopenharmony_ci 115800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, fd); 116800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, jitCacheData); 117800b99b8Sopenharmony_ci 118800b99b8Sopenharmony_ci std::vector<uintptr_t> jitCache = {}; 119800b99b8Sopenharmony_ci jitCache.push_back(jitCacheData); 120800b99b8Sopenharmony_ci DfxMemory dfxMemory; 121800b99b8Sopenharmony_ci DfxArk::JitCodeWriteFile(&dfxMemory, &(Unwinder::AccessMem), fd, jitCache.data(), jitCache.size()); 122800b99b8Sopenharmony_ci} 123800b99b8Sopenharmony_ci 124800b99b8Sopenharmony_civoid TestParseArkFrameInfoLocal(const uint8_t* data, size_t size) 125800b99b8Sopenharmony_ci{ 126800b99b8Sopenharmony_ci uintptr_t pc; 127800b99b8Sopenharmony_ci uintptr_t funcOffset; 128800b99b8Sopenharmony_ci uintptr_t mapBegin; 129800b99b8Sopenharmony_ci uintptr_t offset; 130800b99b8Sopenharmony_ci int offsetTotalLength = sizeof(pc) + sizeof(funcOffset) + sizeof(mapBegin) + sizeof(offset); 131800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 132800b99b8Sopenharmony_ci return; 133800b99b8Sopenharmony_ci } 134800b99b8Sopenharmony_ci 135800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pc); 136800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, funcOffset); 137800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, mapBegin); 138800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, offset); 139800b99b8Sopenharmony_ci 140800b99b8Sopenharmony_ci JsFunction jsFunction; 141800b99b8Sopenharmony_ci DfxArk::ParseArkFrameInfoLocal(static_cast<uintptr_t>(pc), static_cast<uintptr_t>(funcOffset), 142800b99b8Sopenharmony_ci static_cast<uintptr_t>(mapBegin), static_cast<uintptr_t>(offset), &jsFunction); 143800b99b8Sopenharmony_ci} 144800b99b8Sopenharmony_ci 145800b99b8Sopenharmony_civoid TestArkCreateJsSymbolExtractor(const uint8_t* data, size_t size) 146800b99b8Sopenharmony_ci{ 147800b99b8Sopenharmony_ci uintptr_t extractorPtr; 148800b99b8Sopenharmony_ci if (size < sizeof(extractorPtr)) { 149800b99b8Sopenharmony_ci return; 150800b99b8Sopenharmony_ci } 151800b99b8Sopenharmony_ci 152800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, extractorPtr); 153800b99b8Sopenharmony_ci 154800b99b8Sopenharmony_ci DfxArk::ArkCreateJsSymbolExtractor(&extractorPtr); 155800b99b8Sopenharmony_ci} 156800b99b8Sopenharmony_ci 157800b99b8Sopenharmony_civoid TestArkDestoryJsSymbolExtractor(const uint8_t* data, size_t size) 158800b99b8Sopenharmony_ci{ 159800b99b8Sopenharmony_ci uintptr_t extractorPtr; 160800b99b8Sopenharmony_ci if (size < sizeof(extractorPtr)) { 161800b99b8Sopenharmony_ci return; 162800b99b8Sopenharmony_ci } 163800b99b8Sopenharmony_ci 164800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, extractorPtr); 165800b99b8Sopenharmony_ci 166800b99b8Sopenharmony_ci DfxArk::ArkDestoryJsSymbolExtractor(extractorPtr); 167800b99b8Sopenharmony_ci} 168800b99b8Sopenharmony_ci 169800b99b8Sopenharmony_civoid TestDfxArk(const uint8_t* data, size_t size) 170800b99b8Sopenharmony_ci{ 171800b99b8Sopenharmony_ci TestGetArkNativeFrameInfo(data, size); 172800b99b8Sopenharmony_ci TestStepArkFrame(data, size); 173800b99b8Sopenharmony_ci TestStepArkFrameWithJit(data, size); 174800b99b8Sopenharmony_ci TestJitCodeWriteFile(data, size); 175800b99b8Sopenharmony_ci TestParseArkFrameInfoLocal(data, size); 176800b99b8Sopenharmony_ci TestArkCreateJsSymbolExtractor(data, size); 177800b99b8Sopenharmony_ci} 178800b99b8Sopenharmony_ci 179800b99b8Sopenharmony_civoid TestDfxHap(const uint8_t* data, size_t size) 180800b99b8Sopenharmony_ci{ 181800b99b8Sopenharmony_ci pid_t pid; 182800b99b8Sopenharmony_ci uint64_t pc; 183800b99b8Sopenharmony_ci uintptr_t methodid; 184800b99b8Sopenharmony_ci uintptr_t offset; 185800b99b8Sopenharmony_ci unsigned int offsetTotalLength = sizeof(pid) + sizeof(pc) + sizeof(methodid) + sizeof(offset); 186800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 187800b99b8Sopenharmony_ci return; 188800b99b8Sopenharmony_ci } 189800b99b8Sopenharmony_ci 190800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pid); 191800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, pc); 192800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, methodid); 193800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, offset); 194800b99b8Sopenharmony_ci 195800b99b8Sopenharmony_ci auto map = std::make_shared<DfxMap>(); 196800b99b8Sopenharmony_ci JsFunction jsFunction; 197800b99b8Sopenharmony_ci DfxHap dfxHap; 198800b99b8Sopenharmony_ci dfxHap.ParseHapInfo(pid, pc, methodid, map, &jsFunction); 199800b99b8Sopenharmony_ci} 200800b99b8Sopenharmony_ci 201800b99b8Sopenharmony_ci#if defined(__aarch64__) 202800b99b8Sopenharmony_civoid TestSetFromFpMiniRegs(const uint8_t* data, size_t size) 203800b99b8Sopenharmony_ci{ 204800b99b8Sopenharmony_ci uintptr_t regs; 205800b99b8Sopenharmony_ci if (size < sizeof(regs)) { 206800b99b8Sopenharmony_ci return; 207800b99b8Sopenharmony_ci } 208800b99b8Sopenharmony_ci 209800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, regs); 210800b99b8Sopenharmony_ci 211800b99b8Sopenharmony_ci auto dfxregs = std::make_shared<DfxRegsArm64>(); 212800b99b8Sopenharmony_ci dfxregs->SetFromFpMiniRegs(®s, size); 213800b99b8Sopenharmony_ci} 214800b99b8Sopenharmony_ci#endif 215800b99b8Sopenharmony_ci 216800b99b8Sopenharmony_ci#if defined(__aarch64__) 217800b99b8Sopenharmony_civoid TestSetFromQutMiniRegs(const uint8_t* data, size_t size) 218800b99b8Sopenharmony_ci{ 219800b99b8Sopenharmony_ci uintptr_t regs; 220800b99b8Sopenharmony_ci if (size < sizeof(regs)) { 221800b99b8Sopenharmony_ci return; 222800b99b8Sopenharmony_ci } 223800b99b8Sopenharmony_ci 224800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, regs); 225800b99b8Sopenharmony_ci 226800b99b8Sopenharmony_ci auto dfxregs = std::make_shared<DfxRegsArm64>(); 227800b99b8Sopenharmony_ci dfxregs->SetFromQutMiniRegs(®s, size); 228800b99b8Sopenharmony_ci} 229800b99b8Sopenharmony_ci#endif 230800b99b8Sopenharmony_ci 231800b99b8Sopenharmony_ci#if defined(__aarch64__) 232800b99b8Sopenharmony_civoid TestDfxRegsArm64(const uint8_t* data, size_t size) 233800b99b8Sopenharmony_ci{ 234800b99b8Sopenharmony_ci TestSetFromFpMiniRegs(data, size); 235800b99b8Sopenharmony_ci TestSetFromQutMiniRegs(data, size); 236800b99b8Sopenharmony_ci} 237800b99b8Sopenharmony_ci#endif 238800b99b8Sopenharmony_ci 239800b99b8Sopenharmony_civoid TestThreadContext(const uint8_t* data, size_t size) 240800b99b8Sopenharmony_ci{ 241800b99b8Sopenharmony_ci int32_t tid; 242800b99b8Sopenharmony_ci uintptr_t stackBottom; 243800b99b8Sopenharmony_ci uintptr_t stackTop; 244800b99b8Sopenharmony_ci unsigned int offsetTotalLength = sizeof(tid) + sizeof(stackBottom) + sizeof(stackTop); 245800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 246800b99b8Sopenharmony_ci return; 247800b99b8Sopenharmony_ci } 248800b99b8Sopenharmony_ci 249800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, tid); 250800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, stackBottom); 251800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, stackTop); 252800b99b8Sopenharmony_ci 253800b99b8Sopenharmony_ci LocalThreadContext& context = LocalThreadContext::GetInstance(); 254800b99b8Sopenharmony_ci context.GetStackRange(tid, stackBottom, stackTop); 255800b99b8Sopenharmony_ci context.CollectThreadContext(tid); 256800b99b8Sopenharmony_ci context.GetThreadContext(tid); 257800b99b8Sopenharmony_ci context.ReleaseThread(tid); 258800b99b8Sopenharmony_ci} 259800b99b8Sopenharmony_ci 260800b99b8Sopenharmony_civoid TestDfxInstrStatistic(const uint8_t* data, size_t size) 261800b99b8Sopenharmony_ci{ 262800b99b8Sopenharmony_ci uint32_t type; 263800b99b8Sopenharmony_ci uint64_t val; 264800b99b8Sopenharmony_ci uint64_t errInfo; 265800b99b8Sopenharmony_ci unsigned int offsetTotalLength = sizeof(type) + sizeof(val) + sizeof(errInfo) + 266800b99b8Sopenharmony_ci FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH; 267800b99b8Sopenharmony_ci if (offsetTotalLength > size) { 268800b99b8Sopenharmony_ci return; 269800b99b8Sopenharmony_ci } 270800b99b8Sopenharmony_ci 271800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, type); 272800b99b8Sopenharmony_ci type = type % 10; // 10 : get the last digit of the number 273800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, val); 274800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, errInfo); 275800b99b8Sopenharmony_ci 276800b99b8Sopenharmony_ci std::string soName(reinterpret_cast<const char*>(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH); 277800b99b8Sopenharmony_ci data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH; 278800b99b8Sopenharmony_ci 279800b99b8Sopenharmony_ci InstrStatisticType statisticType; 280800b99b8Sopenharmony_ci if (type == 0) { 281800b99b8Sopenharmony_ci statisticType = InstrStatisticType::InstructionEntriesArmExidx; 282800b99b8Sopenharmony_ci } else { 283800b99b8Sopenharmony_ci statisticType = InstrStatisticType::UnsupportedArmExidx; 284800b99b8Sopenharmony_ci } 285800b99b8Sopenharmony_ci DfxInstrStatistic& statistic = DfxInstrStatistic::GetInstance(); 286800b99b8Sopenharmony_ci statistic.SetCurrentStatLib(soName); 287800b99b8Sopenharmony_ci statistic.AddInstrStatistic(statisticType, val, errInfo); 288800b99b8Sopenharmony_ci std::vector<std::pair<uint32_t, uint32_t>> result; 289800b99b8Sopenharmony_ci statistic.DumpInstrStatResult(result); 290800b99b8Sopenharmony_ci} 291800b99b8Sopenharmony_ci 292800b99b8Sopenharmony_civoid TestDfxXzUtils(const uint8_t* data, size_t size) 293800b99b8Sopenharmony_ci{ 294800b99b8Sopenharmony_ci uint8_t src; 295800b99b8Sopenharmony_ci if (size < sizeof(src)) { 296800b99b8Sopenharmony_ci return; 297800b99b8Sopenharmony_ci } 298800b99b8Sopenharmony_ci 299800b99b8Sopenharmony_ci STREAM_TO_VALUEINFO(data, src); 300800b99b8Sopenharmony_ci 301800b99b8Sopenharmony_ci std::shared_ptr<std::vector<uint8_t>> out; 302800b99b8Sopenharmony_ci XzDecompress(&src, size, out); 303800b99b8Sopenharmony_ci} 304800b99b8Sopenharmony_ci 305800b99b8Sopenharmony_civoid FaultloggerdUnwinderTest(const uint8_t* data, size_t size) 306800b99b8Sopenharmony_ci{ 307800b99b8Sopenharmony_ci TestDfxConfig(); 308800b99b8Sopenharmony_ci TestDfxArk(data, size); 309800b99b8Sopenharmony_ci TestDfxHap(data, size); 310800b99b8Sopenharmony_ci#if defined(__aarch64__) 311800b99b8Sopenharmony_ci TestDfxRegsArm64(data, size); 312800b99b8Sopenharmony_ci#endif 313800b99b8Sopenharmony_ci TestThreadContext(data, size); 314800b99b8Sopenharmony_ci TestDfxInstrStatistic(data, size); 315800b99b8Sopenharmony_ci TestDfxXzUtils(data, size); 316800b99b8Sopenharmony_ci sleep(1); 317800b99b8Sopenharmony_ci} 318800b99b8Sopenharmony_ci} // namespace HiviewDFX 319800b99b8Sopenharmony_ci} // namespace OHOS 320800b99b8Sopenharmony_ci 321800b99b8Sopenharmony_ci/* Fuzzer entry point */ 322800b99b8Sopenharmony_ciextern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) 323800b99b8Sopenharmony_ci{ 324800b99b8Sopenharmony_ci if (data == nullptr || size == 0) { 325800b99b8Sopenharmony_ci return 0; 326800b99b8Sopenharmony_ci } 327800b99b8Sopenharmony_ci 328800b99b8Sopenharmony_ci /* Run your code on data */ 329800b99b8Sopenharmony_ci OHOS::HiviewDFX::FaultloggerdUnwinderTest(data, size); 330800b99b8Sopenharmony_ci return 0; 331800b99b8Sopenharmony_ci} 332