From cb898b4f2f0cedfa7674f5b5cdcf2963dce377e4 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 30 Oct 2024 11:22:20 -0700 Subject: [PATCH 1/2] [lldb] Add a fuzzer for the DWARF Expression Evaluator This adds a fuzzer for the DWARF expression evaluator. It does pretty much the same thing as what we do in the corresponding unit test but with data generated by libfuzzer. --- lldb/tools/lldb-fuzzer/CMakeLists.txt | 1 + .../CMakeLists.txt | 34 ++++++++ .../lldb-dwarf-expression-fuzzer.cpp | 83 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt create mode 100644 lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp diff --git a/lldb/tools/lldb-fuzzer/CMakeLists.txt b/lldb/tools/lldb-fuzzer/CMakeLists.txt index 4c081a9de53e2..e384ca1858398 100644 --- a/lldb/tools/lldb-fuzzer/CMakeLists.txt +++ b/lldb/tools/lldb-fuzzer/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(lldb-commandinterpreter-fuzzer) +add_subdirectory(lldb-dwarf-expression-fuzzer) add_subdirectory(lldb-expression-fuzzer) add_subdirectory(lldb-target-fuzzer) add_subdirectory(utils) diff --git a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt new file mode 100644 index 0000000000000..374a80b7bb83a --- /dev/null +++ b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt @@ -0,0 +1,34 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_llvm_fuzzer(lldb-dwarf-expression-fuzzer + EXCLUDE_FROM_ALL + lldb-dwarf-expression-fuzzer.cpp + ) + +include_directories(${LLDB_SOURCE_ROOT}) + +if(TARGET lldb-dwarf-expression-fuzzer) + target_include_directories(lldb-dwarf-expression-fuzzer PRIVATE ..) + target_link_libraries(lldb-dwarf-expression-fuzzer + PRIVATE + lldbCore + lldbPluginExpressionParserClang + lldbPluginPlatformLinux + lldbPluginTypeSystemClang + lldbFuzzerUtils + ) + + add_custom_command(TARGET lldb-dwarf-expression-fuzzer PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/fuzzer-artifacts/dwarf-expression-artifacts + ) + + add_custom_target(fuzz-lldb-dwarf-expression + COMMENT "Running the LLDB target fuzzer..." + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/fuzzer-artifacts/dwarf-expression-artifacts + COMMAND $ -artifact_prefix=dwarf-expression- + USES_TERMINAL + ) + set_target_properties(fuzz-lldb-dwarf-expression PROPERTIES FOLDER "LLDB/Fuzzer") +endif() diff --git a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp new file mode 100644 index 0000000000000..65c160d7b731c --- /dev/null +++ b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp @@ -0,0 +1,83 @@ +//===-- lldb-target-fuzzer.cpp - Fuzz target creation ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "utils/TempFile.h" + +#include "Plugins/Platform/Linux/PlatformLinux.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Value.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::plugin::dwarf; +using namespace lldb_fuzzer; + +extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) { + FileSystem::Initialize(); + HostInfo::Initialize(); + platform_linux::PlatformLinux::Initialize(); + return 0; +} + +static void Evaluate(llvm::ArrayRef expr, + lldb::ModuleSP module_sp = {}, DWARFUnit *unit = nullptr, + ExecutionContext *exe_ctx = nullptr) { + DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle, + /*addr_size*/ 4); + + llvm::Expected result = + DWARFExpression::Evaluate(exe_ctx, /*reg_ctx*/ nullptr, module_sp, + extractor, unit, lldb::eRegisterKindLLDB, + /*initial_value_ptr*/ nullptr, + /*object_address_ptr*/ nullptr); + + if (!result) + llvm::consumeError(result.takeError()); +} + +class MockTarget : public Target { +public: + MockTarget(Debugger &debugger, const ArchSpec &target_arch, + const lldb::PlatformSP &platform_sp, llvm::ArrayRef data) + : Target(debugger, target_arch, platform_sp, true), m_data(data) {} + + size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, + Status &error, bool force_live_memory = false, + lldb::addr_t *load_addr_ptr = nullptr) override { + std::memcpy(dst, m_data.data(), m_data.size()); + return m_data.size(); + } + +private: + llvm::ArrayRef m_data; +}; + +extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { + // We're going to use the first half of the input data as the DWARF expression + // and the second half as memory. + const size_t partition = size / 2; + llvm::ArrayRef expression_data(data, partition); + llvm::ArrayRef memory_data(data + partition, size - partition); + + // Create a mock target for reading memory. + ArchSpec arch("i386-pc-linux"); + Platform::SetHostPlatform( + platform_linux::PlatformLinux::CreateInstance(true, &arch)); + lldb::DebuggerSP debugger_sp = Debugger::CreateInstance(); + lldb::PlatformSP platform_sp; + auto target_sp = std::make_shared(*debugger_sp, arch, platform_sp, + memory_data); + ExecutionContext exe_ctx(static_cast(target_sp), false); + + Evaluate(expression_data); + return 0; +} From c9b5acfefef7d0b705223d1880d0c0609c899bf7 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 30 Oct 2024 22:12:47 -0700 Subject: [PATCH 2/2] Address code review feedback --- .../lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt | 5 ++--- .../lldb-dwarf-expression-fuzzer.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt index 374a80b7bb83a..464696fc051d6 100644 --- a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt +++ b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/CMakeLists.txt @@ -7,10 +7,9 @@ add_llvm_fuzzer(lldb-dwarf-expression-fuzzer lldb-dwarf-expression-fuzzer.cpp ) -include_directories(${LLDB_SOURCE_ROOT}) - if(TARGET lldb-dwarf-expression-fuzzer) target_include_directories(lldb-dwarf-expression-fuzzer PRIVATE ..) + target_include_directories(lldb-dwarf-expression-fuzzer PRIVATE ${LLDB_SOURCE_ROOT}) target_link_libraries(lldb-dwarf-expression-fuzzer PRIVATE lldbCore @@ -25,7 +24,7 @@ if(TARGET lldb-dwarf-expression-fuzzer) ) add_custom_target(fuzz-lldb-dwarf-expression - COMMENT "Running the LLDB target fuzzer..." + COMMENT "Running the LLDB DWARF expression evaluator fuzzer..." WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/fuzzer-artifacts/dwarf-expression-artifacts COMMAND $ -artifact_prefix=dwarf-expression- USES_TERMINAL diff --git a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp index 65c160d7b731c..86c3709b3a829 100644 --- a/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp +++ b/lldb/tools/lldb-fuzzer/lldb-dwarf-expression-fuzzer/lldb-dwarf-expression-fuzzer.cpp @@ -1,4 +1,4 @@ -//===-- lldb-target-fuzzer.cpp - Fuzz target creation ---------------------===// +//===-- lldb-target-fuzzer.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information.