Skip to content

Commit 11a90c7

Browse files
committed
Fuzzing: Add experimental version of container fuzzer
Signed-off-by: AdamKorcz <[email protected]>
1 parent fedd657 commit 11a90c7

2 files changed

Lines changed: 98 additions & 4 deletions

File tree

contrib/fuzz/container_fuzzer.go

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,69 @@ import (
3838
"time"
3939
)
4040

41-
func init() {
42-
err := updatePathEnv()
43-
if err != nil {
44-
fmt.Println(err)
41+
var (
42+
haveInstalledWget = false
43+
haveDownloadedbinaries = false
44+
haveExtractedBinaries = false
45+
haveChangedPATH = false
46+
haveInitialized = false
47+
)
48+
49+
// initInSteps() performs initialization in several steps
50+
// The reason for spreading the initialization out in
51+
// multiple steps is that each fuzz iteration can maximum
52+
// take 25 seconds when running through OSS-fuzz.
53+
// Should an iteration exceed that, then the fuzzer stops.
54+
func initInSteps() bool {
55+
// Install wget
56+
if !haveInstalledWget {
57+
cmd := exec.Command("apt-get", "install", "-y", "wget")
58+
err := cmd.Run()
59+
if err != nil {
60+
return true
61+
}
62+
haveInstalledWget = true
63+
return true
64+
}
65+
// Download binaries
66+
if !haveDownloadedbinaries {
67+
tarLink := "https://github.com/containerd/containerd/releases/download/v1.5.4/containerd-1.5.4-linux-amd64.tar.gz"
68+
cmd := exec.Command("wget", tarLink)
69+
err := cmd.Run()
70+
if err != nil {
71+
return true
72+
}
73+
haveDownloadedbinaries = true
74+
return true
75+
}
76+
// Extract binaries
77+
binariesDir := "/tmp/containerd-binaries"
78+
if !haveExtractedBinaries {
79+
err := os.MkdirAll(binariesDir, 0777)
80+
if err != nil {
81+
return true
82+
}
83+
cmd := exec.Command("tar", "xvf", "containerd-1.5.4-linux-amd64.tar.gz", "-C", binariesDir)
84+
err = cmd.Run()
85+
if err != nil {
86+
return true
87+
}
88+
haveExtractedBinaries = true
89+
return true
90+
}
91+
// Add binaries to $PATH:
92+
if !haveChangedPATH {
93+
oldPathEnv := os.Getenv("PATH")
94+
newPathEnv := fmt.Sprintf("%s:%s/bin", oldPathEnv, binariesDir)
95+
err := os.Setenv("PATH", newPathEnv)
96+
if err != nil {
97+
return true
98+
}
99+
haveChangedPATH = true
100+
return true
45101
}
102+
haveInitialized = true
103+
return false
46104
}
47105

48106
func tearDown() error {
@@ -153,6 +211,7 @@ func updatePathEnv() error {
153211
if err != nil {
154212
return err
155213
}
214+
haveInitialized = true
156215
return nil
157216
}
158217

@@ -327,12 +386,39 @@ func doFuzz(data []byte, shouldTearDown bool) int {
327386
return 1
328387
}
329388

389+
// FuzzCreateContainerNoTearDown() implements a fuzzer
390+
// similar to FuzzCreateContainerWithTearDown() and
391+
// FuzzCreateContainerWithTearDown(), but it takes a
392+
// different approach to the initialization. Where
393+
// the other 2 fuzzers depend on the containerd binaries
394+
// that were built manually, this fuzzer downloads them
395+
// when starting a fuzz run.
396+
// This fuzzer is experimental for now and is being run
397+
// continuously by OSS-fuzz to collect feedback on
398+
// its sustainability.
399+
func FuzzNoTearDownWithDownload(data []byte) int {
400+
if !haveInitialized {
401+
shouldRestart := initInSteps()
402+
if shouldRestart {
403+
return 0
404+
}
405+
}
406+
ret := doFuzz(data, false)
407+
return ret
408+
}
409+
330410
// FuzzCreateContainerNoTearDown() implements a fuzzer
331411
// similar to FuzzCreateContainerWithTearDown() with
332412
// with one minor distinction: One tears down the
333413
// daemon after each iteration whereas the other doesn't.
334414
// The two fuzzers' performance will be compared over time.
335415
func FuzzCreateContainerNoTearDown(data []byte) int {
416+
if !haveInitialized {
417+
err := updatePathEnv()
418+
if err != nil {
419+
return 0
420+
}
421+
}
336422
ret := doFuzz(data, false)
337423
return ret
338424
}
@@ -342,6 +428,12 @@ func FuzzCreateContainerNoTearDown(data []byte) int {
342428
// FuzzCreateContainerWithTearDown tears down the daemon
343429
// after each iteration.
344430
func FuzzCreateContainerWithTearDown(data []byte) int {
431+
if !haveInitialized {
432+
err := updatePathEnv()
433+
if err != nil {
434+
return 0
435+
}
436+
}
345437
ret := doFuzz(data, true)
346438
return ret
347439
}

contrib/fuzz/oss_fuzz_build.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,7 @@ for i in $( ls *_test.go ); do mv $i ./${i%.*}_fuzz.go; done
6969

7070
# Remove windows test to avoid double declarations:
7171
rm ./client_windows_test_fuzz.go
72+
rm ./helpers_windows_test_fuzz.go
7273
compile_go_fuzzer . FuzzCreateContainerNoTearDown fuzz_create_container_no_teardown
7374
compile_go_fuzzer . FuzzCreateContainerWithTearDown fuzz_create_container_with_teardown
75+
compile_go_fuzzer . FuzzNoTearDownWithDownload fuzz_no_teardown_with_download

0 commit comments

Comments
 (0)