From 0789a0c02b78d70cc06c9c8f86d9a128f2b9d46c Mon Sep 17 00:00:00 2001 From: AdamKorcz Date: Mon, 5 Jul 2021 12:46:03 +0100 Subject: [PATCH] Add docker fetch fuzzer Signed-off-by: AdamKorcz --- contrib/fuzz/docker_fuzzer.go | 78 ++++++++++++++++++++++++++++++++++ contrib/fuzz/oss_fuzz_build.sh | 25 +++++++++++ 2 files changed, 103 insertions(+) create mode 100644 contrib/fuzz/docker_fuzzer.go create mode 100755 contrib/fuzz/oss_fuzz_build.sh diff --git a/contrib/fuzz/docker_fuzzer.go b/contrib/fuzz/docker_fuzzer.go new file mode 100644 index 000000000..ec275da10 --- /dev/null +++ b/contrib/fuzz/docker_fuzzer.go @@ -0,0 +1,78 @@ +// +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. +*/ + +/* + This fuzzer is run continuously by OSS-fuzz. + It is stored in contrib/fuzz for organization, + but in order to execute it, it must be moved to + remotes/docker first. +*/ + +package docker + +import ( + "context" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" +) + +func FuzzFetcher(data []byte) int { + dataLen := len(data) + if dataLen == 0 { + return -1 + } + + s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header().Set("content-range", fmt.Sprintf("bytes %d-%d/%d", 0, dataLen-1, dataLen)) + rw.Header().Set("content-length", fmt.Sprintf("%d", dataLen)) + rw.Write(data) + })) + defer s.Close() + + u, err := url.Parse(s.URL) + if err != nil { + return 0 + } + + f := dockerFetcher{&dockerBase{ + repository: "nonempty", + }} + host := RegistryHost{ + Client: s.Client(), + Host: u.Host, + Scheme: u.Scheme, + Path: u.Path, + } + + ctx := context.Background() + req := f.request(host, http.MethodGet) + rc, err := f.open(ctx, req, "", 0) + if err != nil { + return 0 + } + b, err := ioutil.ReadAll(rc) + if err != nil { + return 0 + } + + expected := data + if len(b) != len(expected) { + panic("len of request is not equal to len of expected but should be") + } + return 1 +} diff --git a/contrib/fuzz/oss_fuzz_build.sh b/contrib/fuzz/oss_fuzz_build.sh new file mode 100755 index 000000000..92c6ca8e2 --- /dev/null +++ b/contrib/fuzz/oss_fuzz_build.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +# 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. + +cd "$(dirname "${BASH_SOURCE[0]}")" +cd ../../ + +compile_go_fuzzer github.com/containerd/containerd/contrib/fuzz FuzzFiltersParse fuzz_filters_parse +compile_go_fuzzer github.com/containerd/containerd/contrib/fuzz FuzzPlatformsParse fuzz_platforms_parse + +mv contrib/fuzz/docker_fuzzer.go remotes/docker/ +compile_go_fuzzer github.com/containerd/containerd/remotes/docker FuzzFetcher fuzz_fetcher +mv remotes/docker/docker_fuzzer.go contrib/fuzz/