cautiouspancake

package module
v0.0.0-...-46d3c96 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2023 License: BSD-3-Clause Imports: 10 Imported by: 0

README

cautious-pancake

GoDoc Go Report Card

github generated the repo name for me

fuzzing

cautious-pancake aims to make fuzzing golang packages easier by identifying pure functions. These functions can be easily fuzzed since they only operate on their direct inputs and do not modify global state.

example

pancakeinfo

Given a package, pancakeinfo will tell you which functions are pure:

$ go get -u github.com/tam7t/cautious-pancake/cmd/pancakeinfo
$ pancakeinfo -pkg=github.com/mdlayher/arp
(Operation).String
NewPacket
(Client).HardwareAddr
(*Packet).UnmarshalBinary
(*Packet).MarshalBinary

The -pure=false flag will return all functions deemed impure, including the reason for the determination and the -private flag will display information on private functions as well.

pancakegen

Given a package and a function, pancakegen will generate code to fuzz that function:

$ go get -u github.com/tam7t/cautious-pancake/cmd/pancakegen
$ pancakegen -pkg=github.com/tam7t/cautious-pancake/fixtures -func=YesMaybePanic
package fixtures

import (
	"testing"
)

func FuzzYesMaybePanic(f *testing.F) {
	f.Fuzz(func(t *testing.T, p0 byte) { 
		YesMaybePanic(p0)
	})
}

If you run the generated code you will quickly get:

$ go test ./fixtures/... --fuzz=Fuzz
fuzz: elapsed: 0s, gathering baseline coverage: 0/1 completed
fuzz: elapsed: 0s, gathering baseline coverage: 1/1 completed, now fuzzing with 16 workers
fuzz: elapsed: 0s, execs: 20 (701/sec), new interesting: 0 (total: 1)
--- FAIL: FuzzYesMaybePanic (0.03s)
    --- FAIL: FuzzYesMaybePanic (0.00s)
        testing.go:1349: panic: bad input
            goroutine 35 [running]:
            runtime/debug.Stack()
                /usr/local/go/src/runtime/debug/stack.go:24 +0x90
            testing.tRunner.func1()
                /usr/local/go/src/testing/testing.go:1349 +0x1f2
            panic({0x65dd40, 0x6ee3e0})
                /usr/local/go/src/runtime/panic.go:838 +0x207
            github.com/tam7t/cautious-pancake/fixtures.YesMaybePanic(...)
                /home/tam7t/code/github.com/tam7t/cautious-pancake/fixtures/fuzzable.go:97
            github.com/tam7t/cautious-pancake/fixtures.FuzzYesMaybePanic.func1(0x0?, 0xa)
                /home/tam7t/code/github.com/tam7t/cautious-pancake/fixtures/fuzzable_test.go:9 +0x77
            reflect.Value.call({0x660400?, 0x6b5f98?, 0x13?}, {0x69f589, 0x4}, {0xc00009bc80, 0x2, 0x2?})
                /usr/local/go/src/reflect/value.go:556 +0x845
            reflect.Value.Call({0x660400?, 0x6b5f98?, 0x514?}, {0xc00009bc80, 0x2, 0x2})
                /usr/local/go/src/reflect/value.go:339 +0xbf
            testing.(*F).Fuzz.func1.1(0x0?)
                /usr/local/go/src/testing/fuzz.go:337 +0x231
            testing.tRunner(0xc0001a16c0, 0xc00018aea0)
                /usr/local/go/src/testing/testing.go:1439 +0x102
            created by testing.(*F).Fuzz.func1
                /usr/local/go/src/testing/fuzz.go:324 +0x5b8
            
    
    Failing input written to testdata/fuzz/FuzzYesMaybePanic/358fa4d16da00de4d29482b2ea74da673eb27bfc5614d2b123ac0aa89e0e1ea5
    To re-run:
    go test -run=FuzzYesMaybePanic/358fa4d16da00de4d29482b2ea74da673eb27bfc5614d2b123ac0aa89e0e1ea5
FAIL
exit status 1
FAIL    github.com/tam7t/cautious-pancake/fixtures      0.032s

indicating that fixtures.YesMaybePanic(0xA) will result in a panic.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// DefaultIgnoreCall lists functions that should be ignored when
	// determining if a function is pure. These calls may technically access
	// or modify global state, but the side effects are rarely important.
	DefaultIgnoreCall = map[string][]string{
		"log": {"Print", "Printf", "Println"},
		"fmt": {"Print", "Printf", "Println", "Errorf"},
	}

	// DefaultIgnoreRead lists global variables that should be ignored
	// when determining if a function is pure. These variables may
	// change values between function calls, but in practice are most
	// often used as constants.
	DefaultIgnoreRead = map[string][]string{
		"encoding/binary": {"BigEndian", "LittleEndian"},
	}
)

Functions

func GenerateFuzz

func GenerateFuzz(f *ssa.Function) string

Types

type CallGraph

type CallGraph struct {
	Prog       *loader.Program
	CallGraph  *callgraph.Graph
	Mapping    map[*ssa.Function]*Node
	IgnoreCall map[string][]string
	IgnoreRead map[string][]string
}

CallGraph keeps track of 'pure' and function

func NewCallGraph

func NewCallGraph(iprog *loader.Program) *CallGraph

NewCallGraph creates a CallGraph by performing ssa analysis

func (*CallGraph) Analyze

func (cg *CallGraph) Analyze() error

Analyze examines the callgraph looking for functions that modify global state or call functions that modify global state.

func (*CallGraph) Impure

func (cg *CallGraph) Impure() []*ssa.Function

Impure returns a slice of the ssa representations of the impure functions in the analyzed package

func (*CallGraph) Lookup

func (cg *CallGraph) Lookup(name string) (*ssa.Function, bool)

Lookup lookup a function in the CallGraph by name and return whether it is pure.

func (*CallGraph) Pure

func (cg *CallGraph) Pure() []*ssa.Function

Pure returns a slice of the ssa representations of the pure functions in the analyzed package

type Node

type Node struct {
	CallGraph     *CallGraph
	RuleBasic     *token.Pos
	RuleInterface *token.Pos
	RuleCallee    *ssa.Function
}

Node contains details on why a function is marked as not pure

func (*Node) Pure

func (n *Node) Pure() bool

Pure returns whether an analyzed node is pure.

func (*Node) Reason

func (n *Node) Reason() (string, string)

Reason returns descriptive strings for why a node is not pure.

func (*Node) String

func (n *Node) String() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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