aboutsummaryrefslogtreecommitdiff
path: root/third_party
diff options
context:
space:
mode:
authorJohn Williams <jrw@google.com>2020-05-21 15:13:52 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-22 00:39:11 +0000
commit8cce349b0a595ddf7178d5730e980ace3a1d1a53 (patch)
tree44007d378fcf29a4d11751b1a5855d1335691c1e /third_party
parent10daf41d41150074dd34fe1671d72d18155b63f6 (diff)
downloadopenscreen-8cce349b0a595ddf7178d5730e980ace3a1d1a53.tar.gz
Added support for libprotobuf-mutator.
The files added by this change are copied from Chromium with slight alterations to remove dependencies on Chromium build infrastructure. Change-Id: I95d96a02eaa542a8f278dbf46bd8a37a814c9c5a Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/2212944 Reviewed-by: Brandon Tolsch <btolsch@chromium.org> Commit-Queue: Brandon Tolsch <btolsch@chromium.org>
Diffstat (limited to 'third_party')
-rw-r--r--third_party/libprotobuf-mutator/BUILD.gn87
-rw-r--r--third_party/libprotobuf-mutator/fuzzable_proto_library.gni62
-rw-r--r--third_party/protobuf/BUILD.gn1
3 files changed, 150 insertions, 0 deletions
diff --git a/third_party/libprotobuf-mutator/BUILD.gn b/third_party/libprotobuf-mutator/BUILD.gn
new file mode 100644
index 00000000..cc3eeaeb
--- /dev/null
+++ b/third_party/libprotobuf-mutator/BUILD.gn
@@ -0,0 +1,87 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build_overrides/build.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
+import("//third_party/libprotobuf-mutator/fuzzable_proto_library.gni")
+
+config("include_config") {
+ include_dirs = [ "src/" ]
+}
+
+source_set("libprotobuf-mutator") {
+ testonly = true
+
+ configs += [ ":include_config" ]
+
+ public_configs = [ ":include_config" ]
+ sources = [
+ "src/src/binary_format.cc",
+ "src/src/libfuzzer/libfuzzer_macro.cc",
+ "src/src/libfuzzer/libfuzzer_mutator.cc",
+ "src/src/mutator.cc",
+ "src/src/text_format.cc",
+ "src/src/utf8_fix.cc",
+ ]
+
+ # Allow users of LPM to use protobuf reflection and other features from
+ # protobuf_full.
+ public_deps = [ "//third_party/protobuf:protobuf_full" ]
+}
+
+# This protoc plugin, like the compiler, should only be built for the host
+# architecture.
+if (current_toolchain == host_toolchain) {
+ # This plugin will be needed to fuzz most protobuf code in Chromium. That's
+ # because production protobuf code must contain the line:
+ # "option optimize_for = LITE_RUNTIME", which instructs the proto compiler not
+ # to compile the proto using the full protobuf runtime. This allows Chromium
+ # not to depend on the full protobuf library, but prevents
+ # libprotobuf-mutator from fuzzing because the lite runtime lacks needed
+ # features (such as reflection). The plugin simply compiles a proto library
+ # as normal but ensures that is compiled with the full protobuf runtime.
+ executable("override_lite_runtime_plugin") {
+ sources = [ "protoc_plugin/protoc_plugin.cc" ]
+ deps = [ "//third_party/protobuf:protoc_lib" ]
+ public_configs = [ "//third_party/protobuf:protobuf_config" ]
+ }
+ # To use the plugin in a proto_library you want to fuzz, change the build
+ # target to fuzzable_proto_library (defined in
+ # //third_party/libprotobuf-mutator/fuzzable_proto_library.gni)
+}
+
+# The CQ will try building this target without "use_libfuzzer" if it is defined.
+# That will cause the build to fail, so don't define it when "use_libfuzzer" is
+# is false.
+if (use_libfuzzer) {
+ # Test that override_lite_runtime_plugin is working when built. This target
+ # contains files that are optimized for LITE_RUNTIME and which import other
+ # files that are also optimized for LITE_RUNTIME.
+ openscreen_fuzzer_test("override_lite_runtime_plugin_test_fuzzer") {
+ sources = [ "protoc_plugin/test_fuzzer.cc" ]
+ deps = [
+ ":libprotobuf-mutator",
+ ":override_lite_runtime_plugin_test_fuzzer_proto",
+ ]
+ }
+}
+
+# Proto library for override_lite_runtime_plugin_test_fuzzer
+fuzzable_proto_library("override_lite_runtime_plugin_test_fuzzer_proto") {
+ sources = [
+ "protoc_plugin/imported.proto",
+ "protoc_plugin/imported_publicly.proto",
+ "protoc_plugin/test_fuzzer_input.proto",
+ ]
+}
+
+# Avoid CQ complaints on platforms we don't care about (ie: iOS).
+# Also prevent people from using this to include protobuf_full into a production
+# build of Chrome.
+if (use_libfuzzer) {
+ # Component that can provide protobuf_full to non-testonly targets
+ static_library("protobuf_full") {
+ public_deps = [ "//third_party/protobuf:protobuf_full" ]
+ }
+}
diff --git a/third_party/libprotobuf-mutator/fuzzable_proto_library.gni b/third_party/libprotobuf-mutator/fuzzable_proto_library.gni
new file mode 100644
index 00000000..fee136c6
--- /dev/null
+++ b/third_party/libprotobuf-mutator/fuzzable_proto_library.gni
@@ -0,0 +1,62 @@
+# Copyright 2020 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# A fuzzable_proto_library is a proto_library that is the same as any other in
+# non-fuzzer builds (ie: use_libfuzzer=false). However, in fuzzer builds, the
+# proto_library is built with the full protobuf runtime and any "optimize_for =
+# LITE_RUNTIME" options are ignored. This is done because libprotobuf-mutator
+# needs the full protobuf runtime, but proto_libraries shipped in chrome must
+# use the optimize for LITE_RUNTIME option which is incompatible with the full
+# protobuf runtime. tl;dr: A fuzzable_proto_library is a proto_library that can
+# be fuzzed with libprotobuf-mutator and shipped in Chrome.
+
+import("//build_overrides/build.gni")
+import("//testing/libfuzzer/fuzzer_test.gni")
+import("//third_party/protobuf/proto_library.gni")
+
+template("fuzzable_proto_library") {
+ # Only make the proto library fuzzable if we are doing a build that we can
+ # use LPM on (i.e. libFuzzer not on Chrome OS).
+ if (use_libfuzzer && current_toolchain != "//build/toolchain/cros:target") {
+ proto_library("proto_library_" + target_name) {
+ forward_variables_from(invoker, "*")
+ assert(current_toolchain == host_toolchain)
+ if (!defined(proto_deps)) {
+ proto_deps = []
+ }
+ proto_deps +=
+ [ "//third_party/libprotobuf-mutator:override_lite_runtime_plugin" ]
+
+ extra_configs = [ "//third_party/protobuf:protobuf_config" ]
+ }
+
+ # Inspired by proto_library.gni's handling of
+ # component_build_force_source_set.
+ if (defined(component_build_force_source_set) &&
+ component_build_force_source_set && is_component_build) {
+ link_target_type = "source_set"
+ } else {
+ link_target_type = "static_library"
+ }
+
+ # By making target a static_library or source_set, we can add protobuf_full
+ # to public_deps.
+ target(link_target_type, target_name) {
+ if (defined(invoker.testonly)) {
+ testonly = invoker.testonly
+ }
+ sources = [ "//third_party/libprotobuf-mutator/dummy.cc" ]
+ public_deps = [
+ ":proto_library_" + target_name,
+ "//third_party/libprotobuf-mutator:protobuf_full",
+ ]
+ }
+ } else {
+ # fuzzable_proto_library should behave like a proto_library when
+ # !use_libfuzzer.
+ proto_library(target_name) {
+ forward_variables_from(invoker, "*")
+ }
+ }
+}
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn
index aa898d12..11516480 100644
--- a/third_party/protobuf/BUILD.gn
+++ b/third_party/protobuf/BUILD.gn
@@ -198,6 +198,7 @@ static_library("protobuf_full") {
visibility = [
":protoc_lib",
"../chromium_quic/src/third_party:quic_trace",
+ "//third_party/libprotobuf-mutator:*",
]
}