Skip to content

Add OSS-Fuzz integration for msgpack-ruby#15340

Open
tranquac wants to merge 1 commit intogoogle:masterfrom
tranquac:add-msgpack-ruby-fuzzing
Open

Add OSS-Fuzz integration for msgpack-ruby#15340
tranquac wants to merge 1 commit intogoogle:masterfrom
tranquac:add-msgpack-ruby-fuzzing

Conversation

@tranquac
Copy link
Copy Markdown

@tranquac tranquac commented Apr 11, 2026

Project

msgpack-ruby — the Ruby gem for the MessagePack binary serialization format.

  • Repo: https://github.com/msgpack/msgpack-ruby
  • Downloads: 468M+ lifetime (~20M/month), used in Rails, Sidekiq, Redis protocol serializers
  • C extension: ext/msgpack/ — 12 source files, ~3,945 LOC
  • OSS-Fuzz coverage: msgpack-c on OSS-Fuzz covers a C++ header-only library; msgpack-ruby's C extension is completely independent code not covered by any existing project

Fuzz targets

fuzz_unpackMessagePack.unpack API variants

Exercises factory_class.c → unpacker_class.c → unpacker.c with 5 option combinations:

  • Default path
  • symbolize_keys: truerb_str_intern() on every map key
  • freeze: truerb_obj_freeze() on each object
  • allow_unknown_ext: trueExtensionValue construction path
  • key_cache: truerstring_cache_fetch / build_interned_string (sorted VALUE array + MEMMOVE in buffer.h)

fuzz_unpack_stream — Streaming Unpacker API

Exercises unpacker_class.c streaming methods with 5 variants:

  • Unpacker#feed_each (default)
  • feed_each with symbolize_keys: true
  • feed + each (iterator path)
  • feed + loop { read } (direct Unpacker_read path)
  • feed_each with key_cache: true

Local test results

build_image:   SUCCESS
build_fuzzers: SUCCESS (address sanitizer)
check_build:   PASSED

fuzz_unpack:        INITED cov: 41 ft: 42 — coverage growing
fuzz_unpack_stream: INITED cov: 128 ft: 148 — coverage growing (dict active)

Known finding: DoS via unchecked pre-allocation

Both fuzz targets consistently discover a resource exhaustion condition:

ERROR: libFuzzer: out-of-memory (malloc(3758149315))

Root cause: ext/msgpack/unpacker.c:339 calls rb_str_buf_new(length) where length comes directly from the msgpack header (str32/bin32 can specify up to 4GB). This allocation happens before checking whether that much data is available in the buffer. A 5-byte crafted message can force a 4GB allocation attempt, causing server-side OOM/DoS.

This is an intentional finding — the harnesses are configured with rss_limit_mb=4096 (via .options files) to allow the fuzzer to continue beyond this known condition and discover additional bugs (memory corruption, use-after-free) in the C extension.

Maintainer acknowledgment

Upstream issue: msgpack/msgpack-ruby#388

@github-actions
Copy link
Copy Markdown

tranquac is integrating a new project:
- Main repo: https://github.com/msgpack/msgpack-ruby
- Criticality score: 0.53187
tranquac is integrating a new project:
- Main repo: https://github.com/msgpack/msgpack-ruby
- Criticality score: 0.53187

@tranquac tranquac force-pushed the add-msgpack-ruby-fuzzing branch from f717ed3 to 854068a Compare April 11, 2026 16:26
@byroot
Copy link
Copy Markdown

byroot commented Apr 11, 2026

LGTM

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