Skip to content

MONGOCRYPT-834 fuzzing for oss-fuzz#1152

Open
mdb-ad wants to merge 6 commits intomongodb:masterfrom
mdb-ad:oss-fuzz
Open

MONGOCRYPT-834 fuzzing for oss-fuzz#1152
mdb-ad wants to merge 6 commits intomongodb:masterfrom
mdb-ad:oss-fuzz

Conversation

@mdb-ad
Copy link
Copy Markdown
Contributor

@mdb-ad mdb-ad commented Apr 24, 2026

Background

Libmongocrypt will be added to OSS-Fuzz for continuous fuzz testing. On our end we only have to provide the fuzzing entry point: LLVMFuzzerTestOneInput which is linked into the fuzzing binary.

Design

The fuzzing engine which accepts binary inputs uses the first byte to decide on the target state. It provides some defaults (local encryption keys, etc.) until the state machine is ready to accept input and feeds the fuzzer generated data. A corpus of starting data derived from test inputs improves fuzzing efficiency.

Coverage

The fuzzing added here covers 14.33% of libmongocrypt's functions.

@mdb-ad mdb-ad requested a review from a team as a code owner April 24, 2026 05:26
@mdb-ad mdb-ad requested a review from kevinAlbs April 24, 2026 05:26
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

How were these binary files generated? Consider documenting in a new doc/fuzzing.md to describe how we can regenerate these if needed.

Comment thread test/fuzz_mongocrypt.c
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Though it may not be strictly needed for OSS-Fuzz, suggest adding a CMake target to help test locally:

option (ENABLE_FUZZING "Build fuzzing targets. Requires a compiler supporting -fsanitize=fuzzer." OFF)
# ...
if (ENABLE_FUZZING)
   include (CheckCCompilerFlag)
   check_c_compiler_flag ("-fsanitize=fuzzer" COMPILER_SUPPORTS_FUZZER)
   if (NOT COMPILER_SUPPORTS_FUZZER)
      message (FATAL_ERROR
         "ENABLE_FUZZING is ON but the compiler does not support -fsanitize=fuzzer. "
      )
   endif ()

   add_executable (fuzz_mongocrypt EXCLUDE_FROM_ALL test/fuzz_mongocrypt.c)
   target_include_directories (fuzz_mongocrypt PRIVATE ./src)
   target_link_libraries (fuzz_mongocrypt PRIVATE mongocrypt_static _mongocrypt::libbson_for_static)
   target_compile_options (fuzz_mongocrypt PRIVATE -fsanitize=fuzzer)
   target_link_options (fuzz_mongocrypt PRIVATE -fsanitize=fuzzer)
endif ()

Tip: I can run this locally on macOS by using the compilers included in brew install llvm:

cmake \
  -DCMAKE_C_COMPILER="/opt/homebrew/opt/llvm/bin/clang" \
  -DCMAKE_CXX_COMPILER="/opt/homebrew/opt/llvm/bin/clang++" \
  -DENABLE_FUZZING=ON \
  -Bcmake-build

Comment thread test/fuzz_mongocrypt.c
/* Set up key encryption key for local provider. */
uint8_t kek_bson[] = {
/* {"provider": "local"} as BSON */
0x1b, 0x00, 0x00, 0x00, /* doc len = 27 */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
0x1b, 0x00, 0x00, 0x00, /* doc len = 27 */
0x19, 0x00, 0x00, 0x00, /* doc len = 27 */

Careful. Length appears incorrect. Contents can be checked with PyMongo using bson.decode:

bson.decode(bytearray([
    0x19, 0x00, 0x00, 0x00,
    0x02,
    ord('p'), ord('r'), ord('o'), ord('v'), ord('i'), ord('d'), ord('e'), ord('r'), 0x00,
    0x06, 0x00, 0x00, 0x00,
    ord('l'), ord('o'), ord('c'), ord('a'), ord('l'), 0x00,
    0x00
]))
# {'provider': 'local'}

Comment thread test/fuzz_mongocrypt.c
0x1b, 0x00, 0x00, 0x00, /* doc len = 27 */
0x02, /* type: string */
'p', 'r', 'o', 'v', 'i', 'd', 'e', 'r', 0x00, /* key */
0x06, 0x00, 0x00, 0x00, /* string len = 6 */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggest running file through clang-format to align comments.

Comment thread test/fuzz_mongocrypt.c
mongocrypt_ctx_setopt_key_id(ctx, kid_bin);
mongocrypt_binary_destroy(kid_bin);
}
mongocrypt_ctx_setopt_algorithm(ctx, "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", -1);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Set algorithm and queryType to "range".

I expect the call to mongocrypt_ctx_explicit_encrypt_expression_init always fails. Encrypt expression requires algorithm and queryType both be set to range.

libmongocrypt checks the queryType for encryptExpression is "range" (1) and later that queryType matches algorithm (2).

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.

2 participants