/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include "../MemoryFake.h" #include "UnwinderComponentCreator.h" #include "fuzzer/FuzzedDataProvider.h" namespace unwindstack { static constexpr int kMaxUnwindStringLen = 50; static constexpr int kMaxUnwindStrings = 50; void PerformUnwind(FuzzedDataProvider* data_provider, Unwinder* unwinder) { // 0 = don't set any values // 1 = set initial_map_names_to_skip // 2 = set map_suffixes_to_ignore // 3 = set both uint8_t set_values = data_provider->ConsumeIntegral() % 4; if (set_values == 0) { unwinder->Unwind(); } else if (set_values == 1) { // Only setting initial_map_names_to_skip std::vector skip_names = GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings); unwinder->Unwind(&skip_names, nullptr); } else if (set_values == 2) { // Only setting map_suffixes_to_ignore std::vector ignore_suffixes = GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings); unwinder->Unwind(nullptr, &ignore_suffixes); } else if (set_values == 3) { // Setting both values std::vector skip_names = GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings); std::vector ignore_suffixes = GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings); unwinder->Unwind(&skip_names, &ignore_suffixes); } } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { FuzzedDataProvider data_provider(data, size); // We need to construct an unwinder. // Generate the Maps: std::unique_ptr maps = GetMaps(&data_provider); // Generate the Regs: uint8_t arch_val = data_provider.ConsumeIntegralInRange(1, kArchCount); ArchEnum arch = static_cast(arch_val); std::unique_ptr regs = GetRegisters(arch); // Generate memory: std::shared_ptr memory = std::make_shared(); PutElfFilesInMemory(reinterpret_cast(memory.get()), &data_provider); size_t max_frames = data_provider.ConsumeIntegralInRange(0, 5000); std::unique_ptr jit_debug_ptr = CreateJitDebug(arch, memory); // Create instance Unwinder unwinder(max_frames, maps.get(), regs.get(), memory); unwinder.SetJitDebug(jit_debug_ptr.get()); unwinder.SetResolveNames(data_provider.ConsumeBool()); // Call unwind PerformUnwind(&data_provider, &unwinder); // Run some additional logic that changes after unwind uint64_t pc = data_provider.ConsumeIntegral(); unwinder.BuildFrameFromPcOnly(pc); unwinder.ConsumeFrames(); return 0; } } // namespace unwindstack