Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
default: clean bin/go-fuzz_executor bin/go-fuzz_scheduler bin/go-fuzz

run: clean bin/go-fuzz_executor bin/go-fuzz run-scheduler

clean:
-rm bin/fuzzlr_*

bin:
-mkdir bin

bin/fuzzlr-scheduler: bin
go build -o bin/fuzzler-scheduler cmd/fuzzlr-scheduler/app.go

bin/fuzzlr_executor: bin
go build -o bin/fuzzlr-executor cmd/fuzzlr-executor/app.go

bin/go-fuzz: bin
git submodule init
git submodule update
cd _vendor/go-fuzz/go-fuzz; \
for arch in {darwin,linux}; do \
GOOS=$$arch go build -o ../../../bin/go-fuzz-$$arch; \
done

bin/go-fuzz-build: bin
git submodule init
git submodule update
cd _vendor/go-fuzz/go-fuzz-build; go build -o ../../../bin/go-fuzz-build

bin/test: bin/go-fuzz-build
for arch in {darwin,linux}; do \
GOOS=$$arch bin/go-fuzz-build -o bin/fmt-fuzz-$$arch.zip github.com/dvyukov/go-fuzz/examples/png; \
done

bin/corpus.zip: bin
zip bin/corpus.zip $(GOPATH)/src/github.com/dvyukov/go-fuzz/examples/png/corpus/*

go-fuzz: bin/go-fuzz bin/test bin/corpus.zip

run-scheduler:
go run -race cmd/fuzzlr-scheduler/app.go -logtostderr=true

install:
go install ./cmd/...

cover:
for i in `dirname **/*_test.go | grep -v "_vendor" | sort | uniq`; do \
echo $$i; \
go test -v -race ./$$i/... -coverprofile=em-coverage.out; \
go tool cover -func=em-coverage.out; rm em-coverage.out; \
done

test:
go test -race ./...
34 changes: 32 additions & 2 deletions cmds/fuzzlr-scheduler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,52 @@ package main

import (
"flag"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
"time"

"github.com/gogo/protobuf/proto"
mesos "github.com/mesos/mesos-go/mesosproto"

"github.com/mesosphere/fuzzlr/scheduler"
"github.com/mesosphere/fuzzlr/serving"
)

func main() {
fs := flag.NewFlagSet("fuzzlr", flag.ExitOnError)
master := fs.String("master", "localhost:5050", "Location of leading Mesos master")
master := fs.String("master", "localhost:5050", "Location of leading Mesos master.")
servingPath := fs.String("binpath", "./bin/", "Directory where go-fuzz binaries are located.")
bin := fs.String("bin", "./fuzz.zip", "Archive generated by go-fuzz-build.")
corpus := fs.String("corpus", "./corpus.zip", "Corpus zip archive to seed the fuzzing with.")
artifactPort := fs.Int("artifactPort", 12300, "Binding port for artifact server")
address := fs.String("address", "127.0.0.1", "Binding address for artifact server")
shutdownTimeout := fs.Duration("shutdown.timeout", 10*time.Second, "Shutdown timeout")

fs.Parse(os.Args[1:])

sched := scheduler.New()
binpaths, err := filepath.Glob(*servingPath)
if err != nil {
log.Printf("Unable to read files from provided serving path %s: %v", *servingPath, err)
return
}
commandInfos := []*mesos.CommandInfo_URI{}
uris := []string{}
for _, path := range binpaths {
uri := serving.ServeExecutorArtifact(path, *address, *artifactPort)
commandInfos = append(commandInfos, &mesos.CommandInfo_URI{
Value: uri,
Executable: proto.Bool(true),
})
uris = append(uris, *uri)
}
go http.ListenAndServe(fmt.Sprintf("%s:%d", *address, *artifactPort), nil)
log.Printf("Serving executor artifacts...")

sched := scheduler.New(*bin, *corpus, uris...)
driver, err := scheduler.NewDriver(*master, sched)
if err != nil {
log.Printf("Unable to create scheduler driver: %s", err)
Expand Down
4 changes: 3 additions & 1 deletion scheduler/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ func NewDriver(master string, s sched.Scheduler) (sched.SchedulerDriver, error)
return sched.NewMesosSchedulerDriver(sched.DriverConfig{
Master: master,
Framework: &pb.FrameworkInfo{
Name: proto.String("Fuzzlr"),
Name: proto.String("Fuzzlr"),
Checkpoint: proto.Bool(true),
FailoverTimeout: proto.Float64(60 * 60 * 24 * 7),
// User: proto.String(""),
},
Scheduler: s,
Expand Down
28 changes: 27 additions & 1 deletion scheduler/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type Scheduler struct {
done chan struct{}
}

func New(artifactURIs ...string) *Scheduler {
func New(bin, corpus string, artifactURIs ...string) *Scheduler {
return &Scheduler{
ExecutorInfo: mesos.ExecutorInfo{
ExecutorId: &mesos.ExecutorID{Value: proto.String("fuzzlr-executor")},
Expand All @@ -33,6 +33,32 @@ func New(artifactURIs ...string) *Scheduler {
}
}

func NewFuzzMasterExecutorInfo(os string, host string, port int, corpus string) *mesos.ExecutorInfo {
cmd := fmt.Sprintf("mkdir -p work/corpus; unzip %s-%s -d ./work/corpus; "+
"./go-fuzz-%s -workdir=work -master=%s:%d > master.log", corpus, os, os, host, port)
return &mesos.ExecutorInfo{
ExecutorId: &mesos.ExecutorID{Value: proto.String("fuzzlr-executor")},
Command: &mesos.CommandInfo{
Value: proto.String(cmd),
Uris: commandURIs(artifactURIs...),
},
Name: proto.String("Fuzzer"),
}
}

func NewSlaveExecutorInfo(masterHost string, masterPort int, bin string) *mesos.ExecutorInfo {
cmd := fmt.Sprintf("./go-fuzz -bin=%s -slave=%s:%d -v=1 > slave.log",
bin, masterHost, masterPort)
return &mesos.ExecutorInfo{
ExecutorId: &mesos.ExecutorID{Value: proto.String("fuzzlr-executor")},
Command: &mesos.CommandInfo{
Value: proto.String(cmd),
Uris: commandURIs(artifactURIs...),
},
Name: proto.String("Fuzzer"),
}
}

// Shutdown shuts down the scheduler or times out after a given duration.
func (s *Scheduler) Shutdown(timeout time.Duration) error {
close(s.shutdown)
Expand Down