diff --git a/WORKSPACE b/WORKSPACE index 1901e46863..b409d1433c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -966,3 +966,16 @@ http_archive( strip_prefix = "curl-8.10.1", url = "https://curl.haxx.se/download/curl-8.10.1.tar.gz", ) +http_archive( + name = "rules_fuzzing", + sha256 = "2cc83f91e3048d275f3ebc8b627ebca5c0fc401b3f093a4de398b11ec3e21137", + strip_prefix = "rules_fuzzing-v0.8.0", + urls = ["https://github.com/bazelbuild/rules_fuzzing/releases/download/v0.8.0/rules_fuzzing-v0.8.0.tar.gz"], +) + +load("@rules_fuzzing//fuzzing:repositories.bzl", "rules_fuzzing_dependencies") +rules_fuzzing_dependencies() +load("@rules_fuzzing//fuzzing:init.bzl", "rules_fuzzing_init") +rules_fuzzing_init() +load("@fuzzing_py_deps//:requirements.bzl", "install_deps") +install_deps() diff --git a/mediapipe/framework/fuzz/BUILD b/mediapipe/framework/fuzz/BUILD new file mode 100644 index 0000000000..bc8a35d069 --- /dev/null +++ b/mediapipe/framework/fuzz/BUILD @@ -0,0 +1,27 @@ +# Copyright 2026 The MediaPipe 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. + +load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test") + +package(default_visibility = ["//visibility:private"]) + +cc_fuzz_test( + name = "calculator_graph_config_fuzz", + srcs = ["calculator_graph_config_fuzz.cc"], + corpus = glob(["corpus/**"], allow_empty = True), + deps = [ + "//mediapipe/framework:calculator_cc_proto", + "//mediapipe/framework:calculator_graph", + ], +) diff --git a/mediapipe/framework/fuzz/calculator_graph_config_fuzz.cc b/mediapipe/framework/fuzz/calculator_graph_config_fuzz.cc new file mode 100644 index 0000000000..3d7d98b7fc --- /dev/null +++ b/mediapipe/framework/fuzz/calculator_graph_config_fuzz.cc @@ -0,0 +1,38 @@ +// Copyright 2026 The MediaPipe 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. +// +// libFuzzer harness for the CalculatorGraphConfig protobuf parser surface. +// +// First-cut harness: raw byte input parsed via CalculatorGraphConfig::ParseFromArray +// then handed to CalculatorGraph::Initialize. Memory-safety violations in the +// proto parsing or graph initialization paths surface as ASAN/UBSAN crashes. + +#include +#include + +#include "mediapipe/framework/calculator.pb.h" +#include "mediapipe/framework/calculator_graph.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + mediapipe::CalculatorGraphConfig config; + if (!config.ParseFromArray(data, static_cast(size))) { + // Wire-format rejected by protobuf — not an interesting input. + return 0; + } + mediapipe::CalculatorGraph graph; + // absl::Status from Initialize is intentionally discarded; we only crash + // on memory-safety violations, not on semantic errors. + (void)graph.Initialize(config); + return 0; +}