mirror of
https://github.com/taigrr/gopher-os
synced 2025-01-18 04:43:13 -08:00
acpi: add Makefile target for fuzzing and AML parser fuzzer
The fuzzer can be invoked by running: "make test-fuzz". The AML parser test suite has been augmented with a special "TestParserCrashers" function that can be used to replay corpuses identified by go-fuzz as causing parser crashes. The test can be invoked as: go test -v -run TestParserCrashers -aml-replace-crashers-from $BUILD/fuzz/corpus/src_gopheros_device_acpi_aml/crashers where $BUILD is the output directory (default: build/) defined in the Makefile.
This commit is contained in:
40
src/gopheros/device/acpi/aml/parser_fuzz.go
Normal file
40
src/gopheros/device/acpi/aml/parser_fuzz.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// +build gofuzz
|
||||
//
|
||||
// The following lines contain paths to interesting corpus data and will be
|
||||
// automatically grepped and copied by the Makefile when fuzzing.
|
||||
//
|
||||
//go-fuzz-corpus+=src/gopheros/device/acpi/table/tabletest/DSDT.aml
|
||||
//go-fuzz-corpus+=src/gopheros/device/acpi/table/tabletest/parser-testsuite-DSDT.aml
|
||||
|
||||
package aml
|
||||
|
||||
import (
|
||||
"gopheros/device/acpi/table"
|
||||
"io/ioutil"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Fuzz is the driver for go-fuzz. The function must return 1 if the fuzzer
|
||||
// should increase priority of the given input during subsequent fuzzing (for
|
||||
// example, the input is lexically correct and was parsed successfully); -1 if
|
||||
// the input must not be added to corpus even if gives new coverage; and 0
|
||||
// otherwise; other values are reserved for future use.
|
||||
func Fuzz(data []byte) int {
|
||||
// Setup SDT header pointing to data
|
||||
headerLen := unsafe.Sizeof(table.SDTHeader{})
|
||||
stream := make([]byte, int(headerLen)+len(data))
|
||||
copy(stream[headerLen:], data)
|
||||
|
||||
header := (*table.SDTHeader)(unsafe.Pointer(&stream[0]))
|
||||
header.Signature = [4]byte{'D', 'S', 'D', 'T'}
|
||||
header.Length = uint32(len(stream))
|
||||
header.Revision = 2
|
||||
|
||||
tree := NewObjectTree()
|
||||
tree.CreateDefaultScopes(0)
|
||||
if err := NewParser(ioutil.Discard, tree).ParseAML(uint8(1), "DSDT", header); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
@@ -16,9 +16,41 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
regenExpFiles = flag.Bool("aml-regenerate-parser-exp-files", false, "Regenerate the expected output files for AML parser tests against real AML files")
|
||||
regenExpFiles = flag.Bool("aml-regenerate-parser-exp-files", false, "Regenerate the expected output files for AML parser tests against real AML files")
|
||||
replayCrashersFrom = flag.String("aml-replay-crashers-from", "", "Replay go-fuzz generated crasher files from this folder")
|
||||
)
|
||||
|
||||
// TestParserCrashers scans through the crasher corpus generated by go-fuzz and
|
||||
// pipes each corpus through the AML parser.
|
||||
func TestParserCrashers(t *testing.T) {
|
||||
if *replayCrashersFrom == "" {
|
||||
t.Skip("-aml-replay-crashers-from not specified; skipping")
|
||||
return
|
||||
}
|
||||
|
||||
fuzzFiles, err := filepath.Glob(filepath.Join(*replayCrashersFrom, "*"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, fuzzFile := range fuzzFiles {
|
||||
// corpus files lack an extension
|
||||
if filepath.Ext(fuzzFile) != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(fuzzFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("trying to parse crash corpus: %q", fuzzFile)
|
||||
p, resolver := parserForMockPayload(t, data)
|
||||
_ = p.ParseAML(0, "DSDT", resolver.LookupTable("DSDT"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
flag.Parse()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user