跳到正文
cccskills
免费在 GitHub 公开

ruzzy

Guides fuzz testing for Ruby libraries and gems with Ruzzy, using varied inputs to find failures. Covers pure Ruby and C extensions, including test harnesses, memory error detection, environment setup, and crash reproduction.

中文简介正在准备中。当前显示英语简介。

原文查看原文说明

Sets up and runs Ruzzy, Trail of Bits' coverage-guided Ruby fuzzer and the only production-ready one for the language. Covers harness structure, fuzzing pure Ruby and the native C extensions in gems, and sanitizer builds. Use when fuzzing a Ruby library or gem, testing a Ruby C extension for memory safety, or asking how to fuzz Ruby at all.

查看安装方法

适用场景

  • Adding fuzz tests to a Ruby library
  • Testing memory safety in a gem's C extension
  • Preparing tracer and harness scripts for pure Ruby
  • Reproducing a saved crash input

包含的文件(3)

  • SKILL.md11.9 KB
  • agents/openai.yaml231 B
  • assets/trail-of-bits-mark.svg3.0 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Ruzzy

Ruzzy is a coverage-guided fuzzer for Ruby built on libFuzzer. It enables fuzzing both pure Ruby code and Ruby C extensions with sanitizer support for detecting memory corruption and undefined behavior.

When to Use

Ruzzy is currently the only production-ready coverage-guided fuzzer for Ruby.

Choose Ruzzy when:

  • Fuzzing Ruby applications or libraries
  • Testing Ruby C extensions for memory safety issues
  • You need coverage-guided fuzzing for Ruby code
  • Working with Ruby gems that have native extensions

Quick Start

Set up environment:

export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"

Test with the included toy example:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby -e 'require "ruzzy"; Ruzzy.dummy'

This should quickly find a crash demonstrating that Ruzzy is working correctly.

Installation

Platform Support

Ruzzy supports Linux x86-64 and AArch64/ARM64. For macOS or Windows, use the Dockerfile or development environment.

Prerequisites

  • Linux x86-64 or AArch64/ARM64
  • Recent version of clang (tested back to 14.0.0, latest release recommended)
  • Ruby with gem installed

Installation Command

Install Ruzzy with clang compiler flags:

MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
    gem install ruzzy

Environment variables explained:

  • MAKE: Overrides make to respect subsequent environment variables
  • CC, CXX, LDSHARED, LDSHAREDXX: Ensure proper clang binaries are used for latest features

Troubleshooting Installation

If installation fails, enable debug output:

RUZZY_DEBUG=1 gem install --verbose ruzzy

Verification

Verify installation by running the toy example (see Quick Start section).

Writing a Harness

Fuzzing Pure Ruby Code

Pure Ruby fuzzing requires two scripts due to Ruby interpreter implementation details.

Tracer script (test_tracer.rb):

# frozen_string_literal: true

require 'ruzzy'

Ruzzy.trace('test_harness.rb')

Harness script (test_harness.rb):

# frozen_string_literal: true

require 'ruzzy'

def fuzzing_target(input)
  # Your code to fuzz here
  if input.length == 4
    if input[0] == 'F'
      if input[1] == 'U'
        if input[2] == 'Z'
          if input[3] == 'Z'
            raise
          end
        end
      end
    end
  end
end

test_one_input = lambda do |data|
  fuzzing_target(data)
  return 0
end

Ruzzy.fuzz(test_one_input)

Run with:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby test_tracer.rb

Fuzzing Ruby C Extensions

C extensions can be fuzzed with a single harness file, no tracer needed.

Example harness for msgpack (fuzz_msgpack.rb):

# frozen_string_literal: true

require 'msgpack'
require 'ruzzy'

test_one_input = lambda do |data|
  begin
    MessagePack.unpack(data)
  rescue Exception
    # We're looking for memory corruption, not Ruby exceptions
  end
  return 0
end

Ruzzy.fuzz(test_one_input)

Run with:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby fuzz_msgpack.rb

Harness Rules

DoDon't
Catch Ruby exceptions if testing C extensionsLet Ruby exceptions crash the fuzzer
Return 0 from test_one_input lambdaReturn other values
Keep harness deterministicUse randomness or time-based logic
Use tracer script for pure RubySkip tracer for pure Ruby code

See Also: For detailed harness writing techniques, patterns for handling complex inputs, and advanced strategies, see the fuzz-harness-writing technique skill.

Compilation

Installing Gems with Sanitizers

When installing Ruby gems with C extensions for fuzzing, compile with sanitizer flags:

MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
CFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
CXXFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
    gem install <gem-name>

Build Flags

FlagPurpose
-fsanitize=address,fuzzer-no-linkEnable AddressSanitizer and fuzzer instrumentation
-fno-omit-frame-pointerImprove stack trace quality
-fno-commonBetter compatibility with sanitizers
-fPICPosition-independent code for shared libraries
-gInclude debug symbols

Running Campaigns

Environment Setup

Before running any fuzzing campaign, set ASAN_OPTIONS:

export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"

Options explained:

  1. allocator_may_return_null=1: Skip common low-impact allocation failures (DoS)
  2. detect_leaks=0: Ruby interpreter leaks data, ignore these for now
  3. use_sigaltstack=0: Ruby recommends disabling sigaltstack with ASan

Basic Run

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby harness.rb

Note: LD_PRELOAD is required for sanitizer injection. Unlike ASAN_OPTIONS, do not export it as it may interfere with other programs.

With Corpus

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby harness.rb /path/to/corpus

Passing libFuzzer Options

All libFuzzer options can be passed as arguments:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby harness.rb /path/to/corpus -max_len=1024 -timeout=10

See libFuzzer options for full reference.

Reproducing Crashes

Re-run a crash case by passing the crash file:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby harness.rb ./crash-253420c1158bc6382093d409ce2e9cff5806e980

Interpreting Output

OutputMeaning
INFO: Running with entropic power scheduleFuzzing campaign started
ERROR: AddressSanitizer: heap-use-after-freeMemory corruption detected
SUMMARY: libFuzzer: fuzz target exitedRuby exception occurred
artifact_prefix='./'; Test unit written to ./crash-*Crash input saved
Base64: ...Base64 encoding of crash input

Sanitizer Integration

AddressSanitizer (ASan)

Ruzzy includes a pre-compiled AddressSanitizer library:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby harness.rb

Use ASan for detecting:

  • Heap buffer overflows
  • Stack buffer overflows
  • Use-after-free
  • Double-free
  • Memory leaks (disabled by default in Ruzzy)

UndefinedBehaviorSanitizer (UBSan)

Ruzzy also includes UBSan:

LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::UBSAN_PATH') \
    ruby harness.rb

Use UBSan for detecting:

  • Signed integer overflow
  • Null pointer dereferences
  • Misaligned memory access
  • Division by zero

Common Sanitizer Issues

IssueSolution
Ruby interpreter leak warningsUse ASAN_OPTIONS=detect_leaks=0
Sigaltstack conflictsUse ASAN_OPTIONS=use_sigaltstack=0
Allocation failure spamUse ASAN_OPTIONS=allocator_may_return_null=1
LD_PRELOAD interferes with toolsDon't export it; set inline with ruby command

See Also: For detailed sanitizer configuration, common issues, and advanced flags, see the address-sanitizer and undefined-behavior-sanitizer technique skills.

Real-World Examples

Example: msgpack-ruby

Fuzzing the msgpack MessagePack parser for memory corruption.

Install with sanitizers:

MAKE="make --environment-overrides V=1" \
CC="/path/to/clang" \
CXX="/path/to/clang++" \
LDSHARED="/path/to/clang -shared" \
LDSHAREDXX="/path/to/clang++ -shared" \
CFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
CXXFLAGS="-fsanitize=address,fuzzer-no-link -fno-omit-frame-pointer -fno-common -fPIC -g" \
    gem install msgpack

Harness (fuzz_msgpack.rb):

# frozen_string_literal: true

require 'msgpack'
require 'ruzzy'

test_one_input = lambda do |data|
  begin
    MessagePack.unpack(data)
  rescue Exception
    # We're looking for memory corruption, not Ruby exceptions
  end
  return 0
end

Ruzzy.fuzz(test_one_input)

Run:

export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby fuzz_msgpack.rb

Example: Pure Ruby Target

Fuzzing pure Ruby code with a custom parser.

Tracer (test_tracer.rb):

# frozen_string_literal: true

require 'ruzzy'

Ruzzy.trace('test_harness.rb')

Harness (test_harness.rb):

# frozen_string_literal: true

require 'ruzzy'
require_relative 'my_parser'

test_one_input = lambda do |data|
  begin
    MyParser.parse(data)
  rescue StandardError
    # Expected exceptions from malformed input
  end
  return 0
end

Ruzzy.fuzz(test_one_input)

Run:

export ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0"
LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \
    ruby test_tracer.rb

Troubleshooting

ProblemCauseSolution
Installation failsWrong clang version or pathVerify clang path, use clang 14.0.0+
cannot open shared object fileLD_PRELOAD not setSet LD_PRELOAD inline with ruby command
Fuzzer immediately exitsMissing corpus directoryCreate corpus directory or pass as argument
No coverage progressPure Ruby needs tracerUse tracer script for pure Ruby code
Leak detection spamRuby interpreter leaksSet ASAN_OPTIONS=detect_leaks=0
Installation debug neededCompilation errorsUse RUZZY_DEBUG=1 gem install --verbose ruzzy

Related Skills

Technique Skills

SkillUse Case
fuzz-harness-writingDetailed guidance on writing effective harnesses
address-sanitizerMemory error detection during fuzzing
undefined-behavior-sanitizerDetecting undefined behavior in C extensions
libfuzzerUnderstanding libFuzzer options (Ruzzy is built on libFuzzer)

Related Fuzzers

SkillWhen to Consider
libfuzzerWhen fuzzing Ruby C extension code directly in C/C++
aflppAlternative approach for fuzzing Ruby by instrumenting Ruby interpreter

Resources

Key External Resources

Introducing Ruzzy, a coverage-guided Ruby fuzzer Official Trail of Bits blog post announcing Ruzzy, covering motivation, architecture, and initial results.

Ruzzy GitHub Repository Source code, additional examples, and development instructions.

libFuzzer Documentation Since Ruzzy is built on libFuzzer, understanding libFuzzer options and behavior is valuable.

Fuzzing Ruby C extensions Detailed guide on fuzzing C extensions with compilation flags and examples.

Fuzzing pure Ruby code Detailed guide on the tracer pattern required for pure Ruby fuzzing.

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Build and test code with AddressSanitizer, a tool that detects invalid memory access during execution. Configure checks for C/C++ and unsafe Rust, investigate crash reports, and adjust settings for fuzzing, or testing with generated inputs.

中文简介正在准备中。当前显示英语简介。

  • Detect memory errors while fuzzing C/C++
  • Test unsafe Rust and calls to external libraries
  • Interpret an ASan crash report
trailofbits/skills76412026年10月16日 更新

aflpp

免费

Sets up AFL++ to test C/C++ programs with varied generated inputs, a technique called fuzzing. Covers running tests across CPU cores, monitoring progress, reducing input collections, and reproducing crashes for investigation.

中文简介正在准备中。当前显示英语简介。

  • Running C/C++ fuzzing across multiple CPU cores
  • Exploring further after libFuzzer progress stalls
  • Monitoring fuzzing progress and stability
trailofbits/skills76412026年10月16日 更新

Audits GitHub Actions workflows that run AI coding agents. Traces how attacker-controlled content reaches prompts, checks permissions and sandbox settings, and reports evidence, severity, and fixes for prompt injection and related configuration risks.

中文简介正在准备中。当前显示英语简介。

  • Reviewing workflows that run AI coding agents
  • Tracing issue and PR content into agent prompts
  • Checking sandbox settings and user allowlists
trailofbits/skills76412026年10月16日 更新

Reviews Algorand smart contracts written in TEAL or PyTeal for 11 vulnerability patterns. Produces a complete coverage table and findings with code references, severity ratings, and suggested fixes, with optional automated checks using Tealer.

中文简介正在准备中。当前显示英语简介。

  • Security checks before an Algorand contract audit
  • Reviewing TEAL or PyTeal transaction validation
  • Verifying fixes for reported vulnerabilities
trailofbits/skills76412026年10月16日 更新

atheris

免费

Set up Atheris to test Python code and C extensions with automatically varied inputs. It guides test harness creation, coverage tracking to explore more code, and AddressSanitizer setup for finding memory errors.

中文简介正在准备中。当前显示英语简介。

  • Fuzzing a Python package or parser
  • Investigating memory corruption in Python C extensions
  • Turning raw bytes into typed test arguments
trailofbits/skills76412026年10月16日 更新

Connect static analysis results and human audit notes to a Trailmark code graph. Group findings by severity and compare them with input flow, impact, and privilege boundaries to prioritize investigation and understand findings in their code context.

中文简介正在准备中。当前显示英语简介。

  • Connecting Semgrep or CodeQL results to code structure
  • Combining human audit notes with automated findings
  • Prioritizing findings using input flow and impact
trailofbits/skills76412026年10月16日 更新

查看 trailofbits 的全部技能

报告此技能的问题