aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/core/kernels/fuzzing
diff options
context:
space:
mode:
authorGravatar Frank Chen <frankchn@google.com>2017-07-18 17:04:44 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2017-07-18 17:09:10 -0700
commitafb6962992b8e9e14e27989772519ee4fe38e851 (patch)
tree353cccd3aa8adb07a0c0b2913c4cecd6338de81f /tensorflow/core/kernels/fuzzing
parent06acccabcb41513c76bbfffcd17817a7b136494b (diff)
Introduces fuzzers for some complex operations and kernels in TensorFlow in preparation for eventaul fuzzing using Google OSS-Fuzz.
PiperOrigin-RevId: 162425120
Diffstat (limited to 'tensorflow/core/kernels/fuzzing')
-rw-r--r--tensorflow/core/kernels/fuzzing/BUILD55
-rw-r--r--tensorflow/core/kernels/fuzzing/decode_base64_fuzz.cc29
-rw-r--r--tensorflow/core/kernels/fuzzing/decode_jpeg_fuzz.cc29
-rw-r--r--tensorflow/core/kernels/fuzzing/decode_json_example_fuzz.cc29
-rw-r--r--tensorflow/core/kernels/fuzzing/decode_png_fuzz.cc29
-rw-r--r--tensorflow/core/kernels/fuzzing/encode_base64_fuzz.cc29
-rw-r--r--tensorflow/core/kernels/fuzzing/encode_jpeg_fuzz.cc63
-rw-r--r--tensorflow/core/kernels/fuzzing/example_proto_fast_parsing_fuzz.cc64
-rw-r--r--tensorflow/core/kernels/fuzzing/fuzz_session.h156
-rw-r--r--tensorflow/core/kernels/fuzzing/identity_fuzz.cc45
-rw-r--r--tensorflow/core/kernels/fuzzing/parse_tensor_op_fuzz.cc45
-rw-r--r--tensorflow/core/kernels/fuzzing/string_split_fuzz.cc60
-rw-r--r--tensorflow/core/kernels/fuzzing/string_to_number_fuzz.cc32
-rw-r--r--tensorflow/core/kernels/fuzzing/tf_ops_fuzz_target_lib.bzl13
14 files changed, 678 insertions, 0 deletions
diff --git a/tensorflow/core/kernels/fuzzing/BUILD b/tensorflow/core/kernels/fuzzing/BUILD
new file mode 100644
index 0000000000..3e7f9bdb44
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/BUILD
@@ -0,0 +1,55 @@
+licenses(["notice"]) # Apache 2.0
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+cc_library(
+ name = "fuzz_session",
+ hdrs = ["fuzz_session.h"],
+ deps = [
+ "//tensorflow/cc:cc_ops",
+ "//tensorflow/cc:scope",
+ "//tensorflow/core:all_kernels",
+ "//tensorflow/core:core_cpu",
+ "//tensorflow/core:direct_session",
+ "//tensorflow/core:ops",
+ "//tensorflow/core:tensorflow",
+ ],
+)
+
+filegroup(
+ name = "all_files",
+ srcs = glob(
+ ["**/*"],
+ exclude = [
+ "**/METADATA",
+ "**/OWNERS",
+ ],
+ ),
+ visibility = ["//tensorflow:__subpackages__"],
+)
+
+load("//tensorflow/core/kernels/fuzzing:tf_ops_fuzz_target_lib.bzl", "tf_ops_fuzz_target_lib")
+
+tf_ops_fuzz_target_lib("identity")
+
+tf_ops_fuzz_target_lib("string_to_number")
+
+tf_ops_fuzz_target_lib("string_split")
+
+tf_ops_fuzz_target_lib("encode_base64")
+
+tf_ops_fuzz_target_lib("decode_base64")
+
+tf_ops_fuzz_target_lib("encode_jpeg")
+
+tf_ops_fuzz_target_lib("decode_png")
+
+tf_ops_fuzz_target_lib("decode_jpeg")
+
+tf_ops_fuzz_target_lib("example_proto_fast_parsing")
+
+tf_ops_fuzz_target_lib("parse_tensor_op")
+
+tf_ops_fuzz_target_lib("decode_json_example")
diff --git a/tensorflow/core/kernels/fuzzing/decode_base64_fuzz.cc b/tensorflow/core/kernels/fuzzing/decode_base64_fuzz.cc
new file mode 100644
index 0000000000..6d4a9dfdef
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/decode_base64_fuzz.cc
@@ -0,0 +1,29 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzDecodeBase64 : public FuzzStringInputOp {
+ SINGLE_INPUT_OP_BUILDER(DT_STRING, DecodeBase64);
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzDecodeBase64);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/decode_jpeg_fuzz.cc b/tensorflow/core/kernels/fuzzing/decode_jpeg_fuzz.cc
new file mode 100644
index 0000000000..b084a97204
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/decode_jpeg_fuzz.cc
@@ -0,0 +1,29 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzDecodeJpeg : public FuzzStringInputOp {
+ SINGLE_INPUT_OP_BUILDER(DT_STRING, DecodeJpeg);
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzDecodeJpeg);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/decode_json_example_fuzz.cc b/tensorflow/core/kernels/fuzzing/decode_json_example_fuzz.cc
new file mode 100644
index 0000000000..9dd795b94e
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/decode_json_example_fuzz.cc
@@ -0,0 +1,29 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzDecodeJSONExample : public FuzzStringInputOp {
+ SINGLE_INPUT_OP_BUILDER(DT_STRING, DecodeJSONExample);
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzDecodeJSONExample);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/decode_png_fuzz.cc b/tensorflow/core/kernels/fuzzing/decode_png_fuzz.cc
new file mode 100644
index 0000000000..4a68a5b580
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/decode_png_fuzz.cc
@@ -0,0 +1,29 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzDecodePng : public FuzzStringInputOp {
+ SINGLE_INPUT_OP_BUILDER(DT_STRING, DecodePng);
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzDecodePng);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/encode_base64_fuzz.cc b/tensorflow/core/kernels/fuzzing/encode_base64_fuzz.cc
new file mode 100644
index 0000000000..2d6c82826c
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/encode_base64_fuzz.cc
@@ -0,0 +1,29 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzEncodeBase64 : public FuzzSession {
+ SINGLE_INPUT_OP_BUILDER(DT_STRING, EncodeBase64);
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzEncodeBase64);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/encode_jpeg_fuzz.cc b/tensorflow/core/kernels/fuzzing/encode_jpeg_fuzz.cc
new file mode 100644
index 0000000000..81b6e49124
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/encode_jpeg_fuzz.cc
@@ -0,0 +1,63 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzEncodeJpeg : public FuzzSession {
+ SINGLE_INPUT_OP_BUILDER(DT_UINT8, EncodeJpeg);
+
+ void FuzzImpl(const uint8_t* data, size_t size) final {
+ if (size < 6) return;
+
+ // Pick random channels and aspect ratio, and then set the
+ // input based upon the aspect ratio and size.
+ int64 channels = (data[0] % 2) * 2 + 1; // 1, 3
+ int64 height = data[1] + (data[2] << 8);
+ int64 width = data[2] + (data[3] << 8);
+ if (width == 0) return;
+
+ // TODO(dga): kcc@ notes: better to use actual supplied h, w and then
+ // trim them if needed to ensure w*h <= size-4.
+ double hw_ratio = height / width;
+ int64 remaining_bytes = size - 5;
+ int64 pixels = remaining_bytes / channels;
+ height = static_cast<int64>(floor(sqrt(hw_ratio * pixels)));
+ if (height == 0) return;
+ width = static_cast<int64>(floor(pixels / height));
+ if (width == 0) return;
+ size_t actual_pixels = height * width * channels;
+ if (actual_pixels == 0) return;
+
+ // TODO(dga): Generalize this by borrowing the AsTensor logic
+ // from tf testing, once we have a few more fuzzers written.
+ Tensor input_tensor(tensorflow::DT_UINT8,
+ TensorShape({height, width, channels}));
+ auto flat_tensor = input_tensor.flat<uint8>();
+ for (size_t i = 0; i < actual_pixels; i++) {
+ flat_tensor(i) = data[i];
+ }
+ // TODO(b/32704451): Don't just ignore the ::tensorflow::Status object!
+ RunOneInput(input_tensor).IgnoreError();
+ }
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzEncodeJpeg);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/example_proto_fast_parsing_fuzz.cc b/tensorflow/core/kernels/fuzzing/example_proto_fast_parsing_fuzz.cc
new file mode 100644
index 0000000000..d91a351c59
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/example_proto_fast_parsing_fuzz.cc
@@ -0,0 +1,64 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+// Fuzz inputs to the example proto decoder.
+// TODO(dga): Make this more comprehensive.
+// Right now, it's just a quick PoC to show how to attach the
+// plumbing, but it needs some real protos to chew on as a
+// corpus, and the sparse/dense parts should be made more rich
+// to achieve higher code coverage.
+
+class FuzzExampleProtoFastParsing : public FuzzSession {
+ void BuildGraph(const Scope& scope) final {
+ using namespace ::tensorflow::ops; // NOLINT(build/namespaces)
+ // The serialized proto.
+ auto input = Placeholder(scope.WithOpName("input1"), DT_STRING);
+
+ auto in_expanded = ExpandDims(scope, input, Const<int>(scope, 0));
+
+ auto names = Const(scope, {"noname"});
+ std::vector<Output> dense_keys = {Const(scope, {"a"})};
+ std::vector<Output> sparse_keys; // Empty.
+ std::vector<Output> dense_defaults = {Const(scope, {1.0f})};
+
+ DataTypeSlice sparse_types = {};
+ std::vector<PartialTensorShape> dense_shapes;
+ dense_shapes.push_back(PartialTensorShape());
+
+ std::ignore = ParseExample(scope.WithOpName("output"), in_expanded, names,
+ sparse_keys, dense_keys, dense_defaults,
+ sparse_types, dense_shapes);
+ }
+
+ void FuzzImpl(const uint8_t* data, size_t size) final {
+ // TODO(dga): Test the batch case also.
+ Tensor input_tensor(tensorflow::DT_STRING, TensorShape({}));
+ input_tensor.scalar<string>()() =
+ string(reinterpret_cast<const char*>(data), size);
+ // TODO(b/32704451): Don't just ignore the ::tensorflow::Status object!
+ RunOneInput(input_tensor).IgnoreError();
+ }
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzExampleProtoFastParsing);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/fuzz_session.h b/tensorflow/core/kernels/fuzzing/fuzz_session.h
new file mode 100644
index 0000000000..fb518798b2
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/fuzz_session.h
@@ -0,0 +1,156 @@
+/* Copyright 2016 Google Inc. 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.
+==============================================================================*/
+
+#ifndef LEARNING_BRAIN_KERNELS_FUZZING_FUZZ_SESSION_H_
+#define LEARNING_BRAIN_KERNELS_FUZZING_FUZZ_SESSION_H_
+
+#include "tensorflow/cc/framework/scope.h"
+#include "tensorflow/core/graph/graph.h"
+#include "tensorflow/core/public/session.h"
+
+// Standard invoking function macro to dispatch to a fuzzer class.
+#ifndef PLATFORM_WINDOWS
+#define STANDARD_TF_FUZZ_FUNCTION(FuzzerClass) \
+ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { \
+ static FuzzerClass* fuzzer = new FuzzerClass(); \
+ return fuzzer->Fuzz(data, size); \
+ }
+#else
+// We don't compile this for Windows, MSVC doesn't like it as pywrap in Windows
+// links all the code into one big object file and there are conflicting
+// function names.
+#define STANDARD_TF_FUZZ_FUNCTION(FuzzerClass)
+#endif
+
+// Standard builder for hooking one placeholder to one op.
+#define SINGLE_INPUT_OP_BUILDER(dtype, opName) \
+ void BuildGraph(const Scope& scope) override { \
+ auto op_node = \
+ tensorflow::ops::Placeholder(scope.WithOpName("input1"), dtype); \
+ std::ignore = \
+ tensorflow::ops::opName(scope.WithOpName("output"), op_node); \
+ }
+
+namespace tensorflow {
+namespace fuzzing {
+
+// Create a TensorFlow session using a specific GraphDef created
+// by BuildGraph(), and make it available for fuzzing.
+// Users must override BuildGraph and FuzzImpl to specify
+// (1) which operations are being fuzzed; and
+// (2) How to translate the uint8_t* buffer from the fuzzer
+// to a Tensor or Tensors that are semantically appropriate
+// for the op under test.
+// For the simple cases of testing a single op that takes a single
+// input Tensor, use the SINGLE_INPUT_OP_BUILDER(dtype, opName) macro in place
+// of defining BuildGraphDef.
+//
+// Typical use:
+// class FooFuzzer : public FuzzSession {
+// SINGLE_INPUT_OP_BUILDER(DT_INT8, Identity);
+// void FuzzImpl(const uint8_t* data, size_t size) {
+// ... convert data and size to a Tensor, pass it to:
+// RunOneInput(input_tensor);
+//
+class FuzzSession {
+ public:
+ FuzzSession() : initialized_(false) {}
+ virtual ~FuzzSession() {}
+
+ // Constructs a Graph using the supplied Scope.
+ // By convention, the graph should have inputs named "input1", ...
+ // "inputN", and one output node, named "output".
+ // Users of FuzzSession should override this method to create their graph.
+ virtual void BuildGraph(const Scope& scope) {}
+
+ // Implements the logic that converts an opaque byte buffer
+ // from the fuzzer to Tensor inputs to the graph. Users must override.
+ virtual void FuzzImpl(const uint8_t* data, size_t size) {}
+
+ // Initializes the FuzzSession. Not safe for multithreading.
+ // Separate init function because the call to virtual BuildGraphDef
+ // can't be put into the constructor.
+ Status InitIfNeeded() {
+ if (initialized_) {
+ return Status::OK();
+ }
+ initialized_ = true;
+
+ Scope root = Scope::NewRootScope().ExitOnError();
+ SessionOptions options;
+ session_ = std::unique_ptr<Session>(NewSession(options));
+
+ BuildGraph(root);
+
+ GraphDef graph_def;
+ TF_CHECK_OK(root.ToGraphDef(&graph_def));
+
+ Status status = session_->Create(graph_def);
+ if (!status.ok()) {
+ // This is FATAL, because this code is designed to fuzz an op
+ // within a session. Failure to create the session means we
+ // can't send any data to the op.
+ LOG(FATAL) << "Could not create session: " << status.error_message();
+ }
+ return status;
+ }
+
+ // Runs the TF session by pulling on the "output" node, attaching
+ // the supplied input_tensor to the "input1" node, and discarding
+ // any returned output.
+ Status RunOneInput(const Tensor& input_tensor) {
+ return session_->Run({{"input1", input_tensor}}, {}, {"output"}, nullptr);
+ }
+
+ Status RunTwoInputs(const Tensor& input1, const Tensor& input2) {
+ return session_->Run({{"input1", input1}, {"input2", input2}}, {},
+ {"output"}, nullptr);
+ }
+
+ // Dispatches to FuzzImpl; small amount of sugar to keep the code
+ // of the per-op fuzzers tiny.
+ int Fuzz(const uint8_t* data, size_t size) {
+ Status status = InitIfNeeded();
+ TF_CHECK_OK(status) << "Fuzzer graph initialization failed: "
+ << status.error_message();
+ // No return value from fuzzing: Success is defined as "did not
+ // crash". The actual application results are irrelevant.
+ FuzzImpl(data, size);
+ return 0;
+ }
+
+ private:
+ bool initialized_;
+ std::unique_ptr<Session> session_;
+};
+
+// A specialized fuzz implementation for ops that take
+// a single string. Caller must still define the op
+// to plumb by overriding BuildGraph or using
+// a plumbing macro.
+class FuzzStringInputOp : public FuzzSession {
+ void FuzzImpl(const uint8_t* data, size_t size) final {
+ Tensor input_tensor(tensorflow::DT_STRING, TensorShape({}));
+ input_tensor.scalar<string>()() =
+ string(reinterpret_cast<const char*>(data), size);
+ // TODO(b/32704451): Don't just ignore the ::tensorflow::Status object!
+ RunOneInput(input_tensor).IgnoreError();
+ }
+};
+
+} // end namespace fuzzing
+} // end namespace tensorflow
+
+#endif // LEARNING_BRAIN_KERNELS_FUZZING_FUZZ_SESSION_H_
diff --git a/tensorflow/core/kernels/fuzzing/identity_fuzz.cc b/tensorflow/core/kernels/fuzzing/identity_fuzz.cc
new file mode 100644
index 0000000000..ac3a12aa39
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/identity_fuzz.cc
@@ -0,0 +1,45 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzIdentity : public FuzzSession {
+ SINGLE_INPUT_OP_BUILDER(DT_INT8, Identity);
+
+ void FuzzImpl(const uint8_t* data, size_t size) final {
+ Tensor input_tensor(tensorflow::DT_INT8,
+ TensorShape({static_cast<int64>(size)}));
+ auto flat_tensor = input_tensor.flat<int8>();
+ for (size_t i = 0; i < size; i++) {
+ flat_tensor(i) = data[i];
+ }
+
+ Status s = RunOneInput(input_tensor);
+ // Note: For many ops, we don't care about this success -- but when
+ // testing to make sure the harness actually works, it's useful.
+ if (!s.ok()) {
+ LOG(ERROR) << "Execution failed: " << s.error_message();
+ }
+ }
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzIdentity);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/parse_tensor_op_fuzz.cc b/tensorflow/core/kernels/fuzzing/parse_tensor_op_fuzz.cc
new file mode 100644
index 0000000000..978fcd1028
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/parse_tensor_op_fuzz.cc
@@ -0,0 +1,45 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+// Fuzz inputs to the serialized Tensor decoder.
+
+class FuzzParseTensor : public FuzzSession {
+ void BuildGraph(const Scope& scope) final {
+ using namespace ::tensorflow::ops; // NOLINT(build/namespaces)
+ // The serialized proto.
+ auto input = Placeholder(scope.WithOpName("input1"), DT_STRING);
+
+ std::ignore = ParseTensor(scope.WithOpName("output"), input, DT_FLOAT);
+ }
+
+ void FuzzImpl(const uint8_t* data, size_t size) final {
+ Tensor input_tensor(tensorflow::DT_STRING, TensorShape({}));
+ input_tensor.scalar<string>()() =
+ string(reinterpret_cast<const char*>(data), size);
+ // TODO(b/32704451): Don't just ignore the ::tensorflow::Status object!
+ RunOneInput(input_tensor).IgnoreError();
+ }
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzParseTensor);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/string_split_fuzz.cc b/tensorflow/core/kernels/fuzzing/string_split_fuzz.cc
new file mode 100644
index 0000000000..7d1aa1fbf3
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/string_split_fuzz.cc
@@ -0,0 +1,60 @@
+/* Copyright 2017 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzStringSplit : public FuzzSession {
+ void BuildGraph(const Scope& scope) override {
+ auto input =
+ tensorflow::ops::Placeholder(scope.WithOpName("input1"), DT_STRING);
+ auto delimeter =
+ tensorflow::ops::Placeholder(scope.WithOpName("input2"), DT_STRING);
+ std::ignore = tensorflow::ops::StringSplit(scope.WithOpName("output"),
+ input, delimeter);
+ }
+
+ void FuzzImpl(const uint8_t* data, size_t size) final {
+ Tensor input_tensor(tensorflow::DT_STRING, TensorShape({}));
+ Tensor delimeter_tensor(tensorflow::DT_STRING, TensorShape({}));
+
+ if (size > 0) {
+ // The spec for split is that the delimeter should be 0 or 1 characters.
+ // Naturally, fuzz it with something larger. (This omits the possibility
+ // of handing it a > int32_max size string, which should be tested for in
+ // an
+ // explicit test).
+ size_t delim_len = static_cast<size_t>(data[0]);
+ if (delim_len > size) {
+ delim_len = size - 1;
+ }
+ delimeter_tensor.scalar<string>()() =
+ string(reinterpret_cast<const char*>(data), delim_len);
+ input_tensor.scalar<string>()() = string(
+ reinterpret_cast<const char*>(data + delim_len), size - delim_len);
+ }
+
+ // TODO(b/32704451): Don't just ignore the ::tensorflow::Status object!
+ RunTwoInputs(input_tensor, delimeter_tensor).IgnoreError();
+ }
+};
+
+STANDARD_TF_FUZZ_FUNCTION(FuzzStringSplit);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/string_to_number_fuzz.cc b/tensorflow/core/kernels/fuzzing/string_to_number_fuzz.cc
new file mode 100644
index 0000000000..94255d215e
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/string_to_number_fuzz.cc
@@ -0,0 +1,32 @@
+/* Copyright 2016 Google Inc. 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 "tensorflow/core/kernels/fuzzing/fuzz_session.h"
+#include "tensorflow/cc/ops/standard_ops.h"
+
+namespace tensorflow {
+namespace fuzzing {
+
+class FuzzStringToNumber : public FuzzStringInputOp {
+ SINGLE_INPUT_OP_BUILDER(DT_STRING, StringToNumber);
+};
+
+// TODO(dga): Generalize this to hit both the float and int
+// variants of StringToNumber - requires an update to the
+// plumbing code to specify the output dtype.
+STANDARD_TF_FUZZ_FUNCTION(FuzzStringToNumber);
+
+} // end namespace fuzzing
+} // end namespace tensorflow
diff --git a/tensorflow/core/kernels/fuzzing/tf_ops_fuzz_target_lib.bzl b/tensorflow/core/kernels/fuzzing/tf_ops_fuzz_target_lib.bzl
new file mode 100644
index 0000000000..f752b59568
--- /dev/null
+++ b/tensorflow/core/kernels/fuzzing/tf_ops_fuzz_target_lib.bzl
@@ -0,0 +1,13 @@
+"""Fuzzing template for TensorFlow ops."""
+
+def tf_ops_fuzz_target_lib(name):
+ native.cc_library(
+ name = name + "_fuzz_lib",
+ srcs = [name + "_fuzz.cc"],
+ deps = [
+ "//tensorflow/core/kernels/fuzzing:fuzz_session",
+ "//tensorflow/cc:cc_ops",
+ ],
+ tags = ["no_windows"],
+ alwayslink = 1,
+ )