fuzzbound

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package fuzzbound bounds the resources one parse of attacker-controlled bytes may consume, so that a fuzz target fails on a resource blow-up instead of merely surviving it.

It exists because "did it panic?" is not a strong enough oracle for the parsers that read encrypted documents. The worst bug this module has shipped (C360) was a CFB header field used unvalidated as an allocation size: a 512-byte file drove a 16 GiB allocation. That does not panic. On a large machine it succeeds; on a small one the kernel OOM-kills the process, which a human reads as infrastructure flake rather than as a finding — and Go's fuzzing engine cannot distinguish it from a machine falling over either. Turning it into an assertion failure with a message is the whole point.

Two resources are bounded.

Allocation volume is read from the runtime's cumulative allocation counter (/gc/heap/allocs:bytes), not from resident memory. That is deliberate: a make([]uint32, 0, 1<<32) is served by fresh mmap'd pages that are never touched, so RSS can stay flat while 16 GiB is charged to the heap. The counter records large allocations (>32 KiB, the only ones that matter here) exactly and at the moment they happen. Small allocations are accumulated at span granularity and so are approximate by at most a few tens of KiB, which is immaterial against the budgets below.

Wall-clock time is bounded so that a quadratic or unbounded loop fails as a finding rather than as a package timeout nobody attributes to a parser.

A budget is (fixed floor) + (rate x input size). The floor absorbs the per-call constants — decoder buffers, cipher key schedules, maps — that do not scale with the input; the rate expresses the structural claim that a container cannot cost materially more than a small multiple of its own size.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Measure

func Measure(fn func()) (allocated uint64, elapsed time.Duration)

Measure runs fn and reports how many bytes it allocated and how long it took.

The allocation figure is process-wide for the duration of the call: another goroutine allocating concurrently inflates it. Fuzz workers run one execution at a time, so in practice fn is the only allocator; Budget.Check re-measures before failing to keep a stray concurrent allocation from being reported as a finding.

func Tripped

func Tripped() bool

Tripped reports whether a resource budget has already been exceeded in this process. A fuzz target should consult it before doing the work it measures, so the run that broke the budget is also the last one to allocate.

Types

type Budget

type Budget struct {
	// What names the operation in failure messages, e.g. "readCFB".
	What string

	// Bytes is the allocation allowed regardless of input size, and
	// BytesPerInputByte the allocation allowed per byte of input.
	Bytes             uint64
	BytesPerInputByte uint64

	// Time is the wall clock allowed regardless of input size, and TimePerMiB
	// the wall clock allowed per MiB of input.
	Time       time.Duration
	TimePerMiB time.Duration
}

Budget is what one parse of an n-byte input is allowed to spend.

func (Budget) Allowance

func (b Budget) Allowance(n int) (bytes uint64, dur time.Duration)

Allowance returns the budget for an input of n bytes.

func (Budget) Check

func (b Budget) Check(tb testing.TB, n int, fn func())

Check runs fn over an input of n bytes and fails tb when fn allocates or runs longer than the budget allows.

fn must be repeatable: a near-miss is measured a second time and reported only if the second measurement also breaks the budget. That costs nothing on the overwhelmingly common in-budget path and keeps a stray concurrent allocation from being reported as a parser bug, while a blow-up (grossFactor times the budget or more) is reported from the first measurement.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL