Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What the fuzz?

What the fuzz?

Fuzz testing of Go programs.

Alexey Palazhchenko

May 25, 2017
Tweet

More Decks by Alexey Palazhchenko

Other Decks in Programming

Transcript

  1. Types of testing data • Well-known normal data • Well-known

    corner cases • Well-known fixed bugs
  2. Types of testing data • Well-known normal data • Well-known

    corner cases • Well-known fixed bugs • Unknown random data
  3. • May not be deterministic • Requires good spec
 («it’s

    a feature, not a bug») • Requires a lot of brute force Testing with random data • Cheap • Fast • Not biased
  4. • We can rewrite our code just like cover tool

    does • We can use code coverage information to reduce input while keeping the same coverage, then mutate it until we get new coverage How can we do better?
  5. • We can rewrite our code just like cover tool

    does • We can use code coverage information to reduce input while keeping the same coverage, then mutate it until we get new coverage • We can use MORE POWER!!1 How can we do better? © Randall Munroe https://what-if.xkcd.com/13/
  6. In a nutshell Instrument program Collect initial corpus, reduce it

    for { Apply random mutation to input Check coverage If gives new coverage, try to reduce input, then add to corpus }
  7. Get it • $ go get github.com/dvyukov/go-fuzz/go-fuzz • ☕ •

    $ go get github.com/dvyukov/go-fuzz/go-fuzz-build
  8. // +build gofuzz func Fuzz(data []byte) int { _, err

    := handle(data) if err != nil { return 0 } return 1 }
  9. Fuzz: basic rules • Return 1 if data happens to

    be correct • Panic in case of unexpected error
  10. Fuzz: basic rules • Return 1 if data happens to

    be correct • Panic in case of unexpected error • Return 0 otherwise
  11. Fuzz: basic rules • Return 1 if data happens to

    be correct • Panic in case of unexpected error • Return 0 otherwise • No external state!
  12. Fuzz: basic rules • Return 1 if data happens to

    be correct • Panic in case of unexpected error • Return 0 otherwise • No external state! • Log only before panic
  13. Fuzz: basic rules • Return 1 if data happens to

    be correct • Panic in case of unexpected error • Return 0 otherwise • No external state! • Log only before panic • That’s ok for function to hang or eat a lot of memory
  14. Fuzz: basic rules • Return 1 if data happens to

    be correct • Panic in case of unexpected error • Return 0 otherwise • No external state! • Log only before panic • That’s ok for function to hang or eat a lot of memory • Use build tag
  15. Initial corpus collection • Small and diverse • Diversity is

    more important • Use data from unit tests!
  16. Run it • $ go-fuzz-build package • Fill workdir/corpus with

    files • $ go-fuzz -bin=package-fuzz.zip -workdir=workdir
  17. Run it • $ go-fuzz-build package • Fill workdir/corpus with

    files • $ go-fuzz -bin=package-fuzz.zip -workdir=workdir • See results in workdir/crashes
  18. Run it • $ go-fuzz-build package • Fill workdir/corpus with

    files • $ go-fuzz -bin=package-fuzz.zip -workdir=workdir • See results in workdir/crashes • Consider adding workdir/corpus to VCS
  19. Fuzz: logic checks • Decode, encode, compare bytes • Decode,

    encode, decode, compare objects • Cross-check with different implementations
 (simple/slow vs fast/sophisticated)
  20. res, err := decode(data) if err != nil { return

    0 } b, err := encode(res) if err != nil { panic(err) } if !reflect.DeepEqual(b, res) { panic(b) } return 1
  21. Fuzz: custom types • When fuzzer gives you lemons bytes,


    make your types • Custom decode function is often better that generic
  22. Fuzz: custom types • When fuzzer gives you lemons bytes,


    make your types • Custom decode function is often better that generic • If you have checksums, append them yourself
  23. if len(data) != 8 { return 0 } i1, err1

    := strconv.Atoi(string(data[:4])) i2, err2 := strconv.Atoi(string(data[4:])) if err1 != nil || err2 != nil { return 0 } // work with i1 and i2
  24. A lot of fancy stuff • Versifier – reverse-engineers text

    protocol and learns its structure, makes structural mutations • Sonar – could help with stuff like checksums, but now public API yet
  25. MORE POWER!!1 • Reuses single process • Forks it for

    faster startup • A lot of concurrency • Distributed across machines © Randall Munroe https://what-if.xkcd.com/13/
  26. ?