VYPR
researchPublished Apr 29, 2026· Updated May 20, 2026· 1 source

Trail of Bits Extends Ruzzy Fuzzer with LibAFL Support for Ruby

Trail of Bits has integrated the advanced LibAFL fuzzing engine into Ruzzy, its coverage-guided fuzzer for Ruby, enabling improved performance and modularity.

Trail of Bits has extended Ruzzy, its coverage-guided fuzzer for pure Ruby code and Ruby C extensions, with support for LibAFL, a Rust-based fuzzing engine that offers improved performance and modularity over LLVM's libFuzzer. The integration, detailed in a blog post, allows Ruby developers and security researchers to leverage LibAFL's advanced fuzzing techniques without changing their existing harnesses.

LibAFL has gained popularity in the fuzzing community, especially as LLVM's libFuzzer has been placed in maintenance mode. Written in Rust, LibAFL claims improved performance, modularity, state-of-the-art fuzzing techniques, and libFuzzer compatibility. Ruzzy was originally built on top of libFuzzer, so using LibAFL's compatibility layer seemed straightforward, but the implementation required navigating complex internals.

The integration uses LibAFL's libafl_libfuzzer runtime to build a libFuzzer.a archive. Ruzzy's build system was modified to allow an environment variable override for the fuzzer library path, enabling users to point to LibAFL's library instead of Clang's default. However, the initial build encountered a linker error: ".preinit_array section is not allowed in DSO." This error occurs because dynamic shared objects (DSOs) cannot contain a .preinit_array section, which is used for pre-initialization functions in executables.

To resolve this, the team had to modify the LibAFL build to remove the .preinit_array section or adjust the linking process. The blog post details the investigation into ELF file internals and the eventual fix, which involved patching the LibAFL build script to avoid generating the problematic section. After the fix, Ruzzy successfully linked with LibAFL's libFuzzer.a.

The new Dockerfile for building Ruzzy with LibAFL installs Rust nightly, clones the LibAFL repository, and builds the libFuzzer.a archive. The environment variable FUZZER_NO_MAIN_LIB is set to point to this archive, and Ruzzy is built with the modified extconf.rb that respects this variable. This approach ensures that Ruby fuzzing harnesses remain unchanged while benefiting from LibAFL's advanced features.

This development is significant for the Ruby security community, as it provides access to a more modern and actively maintained fuzzing engine. LibAFL offers techniques such as mutation scheduling, custom mutators, and multi-threading, which can improve bug discovery. The integration also demonstrates the flexibility of LibAFL's compatibility layer, making it easier for other projects to adopt LibAFL without major rewrites.

Trail of Bits has made the updated Ruzzy code available on GitHub, and the Dockerfile for LibAFL support is included in the repository. This work contributes to the ongoing evolution of fuzzing tools for interpreted languages, which are often overlooked in favor of native code fuzzing.

Synthesized by Vypr AI