Create tensorflow/security/fuzzing.

This should enable us to create fuzzers that can be used in open source, both in OSSFuzz (in the end, this is part of stabilizing the OSSFuzz integration) and by themselves alone (by passing the corresponding flags).

PiperOrigin-RevId: 315182751
Change-Id: I3b6c38b0bd0613fcfe12d0d61726a5a4bab9c09c
This commit is contained in:
Mihai Maruseac 2020-06-07 14:33:07 -07:00 committed by TensorFlower Gardener
parent e39f23b59a
commit a646c1280d
4 changed files with 130 additions and 0 deletions

View File

@ -13,6 +13,7 @@ tensorflow/python/tpu/profiler/pip_package/README
tensorflow/python/tpu/profiler/pip_package/build_pip_package.sh
tensorflow/python/tpu/profiler/pip_package/setup.py
tensorflow/python/tpu/tpu.bzl
tensorflow/security/fuzzing/tf_fuzzing.bzl
tensorflow/stream_executor/build_defs.bzl
tensorflow/third_party/BUILD
tensorflow/third_party/__init__.py

View File

@ -0,0 +1,17 @@
# Fuzzing TensorFlow.
# Since we use OSSFuzz, gather all fuzzers into a single place.
# This way, we can use tooling to determine the status of the fuzzing efforts.
load(
"//tensorflow/security/fuzzing:tf_fuzzing.bzl",
"tf_fuzz_target",
)
package(
licenses = ["notice"], # Apache 2.0
)
tf_fuzz_target(
name = "demo_fuzz",
srcs = ["demo_fuzz.cc"],
)

View File

@ -0,0 +1,32 @@
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
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.
==============================================================================*/
#include <cstdint>
#include <cstdlib>
// This is a demo fuzzer to test that the entire framework functions correctly.
// Once we start moving the existing fuzzers to this framework we will delete
// this.
// TODO(mihaimaruseac): Delete this when no longer needed
void DemoFuzzer(const uint8_t* data, size_t size) {
// Trigger a small bug that should be found by the fuzzer quite quickly
if (size > 10 && size % 3 == 2)
if (data[0] > data[1])
if (data[5] % data[2] == data[3]) abort();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
DemoFuzzer(data, size);
return 0;
}

View File

@ -0,0 +1,80 @@
"""Definitions for rules to fuzz TensorFlow."""
# TensorFlow fuzzing can be done in open source too.
#
# For a fuzzer ${FUZZ} we have the following setup:
# - ${FUZZ}_fuzz.cc : the implementation of the fuzzer
# - corpus/${FUZZ}/... : public corpus for the fuzzer
# - dictionaries/${FUZZ}.dict : fuzzing dictionary for the fuzzer
# - ${FUZZ}_internal/... : internal data for the fuzzer
#
# If a fuzzer needs some framework to build, we can use the ${FUZZ}_internal/
# directory to hold the harness. Or, if the infrastructure needs to be shared
# across multiple fuzzers (for example fuzzing ops), we can store it in other
# places in TF or move it to a different folder here. We will decide on these
# on a case by case basis, for now the ops fuzzing harness resides under
# tensorflow/core/kernels/fuzzing.
#
# The internal folder can also contain proto definitions (if using proto-based
# mutators to do structure aware fuzzing) or any other type of content that is
# not classified elsewhere.
# tf_cc_fuzz_target is a cc_test modified to include fuzzing support.
def tf_fuzz_target(
name,
# Fuzzing specific arguments
fuzzing_dict = [],
corpus = [],
parsers = [],
# Reporting bugs arguments, not used in open source
componentid = None,
hotlists = [],
# Additional cc_test control
data = [],
deps = [],
tags = [],
# Remaining cc_test arguments
**kwargs):
"""Specify how to build a TensorFlow fuzz target.
Args:
name: Mandatory name of the fuzzer target.
fuzzing_dict: An optional a set of dictionary files following
the AFL/libFuzzer dictionary syntax.
corpus: An optional set of files used as the initial test corpus
for the target. When doing "bazel test" in the default null-fuzzer
(unittest) mode, these files are automatically passed to the target
function.
parsers: An optional list of file extensions that the target supports.
Used by tools like autofuzz to reuse corpus sets across targets.
componentid: Used internally for reporting fuzz discovered bugs.
hotlists: Used internally for reporting fuzz discovered bugs.
data: Additional data dependencies passed to the underlying cc_test rule.
deps: An optional list of dependencies for the code you're fuzzing.
tags: Additional tags passed to the underlying cc_test rule.
**kwargs: Collects all remaining arguments and passes them to the
underlying cc_test rule generated by the macro.
"""
componentid = None
hotlists = None
# Fuzzers in open source must be run manually
tags = tags + ["manual"]
# Now, redirect to cc_test
native.cc_test(
name = name,
deps = deps, # TODO(mihaimaruseac): fuzzing lib?
data = data, # TODO(mihaimaruseac): dict, corpus, parsers??
tags = tags, # TODO(mihaimaruseac): fuzzing tags?
**kwargs
)