Skip to content

CDRIVER-5648 fix libfuzzer integration #1686

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 13, 2024

Conversation

spencerjackson
Copy link
Contributor

Summary

This patch modifies the CMake rules in order to allow compilation of the already existing libfuzzer entrypoint.

What Changed?

  1. fuzz_test_libbson.c renamed to fuzz_test_init_from_json.c
    We could have multiple entrypoints, so it makes sense to name the file after the function we're fuzzing.
  2. fuzz_test_init_from_json.c simplified to remove memory allocation
    The faster we can run the entrypoint, the more iterations per second we'll be able to manage.
  3. CMake option MONGO_FUZZ added
    When building a fuzzer, all code in all TUs must be compiled with coverage instrumentation. The final link step must statically link libfuzzer's main symbol. Adding sanitizers to all TUs is also beneficial.
    This new option enables AUBSan and a sanitizer called "fuzzer-no-link", which enables CovSAN and all the other flags libfuzzer needs to operate. Finally, this option sets MONGO_FUZZ_ENGINE to the linker flags needed to statically link in libfuzzer's main. Any binaries which provide fuzzer entrypoints need to use MONGO_FUZZ_ENGINE in their LINK_FLAGS.
  4. Added src/libbson/fuzz/CMakeLists.txt
    This file compiles the fuzzer entrypoint, iff MONGO_FUZZ is enabled.

I haven't used CMake in a while, so feedback is appreciated!

@kevinAlbs kevinAlbs requested review from vector-of-bool, kevinAlbs and eramongodb and removed request for vector-of-bool August 6, 2024 11:54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file in favor of:

  • reusing MONGO_SANITIZE to set sanitizer options, and
  • scoping fuzz-testing-related properties and targets to src/libbson/fuzz/CMakeLists.txt.

Described in further detail in other comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -399,6 +399,8 @@ install (EXPORT bson-targets
include (LegacyPackage)
include (CPack)

add_subdirectory(fuzz)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
add_subdirectory(fuzz)
if (MONGO_FUZZ)
add_subdirectory(fuzz)
endif ()

Condition the definition of fuzz targets on MONGO_FUZZ.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -0,0 +1,9 @@
if (MONGO_FUZZ)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (MONGO_FUZZ)

Condition the add_subdirectory() rather than this file's contents.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 5 to 6
target_include_directories(fuzz_test_init_from_json PRIVATE "src" "${PROJECT_BINARY_DIR}/src/")
target_link_libraries(fuzz_test_init_from_json ${bson_libs})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
target_include_directories(fuzz_test_init_from_json PRIVATE "src" "${PROJECT_BINARY_DIR}/src/")
target_link_libraries(fuzz_test_init_from_json ${bson_libs})
target_link_libraries(fuzz_test_init_from_json PRIVATE bson_static)

Use same library linkage pattern as existing test executables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 5 to 9
mongo_setting(
MONGO_FUZZ "Whether fuzz testing is enabled"
TYPE BOOL
DEFAULT FALSE
)
Copy link
Contributor

@eramongodb eramongodb Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mongo_setting(
MONGO_FUZZ "Whether fuzz testing is enabled"
TYPE BOOL
DEFAULT FALSE
)

Move the MONGO_FUZZ option definition into build/cmake/Sanitizers.cmake prior to the MONGO_SANITIZE option definition and redefine as follows:

mongo_bool_setting(
    MONGO_FUZZ "Enable LibFuzzer integration"
    DEFAULT VALUE OFF
    VALIDATE CODE [[
        if (NOT ENABLE_STATIC)
            message (FATAL_ERROR "MONGO_FUZZ requires ENABLE_STATIC=ON or ENABLE_STATIC=BUILD_ONLY")
        endif ()
    ]]
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 11 to 14
if (MONGO_FUZZ)
set(CMAKE_C_FLAGS "-fsanitize=undefined -fsanitize=address -fsanitize=fuzzer-no-link" CACHE STRING "Custom comp" FORCE)
set(MONGO_FUZZ_ENGINE -fsanitize=fuzzer)
endif ()
Copy link
Contributor

@eramongodb eramongodb Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (MONGO_FUZZ)
set(CMAKE_C_FLAGS "-fsanitize=undefined -fsanitize=address -fsanitize=fuzzer-no-link" CACHE STRING "Custom comp" FORCE)
set(MONGO_FUZZ_ENGINE -fsanitize=fuzzer)
endif ()

Remove in favor of reusing the existing MONGO_SANITIZE option by adding the following after the MONGO_SANITIZE option definition in build/cmake/Sanitizers.cmake:

if (MONGO_FUZZ)
    set(mongo_fuzz_options "address,undefined,fuzzer-no-link")

    if (NOT "${MONGO_SANITIZE}" STREQUAL "${mongo_fuzz_options}")
        message(WARNING "Overriding user-provided MONGO_SANITIZE options in favor of MONGO_SANITIZE=ON")
    endif()

    set_property (CACHE MONGO_SANITIZE PROPERTY VALUE "${mongo_fuzz_options}")
endif ()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 3 to 4
add_executable(fuzz_test_init_from_json
fuzz_test_init_from_json.c)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
add_executable(fuzz_test_init_from_json
fuzz_test_init_from_json.c)
add_executable(fuzz_test_init_from_json EXCLUDE_FROM_ALL fuzz_test_init_from_json.c)

Do not build fuzz executable as part of build-and-install routines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

fuzz_test_init_from_json.c)
target_include_directories(fuzz_test_init_from_json PRIVATE "src" "${PROJECT_BINARY_DIR}/src/")
target_link_libraries(fuzz_test_init_from_json ${bson_libs})
set_target_properties(fuzz_test_init_from_json PROPERTIES LINK_FLAGS ${MONGO_FUZZ_ENGINE})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set_target_properties(fuzz_test_init_from_json PROPERTIES LINK_FLAGS ${MONGO_FUZZ_ENGINE})
set_property(TARGET fuzz_test_init_from_json APPEND PROPERTY LINK_OPTIONS -fsanitize=fuzzer)

Pass fuzzer "with link" option directly and avoid potentially overwriting existing LINK_OPTIONS values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@eramongodb eramongodb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much! One last suggestion remaining; otherwise, LGTM.

Comment on lines 44 to 60
mongo_bool_setting(
MONGO_FUZZ "Enable LibFuzzer integration"
DEFAULT VALUE OFF
VALIDATE CODE [[
if (NOT ENABLE_STATIC)
message (FATAL_ERROR "MONGO_FUZZ requires ENABLE_STATIC=ON or ENABLE_STATIC=BUILD_ONLY")
endif ()
]]
)

if (MONGO_FUZZ)
set(mongo_fuzz_options "address,undefined,fuzzer-no-link")
if (NOT "${MONGO_SANITIZE}" STREQUAL "${mongo_fuzz_options}")
message(WARNING "Overriding user-provided MONGO_SANITIZE options in favor of MONGO_SANITIZE=ON")
endif ()
set_property (CACHE MONGO_SANITIZE PROPERTY VALUE "${mongo_fuzz_options}")
endif ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These commands must come before MONGO_SANITIZE is parsed. Move up to come immediately after the MONGO_SANITIZE option definition:

mongo_setting (MONGO_SANITIZE ...)

mongo_bool_setting (MONGO_FUZZ ...)

if (MONGO_FUZZ)
  set(mongo_fuzz_options "address,undefined,fuzzer-no-link")
  ...
endif ()

# Replace commas with semicolons for the genex
string(REPLACE ";" "," _sanitize "${MONGO_SANITIZE}")

if (_sanitize)
  ...
endif ()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@spencerjackson
Copy link
Contributor Author

Comments addressed, I also tweaked the logic in the MONGO_FUZZ VALIDATE block, so that it errors only if (MONGO_FUZZ AND NOT ENABLE_STATIC)

@eramongodb eramongodb self-assigned this Aug 9, 2024
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution. LGTM with minor CMake suggested tweaks.

if (MONGO_FUZZ)
set(mongo_fuzz_options "address,undefined,fuzzer-no-link")
if (NOT "${MONGO_SANITIZE}" STREQUAL "${mongo_fuzz_options}")
message(WARNING "Overriding user-provided MONGO_SANITIZE options in favor of MONGO_SANITIZE=ON")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
message(WARNING "Overriding user-provided MONGO_SANITIZE options in favor of MONGO_SANITIZE=ON")
message(WARNING "Overriding user-provided MONGO_SANITIZE options due to MONGO_FUZZ=ON")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


if (MONGO_FUZZ)
set(mongo_fuzz_options "address,undefined,fuzzer-no-link")
if (NOT "${MONGO_SANITIZE}" STREQUAL "${mongo_fuzz_options}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (NOT "${MONGO_SANITIZE}" STREQUAL "${mongo_fuzz_options}")
if (MONGO_SANITIZE AND NOT "${MONGO_SANITIZE}" STREQUAL "${mongo_fuzz_options}")

To skip warning when MONGO_SANITIZE is not set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@eramongodb eramongodb merged commit 8cc212b into mongodb:master Aug 13, 2024
42 of 43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants