fuzz

package
v0.0.0-...-255e35d Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2024 License: Apache-2.0 Imports: 6 Imported by: 0

README

Fuzzing Istio Code

The Istio (Go) code base is fuzzed using native Go fuzzing. For general docs on how to fuzz in Go, see Getting started with fuzzing.

Writing a test

Generally, writing a fuzz test for Istio is the same as any other Go program. However, because most of our fuzzing is based on complex structs rather than the primitives Go supports natively, the pkg/fuzz package contains a number of helpers to fuzz.

Here is an example:

// Define a new fuzzer. Must have Fuzz prefix
func FuzzBuildHTTP(f *testing.F) {
  fuzz.Fuzz(f, func(fg fuzz.Helper) {
    // Setup a few structs for testing
    bundle := fuzz.Struct[trustdomain.Bundle](fg)
        // This one has a custom validator
    push := fuzz.Struct[*model.PushContext](fg, validatePush)
        // *model.Proxy, and other types, implement the fuzz.Validator interface and already validate some basics.
    node := fuzz.Struct[*model.Proxy](fg)
    selectionOpts := model.WorkloadSelectionOpts{
      Namespace:       node.ConfigNamespace,
      WorkloadLabels:  node.Labels,
    }
    option := fuzz.Struct[Option](fg)

    // Run our actual test code. In this case, we are just checking nothing crashes.
    // In other tests, explicit assertions may be helpful.
    policies := push.AuthzPolicies.ListAuthorizationPolicies(selectionOpts)
    New(bundle, push, policies, option).BuildHTTP()
  })
}

Running tests

Fuzz tests can be run using standard Go tooling:

go test ./path/to/pkg -v -run=^$ -fuzz=Fuzz

CI testing

Go fuzzers are run as part of standard unit tests against known test cases (from f.Add (which fuzz.BaseCases calls), or testdata). For continuous fuzzing, OSS-Fuzz continually builds and runs the fuzzers and reports any failures. These results are private to the Istio Product Security WG until disclosed.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BaseCases

func BaseCases(f test.Fuzzer)

BaseCases inserts a few trivial test cases to do a very brief sanity check of a test that relies on []byte inputs

func Finalize

func Finalize()

Finalize works around an issue in the oss-fuzz logic that doesn't allow using Skip() Instead, we send a panic which we handle and treat as skip. https://github.com/AdamKorcz/go-118-fuzz-build/issues/6

func Fuzz

func Fuzz(f test.Fuzzer, ff func(fg Helper))

Fuzz is a wrapper around:

 fuzz.BaseCases(f)
	f.Fuzz(func(...) {
	   defer fuzz.Finalizer()
	}

To avoid needing to call BaseCases and Finalize everywhere.

func Slice

func Slice[T any](h Helper, count int, validators ...func(T) bool) []T

Slice generates a slice of Structs

func Struct

func Struct[T any](h Helper, validators ...func(T) bool) T

Struct generates a Struct. Validation patterns can be passed in - if any return false, the fuzz case is skipped. Additionally, if the T implements Validator, it will implicitly be used.

Types

type Helper

type Helper struct {
	// contains filtered or unexported fields
}

Helper is a helper struct for fuzzing

func New

func New(t test.Failer, data []byte) Helper

New creates a new fuzz.Helper, capable of generating more complex types

func (Helper) T

func (h Helper) T() test.Failer

T Returns the underlying test.Failer. Should be avoided where possible; in oss-fuzz many functions do not work.

type Validator

type Validator interface {
	// FuzzValidate returns true if the current struct is valid for fuzzing.
	FuzzValidate() bool
}

Jump to

Keyboard shortcuts

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