Reland "[lldb/Fuzzer] Add fuzzer for expression evaluator"
This reverts commit d959324e1efec12c3924c17b7d90db0b37eb84c3. The target_include_directories in the clang-fuzzer CMake files are set to PRIVATE instead of PUBLIC to prevent the clang buildbots from breaking when symlinking clang into llvm. The expression evaluator fuzzer itself has been modified to prevent a bug that occurs when running it without a target.
This commit is contained in:
parent
12e78ff881
commit
bcf6ffb87e
@ -1,5 +1,9 @@
|
|||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
set(PBM_PREFIX protobuf_mutator)
|
|
||||||
|
if (NOT PBM_PREFIX)
|
||||||
|
set (PBM_PREFIX protobuf_mutator)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(PBM_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PBM_PREFIX}/src/${PBM_PREFIX})
|
set(PBM_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PBM_PREFIX}/src/${PBM_PREFIX})
|
||||||
set(PBM_LIB_PATH ${PBM_PATH}-build/src/libprotobuf-mutator.a)
|
set(PBM_LIB_PATH ${PBM_PATH}-build/src/libprotobuf-mutator.a)
|
||||||
set(PBM_FUZZ_LIB_PATH ${PBM_PATH}-build/src/libfuzzer/libprotobuf-mutator-libfuzzer.a)
|
set(PBM_FUZZ_LIB_PATH ${PBM_PATH}-build/src/libfuzzer/libprotobuf-mutator-libfuzzer.a)
|
||||||
|
@ -11,3 +11,5 @@ add_clang_library(clangHandleCXX
|
|||||||
clangSerialization
|
clangSerialization
|
||||||
clangTooling
|
clangTooling
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_include_directories(clangHandleCXX PRIVATE .)
|
||||||
|
@ -14,6 +14,8 @@ add_clang_library(clangLoopProtoToCXX loop_proto_to_cxx.cpp
|
|||||||
DEPENDS clangCXXLoopProto
|
DEPENDS clangCXXLoopProto
|
||||||
LINK_LIBS clangCXXLoopProto ${PROTOBUF_LIBRARIES}
|
LINK_LIBS clangCXXLoopProto ${PROTOBUF_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
target_include_directories(clangProtoToCXX PRIVATE .)
|
||||||
|
target_include_directories(clangLoopProtoToCXX PRIVATE .)
|
||||||
|
|
||||||
add_clang_executable(clang-proto-to-cxx proto_to_cxx_main.cpp)
|
add_clang_executable(clang-proto-to-cxx proto_to_cxx_main.cpp)
|
||||||
add_clang_executable(clang-loop-proto-to-cxx loop_proto_to_cxx_main.cpp)
|
add_clang_executable(clang-loop-proto-to-cxx loop_proto_to_cxx_main.cpp)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
add_subdirectory(lldb-commandinterpreter-fuzzer)
|
add_subdirectory(lldb-commandinterpreter-fuzzer)
|
||||||
|
add_subdirectory(lldb-expression-fuzzer)
|
||||||
add_subdirectory(lldb-target-fuzzer)
|
add_subdirectory(lldb-target-fuzzer)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
|
60
lldb/tools/lldb-fuzzer/lldb-expression-fuzzer/CMakeLists.txt
Normal file
60
lldb/tools/lldb-fuzzer/lldb-expression-fuzzer/CMakeLists.txt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
if(CLANG_ENABLE_PROTO_FUZZER)
|
||||||
|
set(LLVM_LINK_COMPONENTS
|
||||||
|
Support
|
||||||
|
)
|
||||||
|
|
||||||
|
add_llvm_fuzzer(lldb-expression-fuzzer
|
||||||
|
EXCLUDE_FROM_ALL
|
||||||
|
lldb-expression-fuzzer.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(TARGET lldb-expression-fuzzer)
|
||||||
|
target_include_directories(lldb-expression-fuzzer PRIVATE ..)
|
||||||
|
find_package(Protobuf REQUIRED)
|
||||||
|
add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI)
|
||||||
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../../clang/tools/clang-fuzzer PRIVATE ..)
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../../clang/tools/clang-fuzzer)
|
||||||
|
|
||||||
|
set(CLANG_CMAKE_MODULE_PATH
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../../../clang/cmake/modules)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH
|
||||||
|
${CMAKE_MODULE_PATH}
|
||||||
|
${CLANG_CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
|
|
||||||
|
set (PBM_PREFIX lldb_protobuf_mutator)
|
||||||
|
include(ProtobufMutator)
|
||||||
|
include_directories(${ProtobufMutator_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
target_link_libraries(lldb-expression-fuzzer
|
||||||
|
PRIVATE
|
||||||
|
${ProtobufMutator_LIBRARIES}
|
||||||
|
${LLVM_LIB_FUZZING_ENGINE}
|
||||||
|
clangHandleCXX
|
||||||
|
clangCXXProto
|
||||||
|
clangProtoToCXX
|
||||||
|
liblldb
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_command(TARGET lldb-expression-fuzzer PRE_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/fuzzer-artifacts/expression-artifacts
|
||||||
|
# Create and compile a simple C program using the command line. This is
|
||||||
|
# needed because LLDB's expression evaluator needs a legitmate target
|
||||||
|
# instead of a dummy target
|
||||||
|
COMMAND echo 'int main (int argc, char** argv) { return 0\; }' | clang -o main.out -xc -
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a directory for storing the fuzzer's artifacts and run the fuzzer with arguments that will
|
||||||
|
# not attempt to reduce the size of the inputs being generated
|
||||||
|
# Also set the executable that's created above as an environment variable for the
|
||||||
|
# source code to use
|
||||||
|
add_custom_target(fuzz-lldb-expression
|
||||||
|
COMMENT "Running the LLDB expression evaluator fuzzer..."
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/fuzzer-artifacts/expression-artifacts
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E env LLDB_FUZZER_TARGET=${CMAKE_CURRENT_BINARY_DIR}/main.out $<TARGET_FILE:lldb-expression-fuzzer> -artifact_prefix=expression- -reduce_inputs=0
|
||||||
|
USES_TERMINAL
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
@ -0,0 +1,95 @@
|
|||||||
|
//===-- lldb-expression-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.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===---------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// \file
|
||||||
|
// This file is a fuzzer for LLDB's expression evaluator. It uses protobufs
|
||||||
|
// and the libprotobuf-mutator to create valid C-like inputs for the
|
||||||
|
// expression evaluator.
|
||||||
|
//
|
||||||
|
//===---------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "cxx_proto.pb.h"
|
||||||
|
#include "handle-cxx/handle_cxx.h"
|
||||||
|
#include "lldb/API/SBBreakpoint.h"
|
||||||
|
#include "lldb/API/SBDebugger.h"
|
||||||
|
#include "lldb/API/SBError.h"
|
||||||
|
#include "lldb/API/SBLaunchInfo.h"
|
||||||
|
#include "lldb/API/SBProcess.h"
|
||||||
|
#include "lldb/API/SBTarget.h"
|
||||||
|
#include "proto-to-cxx/proto_to_cxx.h"
|
||||||
|
#include "src/libfuzzer/libfuzzer_macro.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
#include "llvm/Support/FormatVariadic.h"
|
||||||
|
#include "llvm/Support/WithColor.h"
|
||||||
|
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace clang_fuzzer;
|
||||||
|
|
||||||
|
char *target_path;
|
||||||
|
|
||||||
|
void ReportError(llvm::StringRef message) {
|
||||||
|
WithColor::error() << message << '\n';
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
target_path = ::getenv("LLDB_FUZZER_TARGET");
|
||||||
|
if (!target_path)
|
||||||
|
ReportError(
|
||||||
|
"no target path specified in with the LLDB_FUZZER_TARGET variable");
|
||||||
|
|
||||||
|
if (!sys::fs::exists(target_path))
|
||||||
|
ReportError(formatv("target path '{0}' does not exist", target_path).str());
|
||||||
|
|
||||||
|
SBDebugger::Initialize();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_BINARY_PROTO_FUZZER(const clang_fuzzer::Function &input) {
|
||||||
|
std::string expression = clang_fuzzer::FunctionToString(input);
|
||||||
|
|
||||||
|
// Create a debugger and a target
|
||||||
|
SBDebugger debugger = SBDebugger::Create(false);
|
||||||
|
if (!debugger.IsValid())
|
||||||
|
ReportError("Couldn't create debugger");
|
||||||
|
|
||||||
|
SBTarget target = debugger.CreateTarget(target_path);
|
||||||
|
if (!target.IsValid())
|
||||||
|
ReportError(formatv("Couldn't create target '{0}'", target_path).str());
|
||||||
|
|
||||||
|
// Create a breakpoint on the only line in the program
|
||||||
|
SBBreakpoint breakpoint = target.BreakpointCreateByName("main", target_path);
|
||||||
|
if (!breakpoint.IsValid())
|
||||||
|
ReportError("Couldn't create breakpoint");
|
||||||
|
|
||||||
|
// Create launch info and error for launching the process
|
||||||
|
SBLaunchInfo launch_info = target.GetLaunchInfo();
|
||||||
|
SBError error;
|
||||||
|
|
||||||
|
// Launch the process and evaluate the fuzzer's input data
|
||||||
|
// as an expression
|
||||||
|
SBProcess process = target.Launch(launch_info, error);
|
||||||
|
if (!process.IsValid() || error.Fail())
|
||||||
|
ReportError("Couldn't launch process");
|
||||||
|
|
||||||
|
SBValue value = target.EvaluateExpression(expression.c_str());
|
||||||
|
|
||||||
|
debugger.DeleteTarget(target);
|
||||||
|
SBDebugger::Destroy(debugger);
|
||||||
|
SBModule::GarbageCollectAllocatedModules();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user