diff --git a/projects/knative/Dockerfile b/projects/knative/Dockerfile new file mode 100644 index 000000000..b1ae5fb1f --- /dev/null +++ b/projects/knative/Dockerfile @@ -0,0 +1,26 @@ +# Copyright 2022 Google LLC +# +# 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. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder-go +RUN git clone --depth 1 https://github.com/knative/pkg +RUN git clone --depth 1 https://github.com/knative/serving +WORKDIR $SRC/pkg +COPY build.sh \ + json_fuzzer.go \ + fuzz_activatornet.go \ + fuzz_pkg_metrics.go \ + fuzz_pkg_websocket.go \ + $SRC/ diff --git a/projects/knative/build.sh b/projects/knative/build.sh new file mode 100644 index 000000000..8cd9bc9b8 --- /dev/null +++ b/projects/knative/build.sh @@ -0,0 +1,37 @@ +#!/bin/bash -eu +# Copyright 2022 Google LLC +# +# 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. +# +################################################################################ + +printf "package metrics\nimport _ \"github.com/AdamKorcz/go-118-fuzz-build/testing\"\n" > $SRC/pkg/metrics/registerfuzzdep.go +go mod tidy && go mod vendor +cp $SRC/json_fuzzer.go $SRC/pkg/webhook/json/ +mv $SRC/pkg/webhook/json/decode_test.go $SRC/pkg/webhook/json/decode_test_fuzz.go +compile_go_fuzzer knative.dev/pkg/webhook/json FuzzJsonDecode fuzz_json_decode + +cp $SRC/fuzz_pkg_metrics.go $SRC/pkg/metrics/ +compile_native_go_fuzzer knative.dev/pkg/metrics FuzzNewObservabilityConfigFromConfigMap FuzzNewObservabilityConfigFromConfigMap + +cp $SRC/fuzz_pkg_websocket.go $SRC/pkg/websocket/ +mv $SRC/pkg/websocket/connection_test.go $SRC/pkg/websocket/connection_fuzz.go +compile_native_go_fuzzer knative.dev/pkg/websocket FuzzSendRawMessage FuzzSendRawMessage + +cp $SRC/fuzz_activatornet.go $SRC/serving/pkg/activator/net/ +cd $SRC/serving +mv pkg/activator/net/throttler_test.go pkg/activator/net/throttler_test_fuzz.go +mv pkg/activator/net/revision_backends_test.go pkg/activator/net/revision_backends_test_fuzz.go +printf "package net\nimport _ \"github.com/AdamKorcz/go-118-fuzz-build/testing\"\n" > $SRC/serving/pkg/activator/net/registerfuzzdep.go +go mod tidy && go mod vendor +compile_native_go_fuzzer knative.dev/serving/pkg/activator/net FuzzNewRevisionThrottler FuzzNewRevisionThrottler diff --git a/projects/knative/fuzz_activatornet.go b/projects/knative/fuzz_activatornet.go new file mode 100644 index 000000000..ef35c58f4 --- /dev/null +++ b/projects/knative/fuzz_activatornet.go @@ -0,0 +1,94 @@ +// Copyright 2022 Google LLC +// +// 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 net + +import ( + "context" + "os" + "testing" + + fuzz "github.com/AdaLogics/go-fuzz-headers" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" + + pkgnet "knative.dev/networking/pkg/apis/networking" + "knative.dev/serving/pkg/queue" + + "knative.dev/pkg/injection" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/record" + + "knative.dev/pkg/controller" +) + +func NewFuzzLogger() *zap.SugaredLogger { + var config zap.Config + config = zap.NewProductionConfig() + // Config customization goes here if any + config.OutputPaths = []string{os.DevNull} + logger, err := config.Build() + if err != nil { + panic(err) + } + return logger.Named("knative-log").Sugar() +} + +func FuzzNewRevisionThrottler(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + ff := fuzz.NewConsumer(data) + + revName := types.NamespacedName{} + ff.GenerateStruct(&revName) + + containerConcurrency, err := ff.GetInt() + if err != nil { + t.Skip() + } + params := queue.BreakerParams{} + ff.GenerateStruct(¶ms) + if params.QueueDepth <= 0 { + t.Skip() + } + if params.MaxConcurrency < 0 { + t.Skip() + } + if params.InitialCapacity < 0 || params.InitialCapacity > params.MaxConcurrency { + t.Skip() + } + logger := NewFuzzLogger() + rt := newRevisionThrottler(revName, containerConcurrency%10, pkgnet.ServicePortNameHTTP1, params, logger) + + //ctx := context.Background() + ctx, cancel := SetupFakeContextWithCancel() + defer cancel() + throttler := newTestThrottler(ctx) + throttler.revisionThrottlers[revName] = rt + + update := revisionDestsUpdate{ + Rev: revName, + ClusterIPDest: "", + Dests: sets.NewString("ip3", "ip2", "ip1"), + } + throttler.handleUpdate(update) + }) +} + +func SetupFakeContextWithCancel() (context.Context, context.CancelFunc) { + ctx, c := context.WithCancel(context.Background()) + ctx = controller.WithEventRecorder(ctx, record.NewFakeRecorder(1000)) + ctx, _ = injection.Fake.SetupInformers(ctx, &rest.Config{}) + return ctx, c +} diff --git a/projects/knative/fuzz_pkg_metrics.go b/projects/knative/fuzz_pkg_metrics.go new file mode 100644 index 000000000..f1354b151 --- /dev/null +++ b/projects/knative/fuzz_pkg_metrics.go @@ -0,0 +1,30 @@ +// Copyright 2022 Google LLC +// +// 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 metrics + +import ( + fuzz "github.com/AdaLogics/go-fuzz-headers" + corev1 "k8s.io/api/core/v1" + "testing" +) + +func FuzzNewObservabilityConfigFromConfigMap(f *testing.F) { + f.Fuzz(func(t *testing.T, configMapData []byte) { + ff := fuzz.NewConsumer(configMapData) + cm := &corev1.ConfigMap{} + ff.GenerateStruct(cm) + _, _ = NewObservabilityConfigFromConfigMap(cm) + }) +} diff --git a/projects/knative/fuzz_pkg_websocket.go b/projects/knative/fuzz_pkg_websocket.go new file mode 100644 index 000000000..3e97cd14a --- /dev/null +++ b/projects/knative/fuzz_pkg_websocket.go @@ -0,0 +1,42 @@ +// Copyright 2022 Google LLC +// +// 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 websocket + +import ( + "github.com/gorilla/websocket" + "testing" +) + +func FuzzSendRawMessage(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + spy := &inspectableConnection{ + writeMessageCalls: make(chan struct{}, 1), + } + + conn := newConnection(staticConnFactory(spy), nil) + conn.connect() + + if got := conn.Status(); got != nil { + t.Skip() + } + + if got := conn.SendRaw(websocket.BinaryMessage, data); got != nil { + t.Skip() + } + if len(spy.writeMessageCalls) != 1 { + t.Fatalf("Expected 'WriteMessage' to be called once, but was called %v times", spy.writeMessageCalls) + } + }) +} diff --git a/projects/knative/json_fuzzer.go b/projects/knative/json_fuzzer.go new file mode 100644 index 000000000..1c3f694c1 --- /dev/null +++ b/projects/knative/json_fuzzer.go @@ -0,0 +1,20 @@ +// Copyright 2022 Google LLC +// +// 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 json + +func FuzzJsonDecode(data []byte) int { + Decode(data, &fixture{}, false) + return 1 +} diff --git a/projects/knative/project.yaml b/projects/knative/project.yaml new file mode 100644 index 000000000..c89e9f412 --- /dev/null +++ b/projects/knative/project.yaml @@ -0,0 +1,11 @@ +homepage: "https://knative.dev/" +language: go +primary_contact: "security@knative.team" +main_repo: "https://github.com/knative" +vendor_ccs: + - "adam@adalogics.com" + - "david@adalogics.com" +fuzzing_engines: + - libfuzzer +sanitizers: + - address