mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Lagom: Add two-stage build for Fuzzers to enable fuzzing generated code
This allows us to fuzz the generated unicode and timezone database helpers, and to fuzz things like LibJS using Fuzzilli to get proper coverage of our unicode handling code. Update the Azure CI to use the new two-stage build as well, and cleanup some unused CMake options there.
This commit is contained in:
parent
bfa4bc6f2d
commit
0c95d9962c
Notes:
sideshowbarker
2024-07-17 18:28:52 +09:00
Author: https://github.com/ADKaster Commit: https://github.com/SerenityOS/serenity/commit/0c95d9962c Pull-request: https://github.com/SerenityOS/serenity/pull/12677 Issue: https://github.com/SerenityOS/serenity/issues/9466 Reviewed-by: https://github.com/linusg ✅ Reviewed-by: https://github.com/trflynn89
4 changed files with 129 additions and 40 deletions
|
@ -43,42 +43,38 @@ jobs:
|
|||
${{ if eq(parameters.fuzzer, 'NoFuzz') }}:
|
||||
with_remote_data_caches: true
|
||||
|
||||
- script: |
|
||||
mkdir -p Meta/Lagom/Build
|
||||
displayName: 'Create Build Directory'
|
||||
|
||||
- ${{ if eq(parameters.fuzzer, 'Fuzz') }}:
|
||||
- script: |
|
||||
cmake -GNinja \
|
||||
cmake -GNinja -B tools-build \
|
||||
-DBUILD_LAGOM=OFF \
|
||||
-DENABLE_LAGOM_CCACHE=ON \
|
||||
-DCMAKE_INSTALL_PREFIX=tool-install
|
||||
ninja -C tools-build install
|
||||
cmake -GNinja -B Build \
|
||||
-DBUILD_LAGOM=ON \
|
||||
-DENABLE_LAGOM_CCACHE=ON \
|
||||
-DENABLE_FUZZER_SANITIZER=ON \
|
||||
-DENABLE_ADDRESS_SANITIZER=ON \
|
||||
-DENABLE_PCI_IDS_DOWNLOAD=OFF \
|
||||
-DENABLE_USB_IDS_DOWNLOAD=OFF \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
..
|
||||
-DCMAKE_PREFIX_PATH=tool-install
|
||||
displayName: 'Create Build Environment'
|
||||
workingDirectory: $(Build.SourcesDirectory)/Meta/Lagom/Build
|
||||
workingDirectory: $(Build.SourcesDirectory)/Meta/Lagom
|
||||
env:
|
||||
CCACHE_DIR: '$(SERENITY_CCACHE_DIR)'
|
||||
- ${{ if eq(parameters.fuzzer, 'NoFuzz') }}:
|
||||
- script: |
|
||||
cmake -GNinja \
|
||||
cmake -GNinja -B Build \
|
||||
-DBUILD_LAGOM=ON \
|
||||
-DENABLE_LAGOM_CCACHE=ON \
|
||||
-DINCLUDE_WASM_SPEC_TESTS=ON \
|
||||
-DWASM_SPEC_TEST_SKIP_FORMATTING=ON \
|
||||
-DENABLE_UNDEFINED_SANITIZER=ON \
|
||||
-DENABLE_ADDRESS_SANITIZER=ON \
|
||||
-DENABLE_PCI_IDS_DOWNLOAD=OFF \
|
||||
-DENABLE_USB_IDS_DOWNLOAD=OFF \
|
||||
-DCMAKE_C_COMPILER=gcc-11 \
|
||||
-DCMAKE_CXX_COMPILER=g++-11 \
|
||||
..
|
||||
-DCMAKE_CXX_COMPILER=g++-11
|
||||
displayName: 'Create Build Environment'
|
||||
workingDirectory: $(Build.SourcesDirectory)/Meta/Lagom/Build
|
||||
workingDirectory: $(Build.SourcesDirectory)/Meta/Lagom
|
||||
env:
|
||||
PATH: '$(PATH):$(Build.SourcesDirectory)/wabt-1.0.23/bin'
|
||||
CCACHE_DIR: '$(SERENITY_CCACHE_DIR)'
|
||||
|
|
84
Meta/Lagom/BuildFuzzers.sh
Executable file
84
Meta/Lagom/BuildFuzzers.sh
Executable file
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
BEST_CLANG_CANDIDATE=""
|
||||
|
||||
die() {
|
||||
>&2 echo "die: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
pick_clang() {
|
||||
local BEST_VERSION=0
|
||||
for CLANG_CANDIDATE in clang clang-13 clang-14 /usr/local/bin/clang-13 /usr/local/bin/clang-14; do
|
||||
if ! command -v $CLANG_CANDIDATE >/dev/null 2>&1; then
|
||||
continue
|
||||
fi
|
||||
if $CLANG_CANDIDATE --version 2>&1 | grep "Apple clang" >/dev/null; then
|
||||
continue
|
||||
fi
|
||||
if ! $CLANG_CANDIDATE -dumpversion >/dev/null 2>&1; then
|
||||
continue
|
||||
fi
|
||||
local VERSION=""
|
||||
VERSION="$($CLANG_CANDIDATE -dumpversion)"
|
||||
local MAJOR_VERSION="${VERSION%%.*}"
|
||||
if [ "$MAJOR_VERSION" -gt "$BEST_VERSION" ]; then
|
||||
BEST_VERSION=$MAJOR_VERSION
|
||||
BEST_CLANG_CANDIDATE="$CLANG_CANDIDATE"
|
||||
fi
|
||||
done
|
||||
if [ "$BEST_VERSION" -lt 13 ]; then
|
||||
die "Please make sure that Clang version 13 or higher is installed."
|
||||
fi
|
||||
}
|
||||
|
||||
# Save flags for oss-fuzz to avoid fuzzing Tools/
|
||||
# https://google.github.io/oss-fuzz/getting-started/new-project-guide/#temporarily-disabling-code-instrumentation-during-builds
|
||||
CFLAGS_SAVE="$CFLAGS"
|
||||
CXXFLAGS_SAVE="$CXXFLAGS"
|
||||
unset CFLAGS
|
||||
unset CXXFLAGS
|
||||
export AFL_NOOPT=1
|
||||
|
||||
# FIXME: Replace these CMake invocations with a CMake superbuild?
|
||||
echo "Building Lagom Tools..."
|
||||
cmake -GNinja -B Build/tools \
|
||||
-DBUILD_LAGOM=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=Build/tool-install
|
||||
ninja -C Build/tools install
|
||||
|
||||
# Restore flags for oss-fuzz
|
||||
export CFLAGS="${CFLAGS_SAVE}"
|
||||
export CXXFLAGS="${CXXFLAGS_SAVE}"
|
||||
unset AFL_NOOPT
|
||||
|
||||
echo "Building Lagom Fuzzers..."
|
||||
|
||||
if [ "$#" -gt "0" ] && [ "--oss-fuzz" = "$1" ] ; then
|
||||
echo "Building for oss-fuzz configuration..."
|
||||
cmake -GNinja -B Build/fuzzers \
|
||||
-DBUILD_LAGOM=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DENABLE_OSS_FUZZ=ON \
|
||||
-DCMAKE_C_COMPILER="$CC" \
|
||||
-DCMAKE_CXX_COMPILER="$CXX" \
|
||||
-DCMAKE_CXX_FLAGS="$CXXFLAGS -DOSS_FUZZ=ON" \
|
||||
-DLINKER_FLAGS="$LIB_FUZZING_ENGINE" \
|
||||
-DCMAKE_PREFIX_PATH=Build/tool-install
|
||||
ninja -C Build/fuzzers
|
||||
cp Build/fuzzers/Fuzzers/Fuzz* "$OUT"/
|
||||
else
|
||||
echo "Building for local fuzz configuration..."
|
||||
pick_clang
|
||||
cmake -GNinja -B Build/lagom-fuzzers \
|
||||
-DBUILD_LAGOM=ON \
|
||||
-DENABLE_FUZZER_SANITIZER=ON \
|
||||
-DENABLE_ADDRESS_SANITIZER=ON \
|
||||
-DENABLE_UNDEFINED_SANITIZER=ON \
|
||||
-DCMAKE_PREFIX_PATH=Build/tool-install \
|
||||
-DCMAKE_C_COMPILER=$BEST_CLANG_CANDIDATE \
|
||||
-DCMAKE_CXX_COMPILER="${BEST_CLANG_CANDIDATE/clang/clang++}"
|
||||
ninja -C Build/lagom-fuzzers
|
||||
fi
|
|
@ -41,14 +41,8 @@ endif()
|
|||
# FIXME: BUILD_SHARED_LIBS has a default of OFF, as it's intended to be set by the
|
||||
# user when configuring the project. We should instead change libjs-test262
|
||||
# and oss-fuzz to set this option on their end, and enable it by default in
|
||||
# Meta/serenity.sh
|
||||
# This is #9867. We can change the oss-fuzz escape hatch to be a FATAL_ERROR
|
||||
# message instead when implementing it.
|
||||
# Meta/serenity.sh. This is #9867.
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries instead of static libraries" ON)
|
||||
if (ENABLE_OSS_FUZZ)
|
||||
# Don't use shared libraries on oss-fuzz, for ease of integration with their infrastructure
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries instead of static libraries" FORCE)
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
|
@ -120,6 +114,12 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang$")
|
|||
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(-Wno-expansion-to-defined)
|
||||
if (ENABLE_FUZZER_SANITIZER)
|
||||
message(FATAL_ERROR
|
||||
"Fuzzer Sanitizer (-fsanitize=fuzzer) is only supported for Fuzzer targets with LLVM. "
|
||||
"Reconfigure CMake with -DCMAKE_C_COMPILER and -DCMAKE_CXX_COMPILER pointing to a clang-based toolchain"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# These are here to support Fuzzili builds further down the directory stack
|
||||
|
@ -168,8 +168,13 @@ function(lagom_lib library fs_name)
|
|||
cmake_parse_arguments(LAGOM_LIBRARY "" "" "SOURCES;LIBS" ${ARGN})
|
||||
set(target_name "Lagom${library}")
|
||||
add_library(${target_name} ${LAGOM_LIBRARY_SOURCES})
|
||||
# alias for parity with exports
|
||||
add_library(Lagom::${library} ALIAS ${target_name})
|
||||
|
||||
# Don't make alias when we're going to import a previous build for Tools
|
||||
# FIXME: Is there a better way to write this?
|
||||
if (NOT ENABLE_OSS_FUZZ AND NOT ENABLE_FUZZER_SANITIZER)
|
||||
# alias for parity with exports
|
||||
add_library(Lagom::${library} ALIAS ${target_name})
|
||||
endif()
|
||||
|
||||
set_target_properties(
|
||||
${target_name} PROPERTIES
|
||||
|
@ -247,11 +252,7 @@ endif()
|
|||
|
||||
# TimeZone
|
||||
# This is needed even if Lagom is not enabled because it is depended upon by code generators.
|
||||
if (NOT ENABLE_OSS_FUZZ AND NOT ENABLE_FUZZER_SANITIZER)
|
||||
include(time_zone_data)
|
||||
else()
|
||||
set(ENABLE_TIME_ZONE_DATABASE_DOWNLOAD OFF)
|
||||
endif()
|
||||
include(time_zone_data)
|
||||
file(GLOB LIBTIMEZONE_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibTimeZone/*.cpp")
|
||||
lagom_lib(TimeZone timezone
|
||||
SOURCES ${LIBTIMEZONE_SOURCES} ${TIME_ZONE_DATA_SOURCES}
|
||||
|
@ -268,7 +269,10 @@ install(
|
|||
|
||||
# Code Generators and other host tools
|
||||
# We need to make sure not to build code generators for Fuzzer builds, as they already have their own main.cpp
|
||||
if (NOT ENABLE_OSS_FUZZ AND NOT ENABLE_FUZZER_SANITIZER)
|
||||
# Instead, we import them from a previous install of Lagom. This mandates a two-stage build for fuzzers.
|
||||
if (ENABLE_OSS_FUZZ OR ENABLE_FUZZER_SANITIZER)
|
||||
find_package(Lagom REQUIRED)
|
||||
else()
|
||||
add_subdirectory(Tools)
|
||||
endif()
|
||||
|
||||
|
@ -442,12 +446,7 @@ if (BUILD_LAGOM)
|
|||
)
|
||||
|
||||
# Unicode
|
||||
# Don't include UnicodeData for Fuzzer builds, we didn't build the CodeGenerators
|
||||
if (NOT ENABLE_OSS_FUZZ AND NOT ENABLE_FUZZER_SANITIZER)
|
||||
include(unicode_data)
|
||||
else()
|
||||
set(ENABLE_UNICODE_DATABASE_DOWNLOAD OFF)
|
||||
endif()
|
||||
include(unicode_data)
|
||||
file(GLOB LIBUNICODE_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibUnicode/*.cpp")
|
||||
lagom_lib(Unicode unicode
|
||||
SOURCES ${LIBUNICODE_SOURCES} ${UNICODE_DATA_SOURCES}
|
||||
|
|
|
@ -14,22 +14,32 @@ Lagom can be used to fuzz parts of SerenityOS's code base. Fuzzers can be run lo
|
|||
|
||||
### Fuzzing locally
|
||||
|
||||
Lagom can be used to fuzz parts of SerenityOS's code base. This requires building with `clang`, so it's convenient to use a different build directory for that. Fuzzers work best with Address Sanitizer enabled. Run CMake like this:
|
||||
Lagom can be used to fuzz parts of SerenityOS's code base. This requires building with `clang`, so it's convenient to use a different build directory for that. Fuzzers work best with Address Sanitizer enabled. The fuzzer build requires code generators to be pre-built without fuzzing in a two stage build. To build with LLVM's libFuzzer, invoke
|
||||
the ``BuildFuzzers.sh`` script with no arguments. The script does the equivalent of the CMake commands below:
|
||||
|
||||
# From the root of the SerenityOS checkout:
|
||||
cmake -GNinja -S Meta/Lagom -B Build/lagom-fuzzers \
|
||||
```sh
|
||||
# From the Meta/Lagom directory:
|
||||
# Stage 1: Build and install code generators and other tools
|
||||
cmake -GNinja -B Build/tools \
|
||||
-DBUILD_LAGOM=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=Build/tool-install
|
||||
ninja -C Build/tools install
|
||||
# Stage 2: Build fuzzers, making sure the build can find the tools we just built
|
||||
cmake -GNinja -B Build/lagom-fuzzers \
|
||||
-DBUILD_LAGOM=ON \
|
||||
-DENABLE_FUZZER_SANITIZER=ON \
|
||||
-DENABLE_ADDRESS_SANITIZER=ON \
|
||||
-DENABLE_UNDEFINED_SANITIZER=ON \
|
||||
-DCMAKE_PREFIX_PATH=Build/tool-install \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_COMPILER=clang
|
||||
cd Build/lagom-fuzzers
|
||||
ninja
|
||||
# Or as a handy rebuild-rerun line:
|
||||
ninja FuzzJs && ./Fuzzers/FuzzJs
|
||||
```
|
||||
|
||||
(Note that we require clang >= 12, so depending on your package manager you may need to specify `clang++-12` and `clang-12` instead.)
|
||||
(Note that we require clang >= 13, see the pick_clang() function in the script for the paths that are searched)
|
||||
|
||||
Any fuzzing results (particularly slow inputs, crashes, etc.) will be dropped in the current directory.
|
||||
|
||||
|
|
Loading…
Reference in a new issue