default to compile in, but also allow plugins

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
Vincent Batts 2018-06-06 12:29:33 -04:00
parent 4e78ffab6a
commit 66e91e3ddf
Signed by: vbatts
GPG key ID: 10937E57733F1362
13 changed files with 170 additions and 63 deletions

View file

@ -5,9 +5,11 @@ SOURCE_FILES := \
$(wildcard walker/*.go) \ $(wildcard walker/*.go) \
$(wildcard walker/walkers/*/*.go) $(wildcard walker/walkers/*/*.go)
PLUGINS := \ PLUGINS := \
$(patsubst walker/walkers/%,plugin-%.so,$(wildcard walker/walkers/*)) $(patsubst walker/walkers/%/plugin.go,plugin-%.so,$(wildcard walker/walkers/*/plugin.go))
default: fuzz-walker $(PLUGINS) default: fuzz-walker
plugins: $(PLUGINS)
fuzz-walker: $(wildcard *.go) fuzz-walker: $(wildcard *.go)
$(GO) build -o $@ . $(GO) build -o $@ .

19
main.go
View file

@ -9,10 +9,13 @@ import (
"git.thisco.de/vbatts/fuzz-walker/walker" "git.thisco.de/vbatts/fuzz-walker/walker"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
)
// This list is populated in the beforefunc of the application _ "git.thisco.de/vbatts/fuzz-walker/walker/walkers/chmodFuzz"
var walkerPlugins []walker.Fuzzer _ "git.thisco.de/vbatts/fuzz-walker/walker/walkers/ioctlFuzz"
_ "git.thisco.de/vbatts/fuzz-walker/walker/walkers/readFuzz"
_ "git.thisco.de/vbatts/fuzz-walker/walker/walkers/writeBytesFuzz"
_ "git.thisco.de/vbatts/fuzz-walker/walker/walkers/writeNumFuzz"
)
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
@ -28,7 +31,7 @@ func main() {
if err != nil { if err != nil {
return err return err
} }
walkerPlugins = append(walkerPlugins, ff) walker.RegisterFuzzFunc(ff.Name(), ff.Func)
} }
return nil return nil
} }
@ -60,18 +63,18 @@ func main() {
return err return err
} }
for _, wp := range walkerPlugins { for fname, ffunc := range walker.FuncMap() {
c1 := make(chan error, 1) c1 := make(chan error, 1)
go func() { go func() {
c1 <- wp.Func(path, info, c.Duration("timeout")*time.Millisecond) c1 <- ffunc(path, info)
}() }()
select { select {
case err := <-c1: case err := <-c1:
if err != nil { if err != nil {
logrus.Warnf("%s: %q fuzz failed with: %v", path, wp.Name(), err) logrus.Warnf("%s: %q fuzz failed with: %v", path, fname, err)
} }
case <-time.After(c.Duration("timeout") * time.Millisecond): case <-time.After(c.Duration("timeout") * time.Millisecond):
logrus.Warnf("%s: %q fuzz timed out", path, wp.Name()) logrus.Warnf("%s: %q fuzz timed out", path, fname)
} }
} }
return nil return nil

View file

@ -4,10 +4,31 @@ import (
"fmt" "fmt"
"os" "os"
"plugin" "plugin"
"time" "sync"
) )
// LoadPlugin loads the file path and returns a Fuzzer // RegisterFuzzFunc is for static linking (not plugin) model
func RegisterFuzzFunc(name string, fnc FuzzFunc) error {
ffLock.Lock()
defer ffLock.Unlock()
if _, ok := fuzzfuncs[name]; ok {
// maybe just output a warning and not bail here?
return fmt.Errorf("RegisterFuzzFunc: %q is already registered", name)
}
fuzzfuncs[name] = fnc
return nil
}
func FuncMap() map[string]FuzzFunc {
return fuzzfuncs
}
var fuzzfuncs = map[string]FuzzFunc{}
var ffLock sync.Mutex
// LoadPlugin loads the file path and returns a Fuzzer.
//
// This is only for making a plugin.
func LoadPlugin(path string) (Fuzzer, error) { func LoadPlugin(path string) (Fuzzer, error) {
p, err := plugin.Open(path) p, err := plugin.Open(path)
if err != nil { if err != nil {
@ -24,14 +45,18 @@ func LoadPlugin(path string) (Fuzzer, error) {
return nf() return nf()
} }
// NewFuzzer initializes a new Fuzzer // NewFuzzer initializes a new Fuzzer.
//
// This is only for making a plugin.
type NewFuzzer func() (Fuzzer, error) type NewFuzzer func() (Fuzzer, error)
// Fuzzer is a struct that produces a FuzzFunc // Fuzzer is a struct that produces a FuzzFunc.
//
// This is only for making a plugin.
type Fuzzer interface { type Fuzzer interface {
Name() string Name() string
Func(path string, info os.FileInfo, timeout time.Duration) error Func(path string, info os.FileInfo) error
} }
// FuzzFunc is like filepath.WalkerFunc, but for poking at `path` // FuzzFunc is like filepath.WalkerFunc, but for poking at `path`
type FuzzFunc func(path string, info os.FileInfo, timeout time.Duration) error type FuzzFunc func(path string, info os.FileInfo) error

View file

@ -0,0 +1,17 @@
package chmodFuzz
import (
"os"
"git.thisco.de/vbatts/fuzz-walker/walker"
)
func init() {
walker.RegisterFuzzFunc(Name, FuzzFunc)
}
const Name = "chmodFuzz"
func FuzzFunc(path string, info os.FileInfo) error {
return nil
}

View file

@ -1,3 +1,5 @@
// +build ignore
package main package main
import ( import (
@ -5,6 +7,7 @@ import (
"time" "time"
"git.thisco.de/vbatts/fuzz-walker/walker" "git.thisco.de/vbatts/fuzz-walker/walker"
"git.thisco.de/vbatts/fuzz-walker/walker/walkers/chmodFuzz"
) )
// NewFuzzer creates the fuzzer for this plugin // NewFuzzer creates the fuzzer for this plugin
@ -15,9 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) {
type myFuzzer struct{} type myFuzzer struct{}
func (mf myFuzzer) Name() string { func (mf myFuzzer) Name() string {
return "chmodFuzz" return chmodFuzz.Name
} }
func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error {
return nil return chmodFuzz.Func(path, info)
} }

View file

@ -0,0 +1,17 @@
package ioctlFuzz
import (
"os"
"git.thisco.de/vbatts/fuzz-walker/walker"
)
func init() {
walker.RegisterFuzzFunc(Name, FuzzFunc)
}
const Name = "ioctlFuzz"
func FuzzFunc(path string, info os.FileInfo) error {
return nil
}

View file

@ -1,3 +1,5 @@
// +build ignore
package main package main
import ( import (
@ -5,6 +7,7 @@ import (
"time" "time"
"git.thisco.de/vbatts/fuzz-walker/walker" "git.thisco.de/vbatts/fuzz-walker/walker"
"git.thisco.de/vbatts/fuzz-walker/walker/walkers/ioctlFuzz"
) )
// NewFuzzer creates the fuzzer for this plugin // NewFuzzer creates the fuzzer for this plugin
@ -15,14 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) {
type myFuzzer struct{} type myFuzzer struct{}
func (mf myFuzzer) Name() string { func (mf myFuzzer) Name() string {
return "ioctlFuzz" return ioctlFuzz.Name
} }
func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error {
// check whether it is a device file return ioctlFuzz.Func(path, info)
//if !info.Mode().IsRegular() {
// return nil
//}
return nil
} }

View file

@ -0,0 +1,30 @@
package readFuzz
import (
"io"
"io/ioutil"
"os"
"git.thisco.de/vbatts/fuzz-walker/walker"
)
func init() {
walker.RegisterFuzzFunc(Name, FuzzFunc)
}
const Name = "readFuzz"
func FuzzFunc(path string, info os.FileInfo) error {
if !info.Mode().IsRegular() {
return nil
}
fd, err := os.Open(path)
if err != nil {
return err
}
defer fd.Close()
_, err = io.Copy(ioutil.Discard, fd)
return err
}

View file

@ -1,12 +1,12 @@
// +build ignore
package main package main
import ( import (
"io"
"io/ioutil"
"os" "os"
"time"
"git.thisco.de/vbatts/fuzz-walker/walker" "git.thisco.de/vbatts/fuzz-walker/walker"
"git.thisco.de/vbatts/fuzz-walker/walker/walkers/readFuzz"
) )
// NewFuzzer creates the fuzzer for this plugin // NewFuzzer creates the fuzzer for this plugin
@ -17,20 +17,9 @@ func NewFuzzer() (walker.Fuzzer, error) {
type myFuzzer struct{} type myFuzzer struct{}
func (mf myFuzzer) Name() string { func (mf myFuzzer) Name() string {
return "readFuzz" return readFuzz.Name
} }
func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { func (mf myFuzzer) Func(path string, info os.FileInfo) error {
if !info.Mode().IsRegular() { return readFuzz.FuzzFunc(path, info)
return nil
}
fd, err := os.Open(path)
if err != nil {
return err
}
defer fd.Close()
_, err = io.Copy(ioutil.Discard, fd)
return err
} }

View file

@ -0,0 +1,17 @@
package writeBytesFuzz
import (
"os"
"git.thisco.de/vbatts/fuzz-walker/walker"
)
func init() {
walker.RegisterFuzzFunc(Name, FuzzFunc)
}
const Name = "writeBytesFuzz"
func FuzzFunc(path string, info os.FileInfo) error {
return nil
}

View file

@ -1,3 +1,5 @@
// +build ignore
package main package main
import ( import (
@ -5,6 +7,7 @@ import (
"time" "time"
"git.thisco.de/vbatts/fuzz-walker/walker" "git.thisco.de/vbatts/fuzz-walker/walker"
"git.thisco.de/vbatts/fuzz-walker/walker/walkers/writeBytesFuzz"
) )
// NewFuzzer creates the fuzzer for this plugin // NewFuzzer creates the fuzzer for this plugin
@ -15,18 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) {
type myFuzzer struct{} type myFuzzer struct{}
func (mf myFuzzer) Name() string { func (mf myFuzzer) Name() string {
return "writeBytesFuzz" return writeBytesFuzz.Name
} }
func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error {
if !info.Mode().IsRegular() { return writeBytesFuzz.Func(path, info)
return nil
}
fd, err := os.Open(path)
if err != nil {
return err
}
defer fd.Close()
return nil
} }

View file

@ -0,0 +1,17 @@
package writeNumFuzz
import (
"os"
"git.thisco.de/vbatts/fuzz-walker/walker"
)
func init() {
walker.RegisterFuzzFunc(Name, FuzzFunc)
}
const Name = "writeNumFuzz"
func FuzzFunc(path string, info os.FileInfo) error {
return nil
}

View file

@ -1,3 +1,5 @@
// +build ignore
package main package main
import ( import (
@ -5,6 +7,7 @@ import (
"time" "time"
"git.thisco.de/vbatts/fuzz-walker/walker" "git.thisco.de/vbatts/fuzz-walker/walker"
"git.thisco.de/vbatts/fuzz-walker/walker/walkers/writeNumFuzz"
) )
// NewFuzzer creates the fuzzer for this plugin // NewFuzzer creates the fuzzer for this plugin
@ -15,17 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) {
type myFuzzer struct{} type myFuzzer struct{}
func (mf myFuzzer) Name() string { func (mf myFuzzer) Name() string {
return "writeNumFuzz" return writeNumFuzz.Name
} }
func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error {
if !info.Mode().IsRegular() { return writeNumFuzz.Func(path, info)
return nil
}
fd, err := os.Open(path)
if err != nil {
return err
}
defer fd.Close()
return nil
} }