Copy fuzzers from github.com/cncf/cncf-fuzzing

This commit copies the fuzzers from the repository except for
containerd_import_structured_fuzzer.go.

Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
Kazuyoshi Kato 2022-07-01 16:38:04 +00:00
parent b316318596
commit e9e33f847d
13 changed files with 505 additions and 38 deletions

View File

@ -27,6 +27,8 @@ issues:
exclude-rules: exclude-rules:
- path: 'cmd[\\/]containerd[\\/]builtins[\\/]' - path: 'cmd[\\/]containerd[\\/]builtins[\\/]'
text: "blank-imports:" text: "blank-imports:"
- path: 'contrib[\\/]fuzz[\\/]'
text: "exported: func name will be used as fuzz.Fuzz"
linters-settings: linters-settings:
gosec: gosec:

View File

@ -0,0 +1,29 @@
//go:build gofuzz
// +build gofuzz
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package compression
import (
"bytes"
)
func FuzzDecompressStream(data []byte) int {
_, _ = DecompressStream(bytes.NewReader(data))
return 1
}

View File

@ -0,0 +1,76 @@
//go:build gofuzz
// +build gofuzz
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package local
import (
"bufio"
"bytes"
"context"
"io"
"testing"
"github.com/opencontainers/go-digest"
"github.com/containerd/containerd/content"
)
func FuzzContentStoreWriter(data []byte) int {
t := &testing.T{}
ctx := context.Background()
ctx, _, cs, cleanup := contentStoreEnv(t)
defer cleanup()
cw, err := cs.Writer(ctx, content.WithRef("myref"))
if err != nil {
return 0
}
if err := cw.Close(); err != nil {
return 0
}
// reopen, so we can test things
cw, err = cs.Writer(ctx, content.WithRef("myref"))
if err != nil {
return 0
}
err = checkCopyFuzz(int64(len(data)), cw, bufio.NewReader(io.NopCloser(bytes.NewReader(data))))
if err != nil {
return 0
}
expected := digest.FromBytes(data)
if err = cw.Commit(ctx, int64(len(data)), expected); err != nil {
return 0
}
return 1
}
func checkCopyFuzz(size int64, dst io.Writer, src io.Reader) error {
nn, err := io.Copy(dst, src)
if err != nil {
return err
}
if nn != size {
return err
}
return nil
}

View File

@ -291,20 +291,6 @@ func populateBlobStore(ctx context.Context, t checker, cs content.Store, nblobs,
return blobs return blobs
} }
func contentStoreEnv(t testing.TB) (context.Context, string, content.Store, func()) {
tmpdir := t.TempDir()
cs, err := NewStore(tmpdir)
if err != nil {
t.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background())
return ctx, tmpdir, cs, func() {
cancel()
}
}
func checkCopy(t checker, size int64, dst io.Writer, src io.Reader) { func checkCopy(t checker, size int64, dst io.Writer, src io.Reader) {
nn, err := io.Copy(dst, src) nn, err := io.Copy(dst, src)
if err != nil { if err != nil {

View File

@ -0,0 +1,38 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package local
import (
"context"
"testing"
"github.com/containerd/containerd/content"
)
func contentStoreEnv(t testing.TB) (context.Context, string, content.Store, func()) {
tmpdir := t.TempDir()
cs, err := NewStore(tmpdir)
if err != nil {
t.Fatal(err)
}
ctx, cancel := context.WithCancel(context.Background())
return ctx, tmpdir, cs, func() {
cancel()
}
}

View File

@ -0,0 +1,37 @@
//go:build gofuzz
// +build gofuzz
// Copyright 2022 ADA Logics Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package apparmor
import (
"os"
)
func FuzzLoadDefaultProfile(data []byte) int {
f, err := os.Create("fuzz_file")
if err != nil {
return 0
}
defer os.Remove("fuzz_file")
_, err = f.Write(data)
if err != nil {
return 0
}
_ = LoadDefaultProfile("fuzz_file")
return 1
}

View File

@ -19,14 +19,11 @@ package fuzz
import ( import (
"bytes" "bytes"
"context" "context"
"sync"
"time"
fuzz "github.com/AdaLogics/go-fuzz-headers" fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/containerd" "github.com/containerd/containerd"
_ "github.com/containerd/containerd/cmd/containerd/builtins" _ "github.com/containerd/containerd/cmd/containerd/builtins"
"github.com/containerd/containerd/cmd/containerd/command"
"github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/namespaces"
) )
@ -36,27 +33,6 @@ const (
defaultAddress = "/tmp/containerd/containerd.sock" defaultAddress = "/tmp/containerd/containerd.sock"
) )
var (
initDaemon sync.Once
)
func startDaemonForFuzzing(arguments []string) {
app := command.App()
_ = app.Run(arguments)
}
func startDaemon() {
args := []string{"--log-level", "debug"}
go func() {
// This is similar to invoking the
// containerd binary.
// See contrib/fuzz/oss_fuzz_build.sh
// for more info.
startDaemonForFuzzing(args)
}()
time.Sleep(time.Second * 4)
}
func fuzzContext() (context.Context, context.CancelFunc) { func fuzzContext() (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
ctx = namespaces.WithNamespace(ctx, "fuzzing-namespace") ctx = namespaces.WithNamespace(ctx, "fuzzing-namespace")

44
contrib/fuzz/daemon.go Normal file
View File

@ -0,0 +1,44 @@
//go:build gofuzz
// +build gofuzz
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package fuzz
import (
"sync"
"time"
"github.com/containerd/containerd/cmd/containerd/command"
)
var (
initDaemon sync.Once
)
func startDaemonForFuzzing(arguments []string) {
app := command.App()
_ = app.Run(arguments)
}
func startDaemon() {
args := []string{"--log-level", "debug"}
go func() {
// This is similar to invoking the
// containerd binary.
// See contrib/fuzz/oss_fuzz_build.sh
// for more info.
startDaemonForFuzzing(args)
}()
time.Sleep(time.Second * 4)
}

108
contrib/fuzz/diff_fuzzer.go Normal file
View File

@ -0,0 +1,108 @@
// Copyright 2021 ADA Logics Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package fuzz
import (
"context"
_ "crypto/sha256" // required by go-digest
"os"
fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/containerd/content/local"
"github.com/containerd/containerd/diff/apply"
"github.com/containerd/containerd/diff/walking"
"github.com/containerd/containerd/mount"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
func FuzzDiffApply(data []byte) int {
f := fuzz.NewConsumer(data)
mountsQty, err := f.GetInt()
if err != nil {
return 0
}
mounts := make([]mount.Mount, 0)
for i := 0; i < mountsQty%30; i++ {
m := mount.Mount{}
err = f.GenerateStruct(&m)
if err != nil {
return 0
}
mounts = append(mounts, m)
}
desc := ocispec.Descriptor{}
err = f.GenerateStruct(&desc)
if err != nil {
return 0
}
tmpdir, err := os.MkdirTemp("", "fuzzing-")
if err != nil {
return 0
}
cs, err := local.NewStore(tmpdir)
if err != nil {
return 0
}
fsa := apply.NewFileSystemApplier(cs)
_, _ = fsa.Apply(context.Background(), desc, mounts)
return 1
}
func FuzzDiffCompare(data []byte) int {
f := fuzz.NewConsumer(data)
lowerQty, err := f.GetInt()
if err != nil {
return 0
}
lower := make([]mount.Mount, 0)
for i := 0; i < lowerQty%30; i++ {
m := mount.Mount{}
err = f.GenerateStruct(&m)
if err != nil {
return 0
}
lower = append(lower, m)
}
upperQty, err := f.GetInt()
if err != nil {
return 0
}
upper := make([]mount.Mount, 0)
for i := 0; i < upperQty%30; i++ {
m := mount.Mount{}
err = f.GenerateStruct(&m)
if err != nil {
return 0
}
upper = append(upper, m)
}
ctx := context.Background()
tmpdir, err := os.MkdirTemp("", "fuzzing-")
if err != nil {
return 0
}
cs, err := local.NewStore(tmpdir)
if err != nil {
return 0
}
walker := walking.NewWalkingDiff(cs)
_, _ = walker.Compare(ctx, lower, upper)
return 1
}

View File

@ -0,0 +1,54 @@
// Copyright 2021 ADA Logics Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package fuzz
import (
"context"
fuzz "github.com/AdaLogics/go-fuzz-headers"
eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/events/exchange"
"github.com/containerd/containerd/namespaces"
)
func FuzzExchange(data []byte) int {
f := fuzz.NewConsumer(data)
namespace, err := f.GetString()
if err != nil {
return 0
}
event := &eventstypes.ContainerCreate{}
err = f.GenerateStruct(event)
if err != nil {
return 0
}
input, err := f.GetString()
if err != nil {
return 0
}
env := &events.Envelope{}
err = f.GenerateStruct(env)
if err != nil {
return 0
}
ctx := namespaces.WithNamespace(context.Background(), namespace)
exch := exchange.NewExchange()
exch.Publish(ctx, input, event)
exch.Forward(ctx, env)
return 1
}

View File

@ -0,0 +1,46 @@
// Copyright 2021 ADA Logics Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package fuzz
import (
"context"
"os"
fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/containerd/content/local"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
func FuzzImagesCheck(data []byte) int {
f := fuzz.NewConsumer(data)
desc := ocispec.Descriptor{}
err := f.GenerateStruct(&desc)
if err != nil {
return 0
}
tmpdir, err := os.MkdirTemp("", "fuzzing-")
if err != nil {
return 0
}
cs, err := local.NewStore(tmpdir)
if err != nil {
return 0
}
_, _, _, _, _ = images.Check(context.Background(), cs, desc, platforms.Default())
return 1
}

View File

@ -0,0 +1,25 @@
// Copyright 2021 ADA Logics Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package fuzz
import (
"github.com/google/uuid"
)
func FuzzUUIDParse(data []byte) int {
_, _ = uuid.Parse(string(data))
return 1
}

View File

@ -0,0 +1,46 @@
//go:build gofuzz
// +build gofuzz
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package config
import (
"io/ioutil"
"os"
fuzz "github.com/AdaLogics/go-fuzz-headers"
)
func FuzzParseHostsFile(data []byte) int {
f := fuzz.NewConsumer(data)
dir, err := ioutil.TempDir("", "fuzz-")
if err != nil {
return 0
}
err = f.CreateFiles(dir)
if err != nil {
return 0
}
defer os.RemoveAll(dir)
b, err := f.GetBytes()
if err != nil {
return 0
}
_, _ = parseHostsFile(dir, b)
return 1
}