Refactor CRI fuzzers

pkg/cri/sbserver/cri_fuzzer.go and pkg/cri/server/cri_fuzzer.go were
mostly the same.

This commit merges them together and move the unified fuzzer to
contrib/fuzz again to sort out dependencies. pkg/cri/ shouldn't consume
cmd/.

Signed-off-by: Kazuyoshi Kato <katokazu@amazon.com>
This commit is contained in:
Kazuyoshi Kato 2022-09-19 20:43:02 +00:00
parent 58701f87c7
commit a37c64b20c
7 changed files with 665 additions and 1156 deletions

View File

@ -17,12 +17,514 @@
package fuzz
import (
"context"
"fmt"
golangruntime "runtime"
"strings"
fuzz "github.com/AdaLogics/go-fuzz-headers"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
"github.com/containerd/containerd/pkg/cri/sbserver"
"github.com/containerd/containerd/pkg/cri/server"
containerstore "github.com/containerd/containerd/pkg/cri/store/container"
sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox"
)
var (
// The APIs the fuzzer can call:
ops = map[int]string{
0: "createContainer",
1: "removeContainer",
2: "addSandboxes",
3: "listContainers",
4: "startContainer",
5: "containerStats",
6: "listContainerStats",
7: "containerStatus",
8: "stopContainer",
9: "updateContainerResources",
10: "listImages",
11: "removeImages",
12: "imageStatus",
13: "imageFsInfo",
14: "listPodSandbox",
15: "portForward",
16: "removePodSandbox",
17: "runPodSandbox",
18: "podSandboxStatus",
19: "stopPodSandbox",
20: "status",
21: "updateRuntimeConfig",
}
executionOrder []string
)
func printExecutions() {
if r := recover(); r != nil {
var err string
switch r.(type) {
case string:
err = r.(string)
case golangruntime.Error:
err = r.(golangruntime.Error).Error()
case error:
err = r.(error).Error()
default:
err = "uknown error type"
}
fmt.Println("Executions:")
for _, eo := range executionOrder {
fmt.Println(eo)
}
panic(err)
}
}
func fuzzCRI(f *fuzz.ConsumeFuzzer, c server.CRIService) int {
executionOrder = make([]string, 0)
defer printExecutions()
calls, err := f.GetInt()
if err != nil {
return 0
}
executionOrder = make([]string, 0)
defer printExecutions()
for i := 0; i < calls%40; i++ {
op, err := f.GetInt()
if err != nil {
return 0
}
opType := op % len(ops)
switch ops[opType] {
case "createContainer":
createContainerFuzz(c, f)
case "removeContainer":
removeContainerFuzz(c, f)
case "addSandboxes":
addSandboxesFuzz(c, f)
case "listContainers":
listContainersFuzz(c, f)
case "startContainer":
startContainerFuzz(c, f)
case "containerStats":
containerStatsFuzz(c, f)
case "listContainerStats":
listContainerStatsFuzz(c, f)
case "containerStatus":
containerStatusFuzz(c, f)
case "stopContainer":
stopContainerFuzz(c, f)
case "updateContainerResources":
updateContainerResourcesFuzz(c, f)
case "listImages":
listImagesFuzz(c, f)
case "removeImages":
removeImagesFuzz(c, f)
case "imageStatus":
imageStatusFuzz(c, f)
case "imageFsInfo":
imageFsInfoFuzz(c, f)
case "listPodSandbox":
listPodSandboxFuzz(c, f)
case "portForward":
portForwardFuzz(c, f)
case "removePodSandbox":
removePodSandboxFuzz(c, f)
case "runPodSandbox":
runPodSandboxFuzz(c, f)
case "podSandboxStatus":
podSandboxStatusFuzz(c, f)
case "stopPodSandbox":
stopPodSandboxFuzz(c, f)
case "status":
statusFuzz(c, f)
case "updateRuntimeConfig":
updateRuntimeConfigFuzz(c, f)
}
}
return 1
}
func logExecution(apiName, request string) {
var logString strings.Builder
logString.WriteString(fmt.Sprintf("Calling %s with \n %s \n\n", apiName, request))
executionOrder = append(executionOrder, logString.String())
}
// createContainerFuzz creates a CreateContainerRequest and passes
// it to c.CreateContainer
func createContainerFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.CreateContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.CreateContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.CreateContainer", reqString)
return nil
}
// removeContainerFuzz creates a RemoveContainerRequest and passes
// it to c.RemoveContainer
func removeContainerFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemoveContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemoveContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemoveContainer", reqString)
return nil
}
func sandboxStore(cs server.CRIService) (*sandboxstore.Store, error) {
var (
ss *sandboxstore.Store
err error
)
ss, err = server.SandboxStore(cs)
if err != nil {
ss, err = sbserver.SandboxStore(cs)
if err != nil {
return nil, err
}
return ss, nil
}
return ss, nil
}
// addSandboxesFuzz creates a sandbox and adds it to the sandboxstore
func addSandboxesFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
quantity, err := f.GetInt()
if err != nil {
return err
}
ss, err := sandboxStore(c)
if err != nil {
return err
}
for i := 0; i < quantity%20; i++ {
newSandbox, err := getSandboxFuzz(f)
if err != nil {
return err
}
err = ss.Add(newSandbox)
if err != nil {
return err
}
}
return nil
}
// getSandboxFuzz creates a sandbox
func getSandboxFuzz(f *fuzz.ConsumeFuzzer) (sandboxstore.Sandbox, error) {
metadata := sandboxstore.Metadata{}
status := sandboxstore.Status{}
err := f.GenerateStruct(&metadata)
if err != nil {
return sandboxstore.Sandbox{}, err
}
err = f.GenerateStruct(&status)
if err != nil {
return sandboxstore.Sandbox{}, err
}
reqString := fmt.Sprintf("metadata: %+v\nstatus: %+v\n", metadata, status)
logExecution("sandboxstore.NewSandbox", reqString)
return sandboxstore.NewSandbox(metadata, status), nil
}
// listContainersFuzz creates a ListContainersRequest and passes
// it to c.ListContainers
func listContainersFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListContainersRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListContainers(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListContainers", reqString)
return nil
}
// startContainerFuzz creates a StartContainerRequest and passes
// it to c.StartContainer
func startContainerFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StartContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StartContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StartContainer", reqString)
return nil
}
// containerStatsFuzz creates a ContainerStatsRequest and passes
// it to c.ContainerStats
func containerStatsFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ContainerStatsRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ContainerStats(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ContainerStats", reqString)
return nil
}
// listContainerStatsFuzz creates a ListContainerStatsRequest and
// passes it to c.ListContainerStats
func listContainerStatsFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListContainerStatsRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListContainerStats(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListContainerStats", reqString)
return nil
}
// containerStatusFuzz creates a ContainerStatusRequest and passes
// it to c.ContainerStatus
func containerStatusFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ContainerStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ContainerStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ContainerStatus", reqString)
return nil
}
// stopContainerFuzz creates a StopContainerRequest and passes
// it to c.StopContainer
func stopContainerFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StopContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StopContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StopContainer", reqString)
return nil
}
// updateContainerResourcesFuzz creates a UpdateContainerResourcesRequest
// and passes it to c.UpdateContainerResources
func updateContainerResourcesFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.UpdateContainerResourcesRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.UpdateContainerResources(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.UpdateContainerResources", reqString)
return nil
}
// listImagesFuzz creates a ListImagesRequest and passes it to
// c.ListImages
func listImagesFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListImagesRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListImages(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListImages", reqString)
return nil
}
// removeImagesFuzz creates a RemoveImageRequest and passes it to
// c.RemoveImage
func removeImagesFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemoveImageRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemoveImage(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemoveImage", reqString)
return nil
}
// imageStatusFuzz creates an ImageStatusRequest and passes it to
// c.ImageStatus
func imageStatusFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ImageStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ImageStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ImageStatus", reqString)
return nil
}
// imageFsInfoFuzz creates an ImageFsInfoRequest and passes it to
// c.ImageFsInfo
func imageFsInfoFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ImageFsInfoRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ImageFsInfo(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ImageFsInfo", reqString)
return nil
}
// listPodSandboxFuzz creates a ListPodSandboxRequest and passes
// it to c.ListPodSandbox
func listPodSandboxFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListPodSandbox", reqString)
return nil
}
// portForwardFuzz creates a PortForwardRequest and passes it to
// c.PortForward
func portForwardFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.PortForwardRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.PortForward(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.PortForward", reqString)
return nil
}
// removePodSandboxFuzz creates a RemovePodSandboxRequest and
// passes it to c.RemovePodSandbox
func removePodSandboxFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemovePodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemovePodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemovePodSandbox", reqString)
return nil
}
// runPodSandboxFuzz creates a RunPodSandboxRequest and passes
// it to c.RunPodSandbox
func runPodSandboxFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RunPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RunPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RunPodSandbox", reqString)
return nil
}
// podSandboxStatusFuzz creates a PodSandboxStatusRequest and
// passes it to
func podSandboxStatusFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.PodSandboxStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.PodSandboxStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.PodSandboxStatus", reqString)
return nil
}
// stopPodSandboxFuzz creates a StopPodSandboxRequest and passes
// it to c.StopPodSandbox
func stopPodSandboxFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StopPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StopPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StopPodSandbox", reqString)
return nil
}
// statusFuzz creates a StatusRequest and passes it to c.Status
func statusFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.Status(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.Status", reqString)
return nil
}
func updateRuntimeConfigFuzz(c server.CRIService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.UpdateRuntimeConfigRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.UpdateRuntimeConfig(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.UpdateRuntimeConfig", reqString)
return nil
}
// This creates a container directly in the store.
func getContainer(f *fuzz.ConsumeFuzzer) (containerstore.Container, error) {
metadata := containerstore.Metadata{}
status := containerstore.Status{}
err := f.GenerateStruct(&metadata)
if err != nil {
return containerstore.Container{}, err
}
err = f.GenerateStruct(&status)
if err != nil {
return containerstore.Container{}, err
}
container, err := containerstore.NewContainer(metadata, containerstore.WithFakeStatus(status))
return container, err
}
func FuzzParseAuth(data []byte) int {
f := fuzz.NewConsumer(data)
auth := &runtime.AuthConfig{}

View File

@ -0,0 +1,47 @@
//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 (
fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/containerd"
criconfig "github.com/containerd/containerd/pkg/cri/config"
"github.com/containerd/containerd/pkg/cri/sbserver"
)
func FuzzCRISandboxServer(data []byte) int {
initDaemon.Do(startDaemon)
f := fuzz.NewConsumer(data)
client, err := containerd.New(defaultAddress)
if err != nil {
return 0
}
defer client.Close()
c, err := sbserver.NewCRIService(criconfig.Config{}, client)
if err != nil {
panic(err)
}
return fuzzCRI(f, c)
}

View File

@ -0,0 +1,47 @@
//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 (
fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/containerd"
criconfig "github.com/containerd/containerd/pkg/cri/config"
"github.com/containerd/containerd/pkg/cri/server"
)
func FuzzCRIServer(data []byte) int {
initDaemon.Do(startDaemon)
f := fuzz.NewConsumer(data)
client, err := containerd.New(defaultAddress)
if err != nil {
return 0
}
defer client.Close()
c, err := server.NewCRIService(criconfig.Config{}, client)
if err != nil {
panic(err)
}
return fuzzCRI(f, c)
}

View File

@ -1,578 +0,0 @@
//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 sbserver
import (
"context"
"fmt"
golangruntime "runtime"
"strings"
"sync"
"time"
fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/go-cni"
criconfig "github.com/containerd/containerd/pkg/cri/config"
servertesting "github.com/containerd/containerd/pkg/cri/server/testing"
containerstore "github.com/containerd/containerd/pkg/cri/store/container"
imagestore "github.com/containerd/containerd/pkg/cri/store/image"
"github.com/containerd/containerd/pkg/cri/store/label"
sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox"
snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot"
ostesting "github.com/containerd/containerd/pkg/os/testing"
"github.com/containerd/containerd/pkg/registrar"
"github.com/containerd/containerd"
_ "github.com/containerd/containerd/cmd/containerd/builtins"
"github.com/containerd/containerd/cmd/containerd/command"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
)
var (
// The APIs the fuzzer can call:
ops = map[int]string{
0: "createContainer",
1: "removeContainer",
2: "addSandboxes",
3: "listContainers",
4: "startContainer",
5: "containerStats",
6: "listContainerStats",
7: "containerStatus",
8: "stopContainer",
9: "updateContainerResources",
10: "listImages",
11: "removeImages",
12: "imageStatus",
13: "imageFsInfo",
14: "listPodSandbox",
15: "portForward",
16: "removePodSandbox",
17: "runPodSandbox",
18: "podSandboxStatus",
19: "stopPodSandbox",
20: "status",
21: "updateRuntimeConfig",
}
)
const (
defaultRoot = "/var/lib/containerd"
defaultState = "/tmp/containerd"
defaultAddress = "/tmp/containerd/containerd.sock"
)
var (
initDaemon sync.Once
executionOrder []string
)
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 printExecutions() {
if r := recover(); r != nil {
var err string
switch r.(type) {
case string:
err = r.(string)
case golangruntime.Error:
err = r.(golangruntime.Error).Error()
case error:
err = r.(error).Error()
default:
err = "uknown error type"
}
fmt.Println("Executions:")
for _, eo := range executionOrder {
fmt.Println(eo)
}
panic(err)
}
}
// FuzzCRI implements a fuzzer that tests CRI APIs.
func FuzzCRI(data []byte) int {
initDaemon.Do(startDaemon)
executionOrder = make([]string, 0)
f := fuzz.NewConsumer(data)
client, err := containerd.New(defaultAddress)
if err != nil {
return 0
}
defer client.Close()
c, err := NewCRIService(criconfig.Config{}, client)
if err != nil {
panic(err)
}
calls, err := f.GetInt()
if err != nil {
return 0
}
defer printExecutions()
for i := 0; i < calls%40; i++ {
op, err := f.GetInt()
if err != nil {
return 0
}
opType := op % len(ops)
switch ops[opType] {
case "createContainer":
createContainerFuzz(c.(*criService), f)
case "removeContainer":
removeContainerFuzz(c.(*criService), f)
case "addSandboxes":
addSandboxesFuzz(c.(*criService), f)
case "listContainers":
listContainersFuzz(c.(*criService), f)
case "startContainer":
startContainerFuzz(c.(*criService), f)
case "containerStats":
containerStatsFuzz(c.(*criService), f)
case "listContainerStats":
listContainerStatsFuzz(c.(*criService), f)
case "containerStatus":
containerStatusFuzz(c.(*criService), f)
case "stopContainer":
stopContainerFuzz(c.(*criService), f)
case "updateContainerResources":
updateContainerResourcesFuzz(c.(*criService), f)
case "listImages":
listImagesFuzz(c.(*criService), f)
case "removeImages":
removeImagesFuzz(c.(*criService), f)
case "imageStatus":
imageStatusFuzz(c.(*criService), f)
case "imageFsInfo":
imageFsInfoFuzz(c.(*criService), f)
case "listPodSandbox":
listPodSandboxFuzz(c.(*criService), f)
case "portForward":
portForwardFuzz(c.(*criService), f)
case "removePodSandbox":
removePodSandboxFuzz(c.(*criService), f)
case "runPodSandbox":
runPodSandboxFuzz(c.(*criService), f)
case "podSandboxStatus":
podSandboxStatusFuzz(c.(*criService), f)
case "stopPodSandbox":
stopPodSandboxFuzz(c.(*criService), f)
case "status":
statusFuzz(c.(*criService), f)
case "updateRuntimeConfig":
updateRuntimeConfigFuzz(c.(*criService), f)
}
}
return 1
}
func logExecution(apiName, request string) {
var logString strings.Builder
logString.WriteString(fmt.Sprintf("Calling %s with \n %s \n\n", apiName, request))
executionOrder = append(executionOrder, logString.String())
}
// createContainerFuzz creates a CreateContainerRequest and passes
// it to c.CreateContainer
func createContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.CreateContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.CreateContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.CreateContainer", reqString)
return nil
}
// removeContainerFuzz creates a RemoveContainerRequest and passes
// it to c.RemoveContainer
func removeContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemoveContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemoveContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemoveContainer", reqString)
return nil
}
// addSandboxesFuzz creates a sandbox and adds it to the sandboxstore
func addSandboxesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
quantity, err := f.GetInt()
if err != nil {
return err
}
for i := 0; i < quantity%20; i++ {
newSandbox, err := getSandboxFuzz(f)
if err != nil {
return err
}
err = c.sandboxStore.Add(newSandbox)
if err != nil {
return err
}
}
return nil
}
// getSandboxFuzz creates a sandbox
func getSandboxFuzz(f *fuzz.ConsumeFuzzer) (sandboxstore.Sandbox, error) {
metadata := sandboxstore.Metadata{}
status := sandboxstore.Status{}
err := f.GenerateStruct(&metadata)
if err != nil {
return sandboxstore.Sandbox{}, err
}
err = f.GenerateStruct(&status)
if err != nil {
return sandboxstore.Sandbox{}, err
}
reqString := fmt.Sprintf("metadata: %+v\nstatus: %+v\n", metadata, status)
logExecution("sandboxstore.NewSandbox", reqString)
return sandboxstore.NewSandbox(metadata, status), nil
}
// listContainersFuzz creates a ListContainersRequest and passes
// it to c.ListContainers
func listContainersFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListContainersRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListContainers(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListContainers", reqString)
return nil
}
// startContainerFuzz creates a StartContainerRequest and passes
// it to c.StartContainer
func startContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StartContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StartContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StartContainer", reqString)
return nil
}
// containerStatsFuzz creates a ContainerStatsRequest and passes
// it to c.ContainerStats
func containerStatsFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ContainerStatsRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ContainerStats(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ContainerStats", reqString)
return nil
}
// listContainerStatsFuzz creates a ListContainerStatsRequest and
// passes it to c.ListContainerStats
func listContainerStatsFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListContainerStatsRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListContainerStats(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListContainerStats", reqString)
return nil
}
// containerStatusFuzz creates a ContainerStatusRequest and passes
// it to c.ContainerStatus
func containerStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ContainerStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ContainerStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ContainerStatus", reqString)
return nil
}
// stopContainerFuzz creates a StopContainerRequest and passes
// it to c.StopContainer
func stopContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StopContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StopContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StopContainer", reqString)
return nil
}
// updateContainerResourcesFuzz creates a UpdateContainerResourcesRequest
// and passes it to c.UpdateContainerResources
func updateContainerResourcesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.UpdateContainerResourcesRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.UpdateContainerResources(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.UpdateContainerResources", reqString)
return nil
}
// listImagesFuzz creates a ListImagesRequest and passes it to
// c.ListImages
func listImagesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListImagesRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListImages(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListImages", reqString)
return nil
}
// removeImagesFuzz creates a RemoveImageRequest and passes it to
// c.RemoveImage
func removeImagesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemoveImageRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemoveImage(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemoveImage", reqString)
return nil
}
// imageStatusFuzz creates an ImageStatusRequest and passes it to
// c.ImageStatus
func imageStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ImageStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ImageStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ImageStatus", reqString)
return nil
}
// imageFsInfoFuzz creates an ImageFsInfoRequest and passes it to
// c.ImageFsInfo
func imageFsInfoFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ImageFsInfoRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ImageFsInfo(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ImageFsInfo", reqString)
return nil
}
// listPodSandboxFuzz creates a ListPodSandboxRequest and passes
// it to c.ListPodSandbox
func listPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListPodSandbox", reqString)
return nil
}
// portForwardFuzz creates a PortForwardRequest and passes it to
// c.PortForward
func portForwardFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.PortForwardRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.PortForward(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.PortForward", reqString)
return nil
}
// removePodSandboxFuzz creates a RemovePodSandboxRequest and
// passes it to c.RemovePodSandbox
func removePodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemovePodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemovePodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemovePodSandbox", reqString)
return nil
}
// runPodSandboxFuzz creates a RunPodSandboxRequest and passes
// it to c.RunPodSandbox
func runPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RunPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RunPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RunPodSandbox", reqString)
return nil
}
// podSandboxStatusFuzz creates a PodSandboxStatusRequest and
// passes it to
func podSandboxStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.PodSandboxStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.PodSandboxStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.PodSandboxStatus", reqString)
return nil
}
// stopPodSandboxFuzz creates a StopPodSandboxRequest and passes
// it to c.StopPodSandbox
func stopPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StopPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StopPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StopPodSandbox", reqString)
return nil
}
// statusFuzz creates a StatusRequest and passes it to c.Status
func statusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.Status(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.Status", reqString)
return nil
}
func updateRuntimeConfigFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.UpdateRuntimeConfigRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.UpdateRuntimeConfig(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.UpdateRuntimeConfig", reqString)
return nil
}
// This creates a container directly in the store.
func getContainer(f *fuzz.ConsumeFuzzer) (containerstore.Container, error) {
metadata := containerstore.Metadata{}
status := containerstore.Status{}
err := f.GenerateStruct(&metadata)
if err != nil {
return containerstore.Container{}, err
}
err = f.GenerateStruct(&status)
if err != nil {
return containerstore.Container{}, err
}
container, err := containerstore.NewContainer(metadata, containerstore.WithFakeStatus(status))
return container, err
}
func newTestCRIServiceForFuzzing(f *fuzz.ConsumeFuzzer) *criService {
labels := label.NewStore()
return &criService{
config: testConfig,
imageFSPath: testImageFSPath,
os: ostesting.NewFakeOS(),
sandboxStore: sandboxstore.NewStore(labels),
imageStore: imagestore.NewStore(nil),
snapshotStore: snapshotstore.NewStore(),
sandboxNameIndex: registrar.NewRegistrar(),
containerStore: containerstore.NewStore(labels),
containerNameIndex: registrar.NewRegistrar(),
netPlugin: map[string]cni.CNI{
defaultNetworkPlugin: servertesting.NewFakeCNIPlugin(),
},
}
}

35
pkg/cri/sbserver/fuzz.go Normal file
View File

@ -0,0 +1,35 @@
//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 sbserver
import (
"fmt"
"github.com/containerd/containerd/pkg/cri/server"
"github.com/containerd/containerd/pkg/cri/store/sandbox"
)
func SandboxStore(cs server.CRIService) (*sandbox.Store, error) {
s, ok := cs.(*criService)
if !ok {
return nil, fmt.Errorf("%+v is not sbserver.criService", cs)
}
return s.sandboxStore, nil
}

View File

@ -1,578 +0,0 @@
//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 server
import (
"context"
"fmt"
golangruntime "runtime"
"strings"
"sync"
"time"
fuzz "github.com/AdaLogics/go-fuzz-headers"
"github.com/containerd/go-cni"
criconfig "github.com/containerd/containerd/pkg/cri/config"
servertesting "github.com/containerd/containerd/pkg/cri/server/testing"
containerstore "github.com/containerd/containerd/pkg/cri/store/container"
imagestore "github.com/containerd/containerd/pkg/cri/store/image"
"github.com/containerd/containerd/pkg/cri/store/label"
sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox"
snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot"
ostesting "github.com/containerd/containerd/pkg/os/testing"
"github.com/containerd/containerd/pkg/registrar"
"github.com/containerd/containerd"
_ "github.com/containerd/containerd/cmd/containerd/builtins"
"github.com/containerd/containerd/cmd/containerd/command"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
)
var (
// The APIs the fuzzer can call:
ops = map[int]string{
0: "createContainer",
1: "removeContainer",
2: "addSandboxes",
3: "listContainers",
4: "startContainer",
5: "containerStats",
6: "listContainerStats",
7: "containerStatus",
8: "stopContainer",
9: "updateContainerResources",
10: "listImages",
11: "removeImages",
12: "imageStatus",
13: "imageFsInfo",
14: "listPodSandbox",
15: "portForward",
16: "removePodSandbox",
17: "runPodSandbox",
18: "podSandboxStatus",
19: "stopPodSandbox",
20: "status",
21: "updateRuntimeConfig",
}
)
const (
defaultRoot = "/var/lib/containerd"
defaultState = "/tmp/containerd"
defaultAddress = "/tmp/containerd/containerd.sock"
)
var (
initDaemon sync.Once
executionOrder []string
)
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 printExecutions() {
if r := recover(); r != nil {
var err string
switch r.(type) {
case string:
err = r.(string)
case golangruntime.Error:
err = r.(golangruntime.Error).Error()
case error:
err = r.(error).Error()
default:
err = "uknown error type"
}
fmt.Println("Executions:")
for _, eo := range executionOrder {
fmt.Println(eo)
}
panic(err)
}
}
// FuzzCRI implements a fuzzer that tests CRI APIs.
func FuzzCRI(data []byte) int {
initDaemon.Do(startDaemon)
executionOrder = make([]string, 0)
f := fuzz.NewConsumer(data)
client, err := containerd.New(defaultAddress)
if err != nil {
return 0
}
defer client.Close()
c, err := NewCRIService(criconfig.Config{}, client)
if err != nil {
panic(err)
}
calls, err := f.GetInt()
if err != nil {
return 0
}
defer printExecutions()
for i := 0; i < calls%40; i++ {
op, err := f.GetInt()
if err != nil {
return 0
}
opType := op % len(ops)
switch ops[opType] {
case "createContainer":
createContainerFuzz(c.(*criService), f)
case "removeContainer":
removeContainerFuzz(c.(*criService), f)
case "addSandboxes":
addSandboxesFuzz(c.(*criService), f)
case "listContainers":
listContainersFuzz(c.(*criService), f)
case "startContainer":
startContainerFuzz(c.(*criService), f)
case "containerStats":
containerStatsFuzz(c.(*criService), f)
case "listContainerStats":
listContainerStatsFuzz(c.(*criService), f)
case "containerStatus":
containerStatusFuzz(c.(*criService), f)
case "stopContainer":
stopContainerFuzz(c.(*criService), f)
case "updateContainerResources":
updateContainerResourcesFuzz(c.(*criService), f)
case "listImages":
listImagesFuzz(c.(*criService), f)
case "removeImages":
removeImagesFuzz(c.(*criService), f)
case "imageStatus":
imageStatusFuzz(c.(*criService), f)
case "imageFsInfo":
imageFsInfoFuzz(c.(*criService), f)
case "listPodSandbox":
listPodSandboxFuzz(c.(*criService), f)
case "portForward":
portForwardFuzz(c.(*criService), f)
case "removePodSandbox":
removePodSandboxFuzz(c.(*criService), f)
case "runPodSandbox":
runPodSandboxFuzz(c.(*criService), f)
case "podSandboxStatus":
podSandboxStatusFuzz(c.(*criService), f)
case "stopPodSandbox":
stopPodSandboxFuzz(c.(*criService), f)
case "status":
statusFuzz(c.(*criService), f)
case "updateRuntimeConfig":
updateRuntimeConfigFuzz(c.(*criService), f)
}
}
return 1
}
func logExecution(apiName, request string) {
var logString strings.Builder
logString.WriteString(fmt.Sprintf("Calling %s with \n %s \n\n", apiName, request))
executionOrder = append(executionOrder, logString.String())
}
// createContainerFuzz creates a CreateContainerRequest and passes
// it to c.CreateContainer
func createContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.CreateContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.CreateContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.CreateContainer", reqString)
return nil
}
// removeContainerFuzz creates a RemoveContainerRequest and passes
// it to c.RemoveContainer
func removeContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemoveContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemoveContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemoveContainer", reqString)
return nil
}
// addSandboxesFuzz creates a sandbox and adds it to the sandboxstore
func addSandboxesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
quantity, err := f.GetInt()
if err != nil {
return err
}
for i := 0; i < quantity%20; i++ {
newSandbox, err := getSandboxFuzz(f)
if err != nil {
return err
}
err = c.sandboxStore.Add(newSandbox)
if err != nil {
return err
}
}
return nil
}
// getSandboxFuzz creates a sandbox
func getSandboxFuzz(f *fuzz.ConsumeFuzzer) (sandboxstore.Sandbox, error) {
metadata := sandboxstore.Metadata{}
status := sandboxstore.Status{}
err := f.GenerateStruct(&metadata)
if err != nil {
return sandboxstore.Sandbox{}, err
}
err = f.GenerateStruct(&status)
if err != nil {
return sandboxstore.Sandbox{}, err
}
reqString := fmt.Sprintf("metadata: %+v\nstatus: %+v\n", metadata, status)
logExecution("sandboxstore.NewSandbox", reqString)
return sandboxstore.NewSandbox(metadata, status), nil
}
// listContainersFuzz creates a ListContainersRequest and passes
// it to c.ListContainers
func listContainersFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListContainersRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListContainers(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListContainers", reqString)
return nil
}
// startContainerFuzz creates a StartContainerRequest and passes
// it to c.StartContainer
func startContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StartContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StartContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StartContainer", reqString)
return nil
}
// containerStatsFuzz creates a ContainerStatsRequest and passes
// it to c.ContainerStats
func containerStatsFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ContainerStatsRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ContainerStats(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ContainerStats", reqString)
return nil
}
// listContainerStatsFuzz creates a ListContainerStatsRequest and
// passes it to c.ListContainerStats
func listContainerStatsFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListContainerStatsRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListContainerStats(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListContainerStats", reqString)
return nil
}
// containerStatusFuzz creates a ContainerStatusRequest and passes
// it to c.ContainerStatus
func containerStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ContainerStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ContainerStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ContainerStatus", reqString)
return nil
}
// stopContainerFuzz creates a StopContainerRequest and passes
// it to c.StopContainer
func stopContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StopContainerRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StopContainer(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StopContainer", reqString)
return nil
}
// updateContainerResourcesFuzz creates a UpdateContainerResourcesRequest
// and passes it to c.UpdateContainerResources
func updateContainerResourcesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.UpdateContainerResourcesRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.UpdateContainerResources(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.UpdateContainerResources", reqString)
return nil
}
// listImagesFuzz creates a ListImagesRequest and passes it to
// c.ListImages
func listImagesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListImagesRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListImages(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListImages", reqString)
return nil
}
// removeImagesFuzz creates a RemoveImageRequest and passes it to
// c.RemoveImage
func removeImagesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemoveImageRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemoveImage(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemoveImage", reqString)
return nil
}
// imageStatusFuzz creates an ImageStatusRequest and passes it to
// c.ImageStatus
func imageStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ImageStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ImageStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ImageStatus", reqString)
return nil
}
// imageFsInfoFuzz creates an ImageFsInfoRequest and passes it to
// c.ImageFsInfo
func imageFsInfoFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ImageFsInfoRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ImageFsInfo(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ImageFsInfo", reqString)
return nil
}
// listPodSandboxFuzz creates a ListPodSandboxRequest and passes
// it to c.ListPodSandbox
func listPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.ListPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.ListPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.ListPodSandbox", reqString)
return nil
}
// portForwardFuzz creates a PortForwardRequest and passes it to
// c.PortForward
func portForwardFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.PortForwardRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.PortForward(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.PortForward", reqString)
return nil
}
// removePodSandboxFuzz creates a RemovePodSandboxRequest and
// passes it to c.RemovePodSandbox
func removePodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RemovePodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RemovePodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RemovePodSandbox", reqString)
return nil
}
// runPodSandboxFuzz creates a RunPodSandboxRequest and passes
// it to c.RunPodSandbox
func runPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.RunPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.RunPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.RunPodSandbox", reqString)
return nil
}
// podSandboxStatusFuzz creates a PodSandboxStatusRequest and
// passes it to
func podSandboxStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.PodSandboxStatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.PodSandboxStatus(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.PodSandboxStatus", reqString)
return nil
}
// stopPodSandboxFuzz creates a StopPodSandboxRequest and passes
// it to c.StopPodSandbox
func stopPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StopPodSandboxRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.StopPodSandbox(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.StopPodSandbox", reqString)
return nil
}
// statusFuzz creates a StatusRequest and passes it to c.Status
func statusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.StatusRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.Status(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.Status", reqString)
return nil
}
func updateRuntimeConfigFuzz(c *criService, f *fuzz.ConsumeFuzzer) error {
r := &runtime.UpdateRuntimeConfigRequest{}
err := f.GenerateStruct(r)
if err != nil {
return err
}
_, _ = c.UpdateRuntimeConfig(context.Background(), r)
reqString := fmt.Sprintf("%+v", r)
logExecution("c.UpdateRuntimeConfig", reqString)
return nil
}
// This creates a container directly in the store.
func getContainer(f *fuzz.ConsumeFuzzer) (containerstore.Container, error) {
metadata := containerstore.Metadata{}
status := containerstore.Status{}
err := f.GenerateStruct(&metadata)
if err != nil {
return containerstore.Container{}, err
}
err = f.GenerateStruct(&status)
if err != nil {
return containerstore.Container{}, err
}
container, err := containerstore.NewContainer(metadata, containerstore.WithFakeStatus(status))
return container, err
}
func newTestCRIServiceForFuzzing(f *fuzz.ConsumeFuzzer) *criService {
labels := label.NewStore()
return &criService{
config: testConfig,
imageFSPath: testImageFSPath,
os: ostesting.NewFakeOS(),
sandboxStore: sandboxstore.NewStore(labels),
imageStore: imagestore.NewStore(nil),
snapshotStore: snapshotstore.NewStore(),
sandboxNameIndex: registrar.NewRegistrar(),
containerStore: containerstore.NewStore(labels),
containerNameIndex: registrar.NewRegistrar(),
netPlugin: map[string]cni.CNI{
defaultNetworkPlugin: servertesting.NewFakeCNIPlugin(),
},
}
}

34
pkg/cri/server/fuzz.go Normal file
View File

@ -0,0 +1,34 @@
//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 server
import (
"fmt"
"github.com/containerd/containerd/pkg/cri/store/sandbox"
)
func SandboxStore(cs CRIService) (*sandbox.Store, error) {
s, ok := cs.(*criService)
if !ok {
return nil, fmt.Errorf("%+v is not server.criService", cs)
}
return s.sandboxStore, nil
}