diff --git a/Makefile b/Makefile index a40527c..1dcd924 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,11 @@ SOURCE_FILES := \ $(wildcard walker/*.go) \ $(wildcard walker/walkers/*/*.go) 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) $(GO) build -o $@ . diff --git a/main.go b/main.go index 338dbc5..77f68d8 100644 --- a/main.go +++ b/main.go @@ -9,10 +9,13 @@ import ( "git.thisco.de/vbatts/fuzz-walker/walker" "github.com/sirupsen/logrus" "github.com/urfave/cli" -) -// This list is populated in the beforefunc of the application -var walkerPlugins []walker.Fuzzer + _ "git.thisco.de/vbatts/fuzz-walker/walker/walkers/chmodFuzz" + _ "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() { app := cli.NewApp() @@ -28,7 +31,7 @@ func main() { if err != nil { return err } - walkerPlugins = append(walkerPlugins, ff) + walker.RegisterFuzzFunc(ff.Name(), ff.Func) } return nil } @@ -60,18 +63,18 @@ func main() { return err } - for _, wp := range walkerPlugins { + for fname, ffunc := range walker.FuncMap() { c1 := make(chan error, 1) go func() { - c1 <- wp.Func(path, info, c.Duration("timeout")*time.Millisecond) + c1 <- ffunc(path, info) }() select { case err := <-c1: 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): - logrus.Warnf("%s: %q fuzz timed out", path, wp.Name()) + logrus.Warnf("%s: %q fuzz timed out", path, fname) } } return nil diff --git a/walker/func.go b/walker/func.go index 95d2124..2c44d44 100644 --- a/walker/func.go +++ b/walker/func.go @@ -4,10 +4,31 @@ import ( "fmt" "os" "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) { p, err := plugin.Open(path) if err != nil { @@ -24,14 +45,18 @@ func LoadPlugin(path string) (Fuzzer, error) { return nf() } -// NewFuzzer initializes a new Fuzzer +// NewFuzzer initializes a new Fuzzer. +// +// This is only for making a plugin. 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 { 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` -type FuzzFunc func(path string, info os.FileInfo, timeout time.Duration) error +type FuzzFunc func(path string, info os.FileInfo) error diff --git a/walker/walkers/chmodFuzz/fuzz.go b/walker/walkers/chmodFuzz/fuzz.go new file mode 100644 index 0000000..cf42300 --- /dev/null +++ b/walker/walkers/chmodFuzz/fuzz.go @@ -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 +} diff --git a/walker/walkers/chmodFuzz/plugin.go b/walker/walkers/chmodFuzz/plugin.go index 41430b0..37ff0c2 100644 --- a/walker/walkers/chmodFuzz/plugin.go +++ b/walker/walkers/chmodFuzz/plugin.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( @@ -5,6 +7,7 @@ import ( "time" "git.thisco.de/vbatts/fuzz-walker/walker" + "git.thisco.de/vbatts/fuzz-walker/walker/walkers/chmodFuzz" ) // NewFuzzer creates the fuzzer for this plugin @@ -15,9 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) { type myFuzzer struct{} func (mf myFuzzer) Name() string { - return "chmodFuzz" + return chmodFuzz.Name } func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { - return nil + return chmodFuzz.Func(path, info) } diff --git a/walker/walkers/ioctlFuzz/fuzz.go b/walker/walkers/ioctlFuzz/fuzz.go new file mode 100644 index 0000000..f5660b8 --- /dev/null +++ b/walker/walkers/ioctlFuzz/fuzz.go @@ -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 +} diff --git a/walker/walkers/ioctlFuzz/plugin.go b/walker/walkers/ioctlFuzz/plugin.go index 57803b5..329f050 100644 --- a/walker/walkers/ioctlFuzz/plugin.go +++ b/walker/walkers/ioctlFuzz/plugin.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( @@ -5,6 +7,7 @@ import ( "time" "git.thisco.de/vbatts/fuzz-walker/walker" + "git.thisco.de/vbatts/fuzz-walker/walker/walkers/ioctlFuzz" ) // NewFuzzer creates the fuzzer for this plugin @@ -15,14 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) { type myFuzzer struct{} func (mf myFuzzer) Name() string { - return "ioctlFuzz" + return ioctlFuzz.Name } func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { - // check whether it is a device file - //if !info.Mode().IsRegular() { - // return nil - //} - - return nil + return ioctlFuzz.Func(path, info) } diff --git a/walker/walkers/readFuzz/fuzz.go b/walker/walkers/readFuzz/fuzz.go new file mode 100644 index 0000000..cade64c --- /dev/null +++ b/walker/walkers/readFuzz/fuzz.go @@ -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 +} diff --git a/walker/walkers/readFuzz/plugin.go b/walker/walkers/readFuzz/plugin.go index f3b2f8e..7f5195f 100644 --- a/walker/walkers/readFuzz/plugin.go +++ b/walker/walkers/readFuzz/plugin.go @@ -1,12 +1,12 @@ +// +build ignore + package main import ( - "io" - "io/ioutil" "os" - "time" "git.thisco.de/vbatts/fuzz-walker/walker" + "git.thisco.de/vbatts/fuzz-walker/walker/walkers/readFuzz" ) // NewFuzzer creates the fuzzer for this plugin @@ -17,20 +17,9 @@ func NewFuzzer() (walker.Fuzzer, error) { type myFuzzer struct{} func (mf myFuzzer) Name() string { - return "readFuzz" + return readFuzz.Name } -func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) 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 +func (mf myFuzzer) Func(path string, info os.FileInfo) error { + return readFuzz.FuzzFunc(path, info) } diff --git a/walker/walkers/writeBytesFuzz/fuzz.go b/walker/walkers/writeBytesFuzz/fuzz.go new file mode 100644 index 0000000..b9a6579 --- /dev/null +++ b/walker/walkers/writeBytesFuzz/fuzz.go @@ -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 +} diff --git a/walker/walkers/writeBytesFuzz/plugin.go b/walker/walkers/writeBytesFuzz/plugin.go index 37aaf22..d38f9aa 100644 --- a/walker/walkers/writeBytesFuzz/plugin.go +++ b/walker/walkers/writeBytesFuzz/plugin.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( @@ -5,6 +7,7 @@ import ( "time" "git.thisco.de/vbatts/fuzz-walker/walker" + "git.thisco.de/vbatts/fuzz-walker/walker/walkers/writeBytesFuzz" ) // NewFuzzer creates the fuzzer for this plugin @@ -15,18 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) { type myFuzzer struct{} func (mf myFuzzer) Name() string { - return "writeBytesFuzz" + return writeBytesFuzz.Name } func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { - if !info.Mode().IsRegular() { - return nil - } - fd, err := os.Open(path) - if err != nil { - return err - } - defer fd.Close() - - return nil + return writeBytesFuzz.Func(path, info) } diff --git a/walker/walkers/writeNumFuzz/fuzz.go b/walker/walkers/writeNumFuzz/fuzz.go new file mode 100644 index 0000000..c2460a8 --- /dev/null +++ b/walker/walkers/writeNumFuzz/fuzz.go @@ -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 +} diff --git a/walker/walkers/writeNumFuzz/plugin.go b/walker/walkers/writeNumFuzz/plugin.go index 9539aa1..b7edfa7 100644 --- a/walker/walkers/writeNumFuzz/plugin.go +++ b/walker/walkers/writeNumFuzz/plugin.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( @@ -5,6 +7,7 @@ import ( "time" "git.thisco.de/vbatts/fuzz-walker/walker" + "git.thisco.de/vbatts/fuzz-walker/walker/walkers/writeNumFuzz" ) // NewFuzzer creates the fuzzer for this plugin @@ -15,17 +18,9 @@ func NewFuzzer() (walker.Fuzzer, error) { type myFuzzer struct{} func (mf myFuzzer) Name() string { - return "writeNumFuzz" + return writeNumFuzz.Name } func (mf myFuzzer) Func(path string, info os.FileInfo, timeout time.Duration) error { - if !info.Mode().IsRegular() { - return nil - } - fd, err := os.Open(path) - if err != nil { - return err - } - defer fd.Close() - return nil + return writeNumFuzz.Func(path, info) }