@@ -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
48106func 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.
335415func 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.
344430func 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}
0 commit comments