chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
# 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("@xla//third_party/rules_python/python:py_library.bzl", "py_library")
load(
"//tensorflow/security/fuzzing:tf_fuzzing.bzl",
"tf_py_fuzz_target",
)
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
licenses = ["notice"],
)
py_library(
name = "python_fuzzing",
srcs = ["python_fuzzing.py"],
strict_deps = True,
deps = ["//tensorflow:tensorflow_py_no_contrib"],
)
tf_py_fuzz_target(
name = "abs_fuzz",
srcs = ["abs_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "acos_fuzz",
srcs = ["acos_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "acosh_fuzz",
srcs = ["acosh_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "add_fuzz",
srcs = ["add_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "constant_fuzz",
srcs = ["constant_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
)
tf_py_fuzz_target(
name = "raggedCountSparseOutput_fuzz",
srcs = ["raggedCountSparseOutput_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "dataFormatVecPermute_fuzz",
srcs = ["dataFormatVecPermute_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "sparseCountSparseOutput_fuzz",
srcs = ["sparseCountSparseOutput_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
tf_py_fuzz_target(
name = "tf2migration_fuzz",
srcs = ["tf2migration_fuzz.py"],
tags = [
"noautofuzz",
"notap",
], # Run in OSS only.
deps = [":python_fuzzing"],
)
+41
View File
@@ -0,0 +1,41 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.Abs."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
def TestOneInput(data):
"""Test randomized fuzzing input for tf.raw_ops.Abs."""
fh = FuzzingHelper(data)
# tf.raw_ops.Abs takes tf.bfloat16, tf.float32, tf.float64, tf.int8, tf.int16,
# tf.int32, tf.int64, tf.half but get_random_numeric_tensor only generates
# tf.float16, tf.float32, tf.float64, tf.int32, tf.int64
input_tensor = fh.get_random_numeric_tensor()
_ = tf.raw_ops.Abs(x=input_tensor)
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
+41
View File
@@ -0,0 +1,41 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.Acos."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
def TestOneInput(data):
"""Test randomized fuzzing input for tf.raw_ops.Acos."""
fh = FuzzingHelper(data)
# tf.raw_ops.Acos takes tf.bfloat16, tf.half, tf.float32, tf.float64, tf.int8,
# tf.int16, tf.int32, tf.int64, tf.complex64, tf.complex128, but
# get_random_numeric_tensor only generates tf.float16, tf.float32, tf.float64,
# tf.int32, tf.int64
input_tensor = fh.get_random_numeric_tensor()
_ = tf.raw_ops.Acos(x=input_tensor)
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
+41
View File
@@ -0,0 +1,41 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.Acosh."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
def TestOneInput(data):
"""Test randomized fuzzing input for tf.raw_ops.Acosh."""
fh = FuzzingHelper(data)
# tf.raw_ops.Acos takes tf.bfloat16, tf.half, tf.float32, tf.float64,
# tf.complex64, tf.complex128, but get_random_numeric_tensor only generates
# tf.float16, tf.float32, tf.float64, tf.int32, tf.int64
dtype = fh.get_tf_dtype(allowed_set=[tf.float16, tf.float32, tf.float64])
input_tensor = fh.get_random_numeric_tensor(dtype=dtype)
_ = tf.raw_ops.Acosh(x=input_tensor)
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
+46
View File
@@ -0,0 +1,46 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.Add."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
def TestOneInput(data):
"""Test numeric randomized fuzzing input for tf.raw_ops.Add."""
fh = FuzzingHelper(data)
# tf.raw_ops.Add also takes tf.bfloat16, tf.half, tf.float32, tf.float64,
# tf.uint8, tf.int8, tf.int16, tf.int32, tf.int64, tf.complex64,
# tf.complex128, but get_random_numeric_tensor only generates tf.float16,
# tf.float32, tf.float64, tf.int32, tf.int64
input_tensor_x = fh.get_random_numeric_tensor()
input_tensor_y = fh.get_random_numeric_tensor()
try:
_ = tf.raw_ops.Add(x=input_tensor_x, y=input_tensor_y)
except (tf.errors.InvalidArgumentError, tf.errors.UnimplementedError):
pass
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
@@ -0,0 +1,68 @@
/* 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 <cassert>
#include <string>
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/attr_value.pb.h"
#include "tensorflow/core/framework/attr_value_util.h"
// This is a fuzzer for AreAttrValuesEqual.
namespace {
// A few helpers to construct AttrValue protos.
template <typename T>
tensorflow::AttrValue createAttrValue(T value) {
tensorflow::AttrValue ret;
SetAttrValue(value, &ret);
return ret;
}
// A helper to do the comparison asserts.
template <typename T>
void compareValues(T value, T value_2) {
const tensorflow::AttrValue proto = createAttrValue(value);
const tensorflow::AttrValue proto_same = createAttrValue(value);
const tensorflow::AttrValue proto2 = createAttrValue(value_2);
// Assert that AreAttrValuesEqual is true with or without allow false
// negatives.
assert(tensorflow::AreAttrValuesEqual(proto, proto_same,
/*allow_false_negatives=*/false));
assert(tensorflow::AreAttrValuesEqual(proto, proto_same,
/*allow_false_negatives=*/true));
// Assert that AreAttrValuesEqual are same with or without allow false
// negatives.
assert(tensorflow::AreAttrValuesEqual(proto, proto2,
/*allow_false_negatives=*/false) ==
tensorflow::AreAttrValuesEqual(proto, proto2,
/*allow_false_negatives=*/true));
}
void FuzzTest(const int i, const int j, const float u, const float v,
const std::string s1, const std::string s2) {
compareValues(i, j);
compareValues(u, v);
compareValues(s1, s2);
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(fuzztest::InRange(1, 100), fuzztest::InRange(1, 1000),
fuzztest::InRange(1.0f, 1000.0f),
fuzztest::InRange(1.0f, 1000.0f),
fuzztest::Arbitrary<std::string>(),
fuzztest::Arbitrary<std::string>());
} // namespace
+255
View File
@@ -0,0 +1,255 @@
# Fuzzing TensorFlow.
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load(
"//tensorflow/core/platform:build_config.bzl",
"tf_proto_library",
)
load(
"//tensorflow/security/fuzzing:tf_fuzzing.bzl",
"tf_cc_fuzz_test",
)
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
licenses = ["notice"],
)
tf_cc_fuzz_test(
name = "status_fuzz",
srcs = ["status_fuzz.cc"],
tags = ["no_oss"],
deps = [
":fuzz_domains",
"//tensorflow/core/platform:status",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "arg_def_case_fuzz",
srcs = ["arg_def_case_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:str_util",
"//tensorflow/core/platform:stringpiece",
"@com_google_absl//absl/strings",
],
)
tf_cc_fuzz_test(
name = "base64_fuzz",
srcs = ["base64_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:base64",
"//tensorflow/core/platform:status",
"//tensorflow/core/platform:stringpiece",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "bfloat16_fuzz",
srcs = ["bfloat16_fuzz.cc"],
tags = ["no_oss"], # b/175698644
deps = [
"//tensorflow/core:portable_gif_internal",
"//tensorflow/core/framework:bfloat16",
],
)
tf_cc_fuzz_test(
name = "checkpoint_reader_fuzz",
srcs = ["checkpoint_reader_fuzz.cc"],
data = glob(["checkpoint_reader_testdata/*"]),
tags = ["no_oss"],
deps = [
":checkpoint_reader_fuzz_input_proto_cc",
"//tensorflow/c:checkpoint_reader",
"//tensorflow/c:tf_status",
"//tensorflow/c:tf_status_helper",
"//tensorflow/core:framework",
"//tensorflow/core:lib",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/platform:resource_loader",
"//tensorflow/core/util:saved_tensor_slice_proto_cc",
"@xla//xla/tsl/platform:status",
],
)
tf_proto_library(
name = "checkpoint_reader_fuzz_input_proto",
srcs = ["checkpoint_reader_fuzz_input.proto"],
make_default_target_header_only = True,
protodeps = [
"//tensorflow/core/util:saved_tensor_slice_proto",
],
)
tf_cc_fuzz_test(
name = "cleanpath_fuzz",
srcs = ["cleanpath_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:path",
"@com_google_absl//absl/strings",
],
)
tf_cc_fuzz_test(
name = "consume_leading_digits_fuzz",
srcs = ["consume_leading_digits_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core:portable_gif_internal",
"//tensorflow/core/platform:str_util",
"//tensorflow/core/platform:stringpiece",
"@com_google_absl//absl/strings:string_view",
],
)
tf_cc_fuzz_test(
name = "joinpath_fuzz",
srcs = ["joinpath_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:path",
"@com_google_absl//absl/strings",
],
)
tf_cc_fuzz_test(
name = "status_group_fuzz",
srcs = ["status_group_fuzz.cc"],
tags = ["no_oss"],
deps = [
":fuzz_domains",
"//tensorflow/core/platform:status",
"@com_google_absl//absl/status",
],
)
cc_library(
name = "fuzz_domains",
testonly = True,
hdrs = ["fuzz_domains.h"],
deps = [
"//tensorflow/core/platform:status",
"@com_google_fuzztest//fuzztest",
],
)
tf_cc_fuzz_test(
name = "stringprintf_fuzz",
srcs = ["stringprintf_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:stringprintf",
"@com_google_absl//absl/strings:str_format",
],
)
tf_cc_fuzz_test(
name = "string_replace_fuzz",
srcs = ["string_replace_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:str_util",
"//tensorflow/core/platform:stringpiece",
"@com_google_absl//absl/strings:string_view",
],
)
tf_cc_fuzz_test(
name = "tstring_fuzz",
srcs = ["tstring_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:tstring",
],
)
tf_cc_fuzz_test(
name = "AreAttrValuesEqual_fuzz",
srcs = ["AreAttrValuesEqual_fuzz.cc"],
tags = ["no_oss"], # b/175698644
deps = [
"//tensorflow/core/framework:attr_value_proto_cc",
"//tensorflow/core/framework:attr_value_util",
],
)
tf_cc_fuzz_test(
name = "ParseAttrValue_fuzz",
srcs = ["ParseAttrValue_fuzz.cc"],
tags = ["no_oss"], # b/175698644
deps = [
"//tensorflow/core/framework:attr_value_proto_cc",
"//tensorflow/core/framework:attr_value_util",
"//tensorflow/core/platform:stringpiece",
],
)
tf_cc_fuzz_test(
name = "parseURI_fuzz",
srcs = ["parseURI_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/core/platform:path",
"//tensorflow/core/platform:stringpiece",
"@com_google_absl//absl/strings",
],
)
cc_library(
name = "fuzz_session",
testonly = 1,
hdrs = ["fuzz_session.h"],
tags = ["no_oss"],
visibility = [
"//tensorflow/cc/framework/fuzzing:__subpackages__",
"//tensorflow/security/fuzzing:__subpackages__",
],
deps = [
"//tensorflow/cc:scope",
"//tensorflow/core:core_cpu_base",
"//tensorflow/core:session_options",
"//tensorflow/core/common_runtime:direct_session_internal",
"//tensorflow/core/framework:tensor",
"//tensorflow/core/platform:status",
"@com_google_fuzztest//fuzztest",
],
)
tf_cc_fuzz_test(
name = "end_to_end_fuzz",
srcs = ["end_to_end_fuzz.cc"],
deps = [
"//tensorflow/cc/saved_model:constants",
"//tensorflow/cc/saved_model:loader",
"//tensorflow/cc/saved_model:tag_constants",
"//tensorflow/core:core_cpu",
"//tensorflow/core:lib",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:tensorflow",
"//tensorflow/core/framework:tensor",
"//tensorflow/core/platform:status",
"//tensorflow/security/fuzzing/cc/core/framework:datatype_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_shape_domains",
"@com_google_absl//absl/status",
"@xla//xla/tsl/platform:env",
"@xla//xla/tsl/platform:status",
],
)
tf_cc_fuzz_test(
name = "text_literal_reader_fuzz",
srcs = ["text_literal_reader_fuzz.cc"],
deps = [
"@xla//xla:text_literal_reader",
"@xla//xla/hlo/parser:hlo_parser",
"@xla//xla/tsl/platform:env",
],
)
@@ -0,0 +1,50 @@
/* Copyright 2021 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 <string>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/attr_value.pb.h"
#include "tensorflow/core/framework/attr_value_util.h"
#include "tensorflow/core/platform/stringpiece.h"
// This is a fuzzer for tensorflow::ParseAttrValue.
namespace {
using tensorflow::StringPiece;
void FuzzTest(std::string_view type, std::string_view text_string) {
// ParseAttrValue converts text protos into the types of attr_value.proto,
// which are string, int, float, bool, DataType, TensorShapeProto,
// TensorProto, NameAttrList, and list of any previously mentioned data type.
// This fuzzer tests the ParseAttrValue's ability to not crash.
tensorflow::AttrValue out;
tensorflow::ParseAttrValue(type, text_string, &out);
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(
fuzztest::ElementOf<std::string>(
{"string", "int", "float", "bool", "type", "shape", "tensor",
"list(string)", "list(int)", "list(float)", "list(bool)",
"list(type)", "list(shape)", "list(tensor)", "list(list(string))",
"list(list(int))", "list(list(float))", "list(list(bool))",
"list(list(type))", "list(list(shape))", "list(list(tensor))",
// Invalid values
"invalid", "123"}),
fuzztest::Arbitrary<std::string>());
} // namespace
@@ -0,0 +1,40 @@
/* 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 <cassert>
#include <string>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "absl/strings/ascii.h"
#include "tensorflow/core/platform/str_util.h"
#include "tensorflow/core/platform/stringpiece.h"
// This is a fuzzer for tensorflow::str_util::ArgDefCase
namespace {
void FuzzTest(std::string_view data) {
std::string ns = tensorflow::str_util::ArgDefCase(data);
for (const auto &c : ns) {
const bool is_letter = absl::ascii_isalpha(c);
const bool is_digit = absl::ascii_isdigit(c);
if (!is_letter && !is_digit) {
assert(c == '_');
}
}
}
FUZZ_TEST(CC_FUZZING, FuzzTest);
} // namespace
@@ -0,0 +1,42 @@
/* 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 <cassert>
#include <string>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "absl/status/status.h"
#include "tensorflow/core/platform/base64.h"
#include "tensorflow/core/platform/status.h"
#include "tensorflow/core/platform/stringpiece.h"
// This is a fuzzer for tensorflow::Base64Encode and tensorflow::Base64Decode.
namespace {
void FuzzTest(std::string_view input) {
std::string encoded_string;
std::string decoded_string;
absl::Status s;
s = tensorflow::Base64Encode(input, &encoded_string);
assert(s.ok());
s = tensorflow::Base64Decode(encoded_string, &decoded_string);
assert(s.ok());
assert(input == decoded_string);
}
FUZZ_TEST(CC_FUZZING, FuzzTest);
} // namespace
@@ -0,0 +1,49 @@
/* 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 <cassert>
#include <cmath>
#include <cstdint>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/bfloat16.h"
#include "tensorflow/core/platform/bfloat16.h"
// This is a fuzzer for tensorflow::FloatToBFloat16 and
// tensorflow::BFloat16ToFloat.
namespace {
void FuzzTest(const std::vector<float>& float_originals) {
const int32_t size = float_originals.size();
std::vector<tensorflow::bfloat16> bfloats(size);
std::vector<float> floats_converted(size);
tensorflow::FloatToBFloat16(float_originals.data(), bfloats.data(), size);
tensorflow::BFloat16ToFloat(bfloats.data(), floats_converted.data(), size);
for (int i = 0; i < float_originals.size(); ++i) {
// The relative error should be less than 1/(2^7) since bfloat16
// has 7 bits mantissa.
// Copied this logic from bfloat16_test.cc
assert(fabs(floats_converted[i] - float_originals[i]) / float_originals[i] <
1.0 / 128);
}
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(fuzztest::ContainerOf<std::vector<float>>(
fuzztest::InRange(1.0f, 1000.0f)));
} // namespace
@@ -0,0 +1,140 @@
/* Copyright 2021 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 <map>
#include <memory>
#include <string>
#include "fuzztest/fuzztest.h"
#include "tensorflow/c/checkpoint_reader.h"
#include "tensorflow/c/tf_status.h"
#include "tensorflow/c/tf_status_helper.h"
#include "xla/tsl/platform/status.h"
#include "tensorflow/core/framework/resource_handle.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/tensor_slice.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/core/framework/variant.h"
#include "tensorflow/core/lib/gtl/cleanup.h"
#include "tensorflow/core/lib/io/table_builder.h"
#include "tensorflow/core/lib/io/table_options.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/file_system.h"
#include "tensorflow/core/platform/resource_loader.h"
#include "tensorflow/core/platform/stringpiece.h"
#include "tensorflow/core/platform/tstring.h"
#include "tensorflow/core/util/saved_tensor_slice.pb.h"
#include "tensorflow/core/util/saved_tensor_slice_util.h"
#include "tensorflow/security/fuzzing/cc/checkpoint_reader_fuzz_input.pb.h"
// This is a fuzzer for tensorflow::checkpoint::CheckpointReader. LevelDB
// reading and proto parsing are already fuzz-tested, so there's no need to test
// them here.
namespace {
using ::tensorflow::checkpoint::EncodeTensorNameSlice;
using ::tensorflow::checkpoint::kSavedTensorSlicesKey;
void CreateCheckpoint(
const std::string& filename,
const tensorflow::testing::CheckpointReaderFuzzInput& contents) {
std::unique_ptr<tensorflow::WritableFile> writable_file;
TF_CHECK_OK(
tensorflow::Env::Default()->NewWritableFile(filename, &writable_file));
tensorflow::table::Options options;
options.compression = tensorflow::table::kNoCompression;
tensorflow::table::TableBuilder builder(options, writable_file.get());
// Entries must be added in sorted order.
{
tensorflow::SavedTensorSlices sts;
*sts.mutable_meta() = contents.meta();
builder.Add(kSavedTensorSlicesKey, sts.SerializeAsString());
}
std::map<std::string, const tensorflow::SavedSlice*> entries;
for (const tensorflow::SavedSlice& saved_slice : contents.data()) {
// The encoded tensor slice name is not included in the fuzz input since
// it's difficult for the fuzzer to find the proper encoding, resulting in
// lots of fruitless inputs with mismatched keys. Note that TensorSlice will
// not currently crash with unverified data so long as it's only used by
// EncodeTensorNameSlice.
tensorflow::TensorSlice slice(saved_slice.slice());
entries.insert(
{EncodeTensorNameSlice(saved_slice.name(), slice), &saved_slice});
}
tensorflow::SavedTensorSlices sts;
for (const auto& entry : entries) {
*sts.mutable_data() = *entry.second;
builder.Add(entry.first, sts.SerializeAsString());
}
TF_CHECK_OK(builder.Finish());
TF_CHECK_OK(writable_file->Close());
}
int GetDataTypeSize(tensorflow::DataType data_type) {
// tensorflow::DataTypeSize doesn't support several types.
switch (data_type) {
case tensorflow::DT_STRING:
return sizeof(tensorflow::tstring);
case tensorflow::DT_VARIANT:
return sizeof(tensorflow::Variant);
case tensorflow::DT_RESOURCE:
return sizeof(tensorflow::ResourceHandle);
default:
return tensorflow::DataTypeSize(data_type);
}
}
static void FuzzTest(
const tensorflow::testing::CheckpointReaderFuzzInput& input) {
// Using a ram file avoids disk I/O, speeding up the fuzzer.
const std::string filename = "ram:///checkpoint";
CreateCheckpoint(filename, input);
// RamFileSystem::NewWritableFile doesn't remove existing files, so
// expliciently ensure the checkpoint is deleted after each test.
auto checkpoint_cleanup = tensorflow::gtl::MakeCleanup([&filename] {
TF_CHECK_OK(tensorflow::Env::Default()->DeleteFile(filename));
});
tensorflow::TF_StatusPtr status(TF_NewStatus());
tensorflow::checkpoint::CheckpointReader reader(filename, status.get());
if (TF_GetCode(status.get()) != TF_OK) return;
// Load each tensor in the input.
std::unique_ptr<tensorflow::Tensor> tensor;
for (const auto& entry : input.meta().tensor()) {
// Fuzz tests have a memory limit of 2 GB; skipping tensors over 1 GB is
// sufficient to avoid OOMs.
static constexpr double kMaxTensorSize = 1e9;
auto data_type = reader.GetVariableToDataTypeMap().find(entry.name());
auto shape = reader.GetVariableToShapeMap().find(entry.name());
if (data_type != reader.GetVariableToDataTypeMap().end() &&
shape != reader.GetVariableToShapeMap().end() &&
static_cast<double>(GetDataTypeSize(data_type->second)) *
shape->second.num_elements() <
kMaxTensorSize) {
reader.GetTensor(entry.name(), &tensor, status.get());
}
}
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithSeeds(fuzztest::ReadFilesFromDirectory<
tensorflow::testing::CheckpointReaderFuzzInput>(
tensorflow::GetDataDependencyFilepath(
"tensorflow/security/fuzzing/cc/checkpoint_reader_testdata")));
} // namespace
@@ -0,0 +1,26 @@
/* Copyright 2021 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.
==============================================================================*/
syntax = "proto3";
package tensorflow.testing;
import "tensorflow/core/util/saved_tensor_slice.proto";
// Input for the CheckpointReader fuzz test.
message CheckpointReaderFuzzInput {
SavedTensorSliceMeta meta = 1;
repeated SavedSlice data = 2;
}
@@ -0,0 +1,34 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
name: "test"
shape {
dim {
}
}
type: DT_BFLOAT16
slice {
extent {
start: 7954877770267194415
length: 7954877770267194415
}
}
}
versions {
bad_consumers: 0
}
}
@@ -0,0 +1,31 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
shape {
dim {
size: 144115188075855872
}
unknown_rank: true
}
type: DT_DOUBLE
slice {
extent {
start: 35184372088832
}
}
}
}
@@ -0,0 +1,41 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
name: "test"
shape {
dim {
size: 3
}
}
type: DT_STRING
slice {
extent {
}
}
}
versions {
producer: 1
}
}
data {
name: "test"
slice {
extent {}
}
data {
}
}
@@ -0,0 +1,27 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
# type must be set.
shape {
}
slice {
}
}
versions {
producer: 1
}
}
@@ -0,0 +1,28 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
shape {
dim {
size: -216172782113783808 # Dimensions must be positive.
}
}
type: DT_QUINT16
}
versions {
producer: 1
}
}
@@ -0,0 +1,45 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
shape {
dim {
size: 281474976645120
}
}
slice {
extent {
start: -576179277326778368
length: 973078528
}
}
}
tensor {
shape {
dim {
size: 281474976645120
}
}
slice {
extent {
length: 973078528
}
}
}
versions {
producer: 1
}
}
@@ -0,0 +1,39 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
name: "test"
shape {
# The number of elements in the tensor will not overflow if computed in
# forward order, but will overflow if computed in reverse order.
dim { size: 0 }
dim { size: 0x100000000 }
dim { size: 0x100000000 }
}
type: DT_DOUBLE
slice {
extent {}
extent {}
extent {}
}
}
versions { producer: 1 }
}
data {
name: "test"
slice { extent {} extent {} extent {} }
data {}
}
@@ -0,0 +1,23 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
name: "test"
type: DT_INT32_REF # Ref types are not allowed in checkpoints.
slice {
}
}
}
@@ -0,0 +1,41 @@
# Copyright 2021 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.
#===============================================================================
meta {
tensor {
name: "test"
shape {
dim {
size: 3
}
}
type: DT_STRING
slice {
extent {}
}
}
versions {
producer: 1
}
}
data {
name: "test"
slice {
extent {}
}
data {
string_val: ["foo", "bar", "foobar"]
}
}
@@ -0,0 +1,42 @@
/* 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 <cassert>
#include <regex> // NOLINT
#include <string>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "absl/strings/match.h"
#include "tensorflow/core/platform/path.h"
// This is a fuzzer for tensorflow::io::CleanPath.
namespace {
void FuzzTest(std::string_view input_path) {
std::string clean_path = tensorflow::io::CleanPath(input_path);
// Assert there are no '/./' no directory changes.
assert(!absl::StrContains(clean_path, "/./"));
// Assert there are no duplicate '/'.
assert(!absl::StrContains(clean_path, "//"));
// Assert there are no higher up directories after entering a directory.
std::regex higher_up_directory("[^.]{1}/[.]{2}");
assert(!std::regex_match(clean_path, higher_up_directory));
}
FUZZ_TEST(CC_FUZZING, FuzzTest);
} // namespace
@@ -0,0 +1,46 @@
/* 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 <cassert>
#include <cstdint>
#include <string>
#include "fuzztest/fuzztest.h"
#include "absl/strings/string_view.h"
#include "tensorflow/core/platform/str_util.h"
#include "tensorflow/core/platform/stringpiece.h"
#include "tensorflow/core/platform/types.h"
// This is a fuzzer for tensorflow::str_util::ConsumeLeadingDigits
namespace {
void FuzzTest(std::string data) {
absl::string_view sp(data);
uint64_t val;
const bool leading_digits =
tensorflow::str_util::ConsumeLeadingDigits(&sp, &val);
const char lead_char_consume_digits = *(sp.data());
if (leading_digits) {
if (lead_char_consume_digits >= '0') {
assert(lead_char_consume_digits > '9');
}
assert(val >= 0);
}
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(
fuzztest::Arbitrary<std::string>().WithMaxSize(25));
} // namespace
@@ -0,0 +1,48 @@
# Fuzztest TensorShape domains
load("@rules_cc//cc:cc_library.bzl", "cc_library")
# copybara:uncomment package(default_applicable_licenses = ["//tensorflow:license"])
cc_library(
name = "tensor_shape_domains",
testonly = 1,
srcs = ["tensor_shape_domains.cc"],
hdrs = ["tensor_shape_domains.h"],
visibility = ["//visibility:public"],
deps = [
"//tensorflow/core:framework",
"@com_google_absl//absl/status:statusor",
"@com_google_fuzztest//fuzztest",
"@xla//xla/tsl/platform:errors",
],
)
cc_library(
name = "tensor_domains",
testonly = 1,
srcs = ["tensor_domains.cc"],
hdrs = ["tensor_domains.h"],
visibility = ["//visibility:public"],
deps = [
":tensor_shape_domains",
"//tensorflow/core:framework",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/platform:tstring",
"@com_google_absl//absl/log",
"@com_google_fuzztest//fuzztest",
"@xla//xla/tsl/platform:errors",
],
)
cc_library(
name = "datatype_domains",
testonly = 1,
srcs = ["datatype_domains.cc"],
hdrs = ["datatype_domains.h"],
visibility = ["//visibility:public"],
deps = [
"//tensorflow/core/framework:types_proto_cc",
"@com_google_fuzztest//fuzztest",
],
)
@@ -0,0 +1,34 @@
/* Copyright 2023 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 "tensorflow/security/fuzzing/cc/core/framework/datatype_domains.h"
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/types.pb.h"
namespace tensorflow::fuzzing {
fuzztest::Domain<DataType> AnyValidDataType() {
return fuzztest::ElementOf({
DT_FLOAT, DT_DOUBLE, DT_INT32, DT_UINT8, DT_INT16, DT_INT8, DT_INT64,
DT_BOOL, DT_UINT16, DT_UINT32, DT_UINT64
// TODO(b/268338352): add unsupported types
// DT_STRING, DT_COMPLEX64, DT_QINT8, DT_QUINT8, DT_QINT32,
// DT_BFLOAT16, DT_QINT16, DT_COMPLEX128, DT_HALF, DT_RESOURCE,
// DT_VARIANT, DT_FLOAT8_E5M2, DT_FLOAT8_E4M3FN
});
}
} // namespace tensorflow::fuzzing
@@ -0,0 +1,29 @@
/* Copyright 2023 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.
==============================================================================*/
#ifndef TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_DATATYPE_DOMAINS_H_
#define TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_DATATYPE_DOMAINS_H_
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/types.pb.h"
namespace tensorflow::fuzzing {
/// Returns a fuzztest domain of valid DataTypes to construct a Tensor
fuzztest::Domain<DataType> AnyValidDataType();
} // namespace tensorflow::fuzzing
#endif // TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_DATATYPE_DOMAINS_H_
@@ -0,0 +1,146 @@
/* Copyright 2023 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 "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include <limits>
#include <string>
#include "fuzztest/fuzztest.h"
#include "absl/log/log.h"
#include "xla/tsl/platform/errors.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/core/platform/tstring.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_shape_domains.h"
namespace tensorflow::fuzzing {
namespace {
using ::fuzztest::Arbitrary;
using ::fuzztest::Domain;
using ::fuzztest::Filter;
using ::fuzztest::FlatMap;
using ::fuzztest::InRange;
using ::fuzztest::Map;
using ::fuzztest::VectorOf;
template <class T>
Domain<T> DomainRange(double min, double max) {
// Need to convert limits to T, and check that we are within bounds.
T min_t = std::numeric_limits<T>::lowest() / 2;
if (min > static_cast<double>(min_t)) min_t = static_cast<T>(min);
T max_t = std::numeric_limits<T>::max() / 2;
if (max < static_cast<double>(max_t)) max_t = static_cast<T>(max);
return InRange(min_t, max_t);
}
template <>
Domain<bool> DomainRange(double min, double max) {
return Arbitrary<bool>();
}
template <typename T>
auto StatusOrAnyTensor(const TensorShape& shape, Domain<T> content_domain) {
return Map(
[shape](const std::vector<T>& contents) -> absl::StatusOr<Tensor> {
Tensor tensor;
TF_RETURN_IF_ERROR(
Tensor::BuildTensor(DataTypeToEnum<T>::v(), shape, &tensor));
auto flat_tensor = tensor.flat<T>();
for (int i = 0; i < contents.size(); ++i) {
flat_tensor(i) = contents[i];
}
return tensor;
},
VectorOf(content_domain).WithSize(shape.num_elements()));
}
#define NUMERIC_TENSOR_HELPER(data_type) \
case data_type: \
return StatusOrAnyTensor( \
shape, DomainRange<EnumToDataType<data_type>::Type>(min, max));
Domain<absl::StatusOr<Tensor>> StatusOrAnyNumericTensor(
const TensorShape& shape, DataType data_type, double min, double max) {
switch (data_type) {
NUMERIC_TENSOR_HELPER(DT_FLOAT);
NUMERIC_TENSOR_HELPER(DT_DOUBLE);
NUMERIC_TENSOR_HELPER(DT_INT32);
NUMERIC_TENSOR_HELPER(DT_UINT8);
NUMERIC_TENSOR_HELPER(DT_INT16);
NUMERIC_TENSOR_HELPER(DT_INT8);
NUMERIC_TENSOR_HELPER(DT_INT64);
NUMERIC_TENSOR_HELPER(DT_UINT16);
NUMERIC_TENSOR_HELPER(DT_UINT32);
NUMERIC_TENSOR_HELPER(DT_UINT64);
NUMERIC_TENSOR_HELPER(DT_BOOL);
// TODO(b/268338352): Add unsupported types
// DT_BOOL, DT_STRING, DT_COMPLEX64, DT_QINT8, DT_QUINT8, DT_QINT32,
// DT_BFLOAT16, DT_QINT16, DT_COMPLEX128, DT_HALF, DT_RESOURCE, DT_VARIANT,
// DT_FLOAT8_E5M2, DT_FLOAT8_E4M3FN
default:
LOG(FATAL) << "Unsupported data type: " << data_type; // Crash OK
}
}
Domain<Tensor> FilterInvalid(Domain<absl::StatusOr<Tensor>> domain) {
return Map([](const absl::StatusOr<Tensor>& t) { return *t; },
Filter(
[](const absl::StatusOr<Tensor>& inner_t) {
return inner_t.status().ok();
},
domain));
}
} // namespace
Domain<Tensor> AnyValidNumericTensor(const TensorShape& shape,
DataType datatype, double min,
double max) {
return FilterInvalid(StatusOrAnyNumericTensor(shape, datatype, min, max));
}
Domain<Tensor> AnyValidNumericTensor(Domain<TensorShape> tensor_shape_domain,
Domain<DataType> datatype_domain,
double min, double max) {
return FlatMap(
[min, max](const TensorShape& shape, DataType datatype) {
return AnyValidNumericTensor(shape, datatype, min, max);
},
tensor_shape_domain, datatype_domain);
}
Domain<Tensor> AnySmallValidNumericTensor(DataType datatype) {
return fuzzing::AnyValidNumericTensor(fuzzing::AnyValidTensorShape(
/*max_rank=*/5,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/10),
fuzztest::Just(datatype),
/*min=*/-10,
/*max=*/10);
}
Domain<Tensor> AnyValidStringTensor(const TensorShape& tensor_shape,
Domain<std::string> string_domain) {
return FilterInvalid(StatusOrAnyTensor<tstring>(
tensor_shape,
Map([](const std::string& s) { return static_cast<tstring>(s); },
string_domain)));
}
} // namespace tensorflow::fuzzing
@@ -0,0 +1,55 @@
/* Copyright 2023 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.
==============================================================================*/
#ifndef TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_TENSOR_DOMAINS_H_
#define TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_TENSOR_DOMAINS_H_
#include <string>
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/tensor_shape.h"
#include "tensorflow/core/framework/types.pb.h"
namespace tensorflow::fuzzing {
inline constexpr double kDefaultMaxAbsoluteValue = 100.0;
/// Returns a fuzztest domain of tensors of the specified shape and datatype
fuzztest::Domain<Tensor> AnyValidNumericTensor(
const TensorShape& shape, DataType datatype,
double min = -kDefaultMaxAbsoluteValue,
double max = kDefaultMaxAbsoluteValue);
/// Returns a fuzztest domain of tensors with shape and datatype
/// that live in the given corresponding domains.
fuzztest::Domain<Tensor> AnyValidNumericTensor(
fuzztest::Domain<TensorShape> tensor_shape_domain,
fuzztest::Domain<DataType> datatype_domain,
double min = -kDefaultMaxAbsoluteValue,
double max = kDefaultMaxAbsoluteValue);
// Returns a fuzztest domain of tensor of max rank 5, with dimensions sizes
// between 0 and 10 and values between -10 and 10.
fuzztest::Domain<Tensor> AnySmallValidNumericTensor(
DataType datatype = DT_INT32);
fuzztest::Domain<Tensor> AnyValidStringTensor(
const TensorShape& shape, fuzztest::Domain<std::string> string_domain =
fuzztest::Arbitrary<std::string>());
} // namespace tensorflow::fuzzing
#endif // TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_TENSOR_DOMAINS_H_
@@ -0,0 +1,59 @@
/* Copyright 2023 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 <cstddef>
#include <cstdint>
#include <limits>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/status/statusor.h"
#include "xla/tsl/platform/errors.h"
#include "tensorflow/core/framework/tensor_shape.h"
namespace tensorflow::fuzzing {
namespace {
using ::fuzztest::Domain;
using ::fuzztest::Filter;
using ::fuzztest::InRange;
using ::fuzztest::Map;
using ::fuzztest::VectorOf;
Domain<absl::StatusOr<TensorShape>> AnyStatusOrTensorShape(
size_t max_rank, int64_t dim_lower_bound, int64_t dim_upper_bound) {
return Map(
[](std::vector<int64_t> v) -> absl::StatusOr<TensorShape> {
TensorShape out;
TF_RETURN_IF_ERROR(TensorShape::BuildTensorShape(v, &out));
return out;
},
VectorOf(InRange(dim_lower_bound, dim_upper_bound))
.WithMaxSize(max_rank));
}
} // namespace
Domain<TensorShape> AnyValidTensorShape(
size_t max_rank = std::numeric_limits<size_t>::max(),
int64_t dim_lower_bound = std::numeric_limits<int64_t>::min(),
int64_t dim_upper_bound = std::numeric_limits<int64_t>::max()) {
return Map([](absl::StatusOr<TensorShape> t) { return *t; },
Filter([](auto t_inner) { return t_inner.status().ok(); },
AnyStatusOrTensorShape(max_rank, dim_lower_bound,
dim_upper_bound)));
}
} // namespace tensorflow::fuzzing
@@ -0,0 +1,38 @@
/* Copyright 2023 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.
==============================================================================*/
#ifndef TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_TENSOR_SHAPE_DOMAINS_H_
#define TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_TENSOR_SHAPE_DOMAINS_H_
#include <limits>
#include <tuple>
#include <utility>
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/framework/tensor_shape.h"
namespace tensorflow::fuzzing {
/// Returns a fuzztest domain with valid TensorShapes.
/// The domain can be customized by setting the maximum rank,
/// and the minimum and maximum size of all dimensions.
fuzztest::Domain<TensorShape> AnyValidTensorShape(
size_t max_rank = std::numeric_limits<int>::max(),
int64_t dim_lower_bound = std::numeric_limits<int64_t>::min(),
int64_t dim_upper_bound = std::numeric_limits<int64_t>::max());
} // namespace tensorflow::fuzzing
#endif // TENSORFLOW_SECURITY_FUZZING_CC_CORE_FRAMEWORK_TENSOR_SHAPE_DOMAINS_H_
@@ -0,0 +1,28 @@
# Fuzzing TensorFlow/core/function with GFT
load(
"//tensorflow/security/fuzzing:tf_fuzzing.bzl",
"tf_cc_fuzz_test",
)
# copybara:uncomment package(default_applicable_licenses = ["//tensorflow:license"])
tf_cc_fuzz_test(
name = "runtime_client_fuzz",
srcs = ["runtime_client_fuzz.cc"],
deps = [
"//tensorflow/c/eager:immediate_execution_context",
"//tensorflow/core:core_cpu",
"//tensorflow/core:framework",
"//tensorflow/core:framework_types_hdr",
"//tensorflow/core:portable_gif_internal",
"//tensorflow/core/common_runtime/eager:context",
"//tensorflow/core/framework:function_proto_cc",
"//tensorflow/core/framework:tensor",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/function/runtime_client:runtime_client_cc",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/strings",
"@xla//xla/tsl/platform:status",
],
)
@@ -0,0 +1,120 @@
// 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.
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/str_cat.h"
#include "tensorflow/c/eager/immediate_execution_context.h"
#include "xla/tsl/platform/status.h"
#include "tensorflow/core/common_runtime/device_mgr.h"
#include "tensorflow/core/common_runtime/eager/context.h"
#include "tensorflow/core/framework/device_factory.h"
#include "tensorflow/core/framework/function.h"
#include "tensorflow/core/framework/function.pb.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/core/function/runtime_client/runtime_client.h"
#include "tensorflow/core/platform/types.h"
#include "tensorflow/core/public/session_options.h"
namespace tensorflow {
namespace fuzzing {
FunctionDef EmptyFunctionDefGenerator(int number_of_input_arguments,
int number_of_output_arguments) {
std::vector<std::string> in_def_vec;
in_def_vec.reserve(number_of_input_arguments);
for (int c = 0; c < number_of_input_arguments; ++c) {
in_def_vec.push_back(absl::StrCat("in", c, ":float"));
}
std::vector<FunctionDefHelper::Node> body_nodes;
if (number_of_output_arguments > number_of_input_arguments) {
Tensor const_value(DataTypeToEnum<float>::value, {});
const_value.scalar<float>()() = 0;
body_nodes.push_back(
{{"zero"}, "Const", {}, {{"value", const_value}, {"dtype", DT_FLOAT}}});
}
std::vector<std::string> out_def_vec;
out_def_vec.reserve(number_of_output_arguments);
std::vector<std::pair<std::string, std::string>> ret_def;
ret_def.reserve(number_of_output_arguments);
for (int c = 0; c < number_of_output_arguments; ++c) {
std::string output_id = "out" + std::to_string(c);
out_def_vec.push_back(output_id + ":float");
if (c < number_of_input_arguments) {
ret_def.emplace_back(output_id, "in" + std::to_string(c));
} else {
ret_def.emplace_back(output_id, "zero:output");
}
}
return FunctionDefHelper::Create("TestFunction", in_def_vec, out_def_vec, {},
body_nodes, ret_def);
}
class FuzzRuntimeClient : public fuzztest::IterationRunnerFixture {
public:
void FuzzTestIterationRunner(
absl::AnyInvocable<void() &&> run_iteration) override {
ctx_ = InitLocalEagerContextPtr();
rt_ = std::make_unique<core::function::Runtime>(*ctx_);
std::move(run_iteration)();
}
void CreateFunctionInnerFuzz(int in_args, int out_args) {
TF_CHECK_OK(
rt_->CreateFunction(EmptyFunctionDefGenerator(in_args, out_args)));
}
void CreateFunctionOuterFuzz(FunctionDef def) {
// Ignore errors because the fuzzer may generate invalid FunctionDef protos.
// Returning a non-OK status for invalid input is expected and acceptable;
// we are only looking for unexpected crashes, hangs, or memory safety
// issues.
rt_->CreateFunction(def).IgnoreError();
}
private:
EagerContextPtr ctx_;
std::unique_ptr<core::function::Runtime> rt_;
EagerContextPtr InitLocalEagerContextPtr() {
SessionOptions opts;
std::vector<std::unique_ptr<Device>> devices;
TF_CHECK_OK(DeviceFactory::AddDevices(
opts, "/job:localhost/replica:0/task:0", &devices));
return EagerContextPtr(new EagerContext(
opts, ContextDevicePlacementPolicy::DEVICE_PLACEMENT_SILENT,
/*async=*/false,
/*device_mgr=*/new DynamicDeviceMgr(std::move(devices)),
/*device_mgr_owned=*/true,
/*rendezvous=*/nullptr,
/*cluster_flr=*/nullptr,
/*collective_executor_mgr=*/nullptr,
/*run_eager_op_as_function=*/true));
}
};
FUZZ_TEST_F(FuzzRuntimeClient, CreateFunctionInnerFuzz)
.WithDomains(fuzztest::InRange(0, 7), fuzztest::InRange(1, 7));
FUZZ_TEST_F(FuzzRuntimeClient, CreateFunctionOuterFuzz);
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,76 @@
/* Copyright 2023 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 <memory>
#include <string>
#include <utility>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/status/status.h"
#include "tensorflow/cc/saved_model/constants.h"
#include "tensorflow/cc/saved_model/loader.h"
#include "tensorflow/cc/saved_model/tag_constants.h"
#include "xla/tsl/platform/env.h"
#include "xla/tsl/platform/status.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/status.h"
#include "tensorflow/core/protobuf/config.pb.h"
#include "tensorflow/core/protobuf/saved_model.pb.h"
#include "tensorflow/core/public/session_options.h"
#include "tensorflow/security/fuzzing/cc/core/framework/datatype_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_shape_domains.h"
namespace tensorflow::fuzzing {
namespace {
// Fuzzer that loads an arbitrary model and performs inference using a fixed
// input.
void FuzzEndToEnd(
const SavedModel& model,
const std::vector<std::pair<std::string, tensorflow::Tensor>>& input_dict) {
SavedModelBundle bundle;
const SessionOptions session_options;
const RunOptions run_options;
const std::string export_dir = "ram://";
TF_CHECK_OK(tsl::WriteBinaryProto(tensorflow::Env::Default(),
export_dir + kSavedModelFilenamePb, model));
absl::Status status = LoadSavedModel(session_options, run_options, export_dir,
{kSavedModelTagServe}, &bundle);
if (!status.ok()) {
return;
}
// Create output placeholder tensors for results
std::vector<tensorflow::Tensor> outputs;
std::vector<std::string> output_names = {"fuzz_out:0", "fuzz_out:1"};
absl::Status status_run =
bundle.session->Run(input_dict, output_names, {}, &outputs);
}
FUZZ_TEST(End2EndFuzz, FuzzEndToEnd)
.WithDomains(
fuzztest::Arbitrary<SavedModel>(),
fuzztest::VectorOf(fuzztest::PairOf(fuzztest::Arbitrary<std::string>(),
fuzzing::AnyValidNumericTensor(
fuzzing::AnyValidTensorShape(
/*max_rank=*/3,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/20),
fuzzing::AnyValidDataType())))
.WithMaxSize(6));
} // namespace
} // namespace tensorflow::fuzzing
@@ -0,0 +1,35 @@
/* Copyright 2022 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.
==============================================================================*/
#ifndef TENSORFLOW_SECURITY_FUZZING_CC_FUZZ_DOMAINS_H_
#define TENSORFLOW_SECURITY_FUZZING_CC_FUZZ_DOMAINS_H_
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/platform/status.h"
namespace helper {
inline fuzztest::Domain<absl::StatusCode> AnyErrorCode() {
// We cannot build a `Status` with error_code of 0 and a message, so force
// error code to be non-zero.
return fuzztest::Map(
[](uint32_t code) { return static_cast<absl::StatusCode>(code); },
fuzztest::Filter([](uint32_t code) { return code != 0; },
fuzztest::Arbitrary<uint32_t>()));
}
} // namespace helper
#endif // TENSORFLOW_SECURITY_FUZZING_CC_FUZZ_DOMAINS_H_
@@ -0,0 +1,174 @@
/* 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 TENSORFLOW_SECURITY_FUZZING_CC_FUZZ_SESSION_H_
#define TENSORFLOW_SECURITY_FUZZING_CC_FUZZ_SESSION_H_
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "tensorflow/cc/framework/scope.h"
#include "tensorflow/core/framework/tensor.h"
#include "tensorflow/core/framework/types.h"
#include "tensorflow/core/platform/status.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/public/session_options.h"
// Standard builder for hooking one placeholder to one op.
#define SINGLE_INPUT_OP_FUZZER(dtype, opName) \
class Fuzz##opName : public FuzzSession<Tensor> { \
void BuildGraph(const Scope& scope) override { \
auto op_node = \
tensorflow::ops::Placeholder(scope.WithOpName("input"), dtype); \
tensorflow::ops::opName(scope.WithOpName("output"), op_node); \
} \
void FuzzImpl(const Tensor& input_tensor) final { \
RunInputs({{"input", input_tensor}}); \
} \
}
#define BINARY_INPUT_OP_FUZZER(dtype1, dtype2, opName) \
class Fuzz##opName : public FuzzSession<Tensor, Tensor> { \
void BuildGraph(const Scope& scope) override { \
auto op_node1 = \
tensorflow::ops::Placeholder(scope.WithOpName("input1"), dtype1); \
auto op_node2 = \
tensorflow::ops::Placeholder(scope.WithOpName("input2"), dtype2); \
tensorflow::ops::opName(scope.WithOpName("output"), op_node1, op_node2); \
} \
void FuzzImpl(const Tensor& input_tensor1, \
const Tensor& input_tensor2) final { \
RunInputs({{"input1", input_tensor1}, {"input2", input_tensor2}}); \
} \
}
namespace tensorflow {
namespace fuzzing {
// Used by GFT to map a known domain (vector<T>) to an unknown
// domain (Tensor of datatype). T and datatype should match/be compatible.
template <typename T = uint8_t>
inline auto AnyTensor() {
return fuzztest::Map(
[](auto v) {
Tensor tensor(DataTypeToEnum<T>::v(),
TensorShape({static_cast<int64_t>(v.size())}));
auto flat_tensor = tensor.flat<T>();
for (int i = 0; i < v.size(); ++i) {
flat_tensor(i) = v[i];
}
return tensor;
},
fuzztest::Arbitrary<std::vector<T>>());
}
// 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:
// SINGLE_INPUT_OP_FUZZER(DT_UINT8, Identity);
// FUZZ_TEST_F(FuzzIdentity, Fuzz).WithDomains(AnyTensor());
template <typename... T>
class FuzzSession {
public:
FuzzSession() : initialized_(false) {}
virtual ~FuzzSession() = default;
// 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) = 0;
// 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 T&...) = 0;
// Initializes the FuzzSession. Not safe for multithreading.
// Separate init function because the call to virtual BuildGraphDef
// can't be put into the constructor.
absl::Status InitIfNeeded() {
if (initialized_) {
return absl::OkStatus();
}
initialized_ = true;
Scope root = Scope::DisabledShapeInferenceScope().ExitOnError();
SessionOptions options;
session_ = std::unique_ptr<Session>(NewSession(options));
BuildGraph(root);
GraphDef graph_def;
TF_CHECK_OK(root.ToGraphDef(&graph_def));
absl::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: " // Crash OK
<< status.message();
}
return status;
}
// Runs the TF session by pulling on the "output" node, attaching
// the supplied input_tensor to the input node(s), and discarding
// any returned output.
// Note: We are ignoring Status from Run here since fuzzers don't need to
// check it (as that will slow them down and printing/logging is useless).
void RunInputs(const std::vector<std::pair<std::string, Tensor>>& inputs) {
RunInputsWithStatus(inputs).IgnoreError();
}
// Same as RunInputs but don't ignore status
absl::Status RunInputsWithStatus(
const std::vector<std::pair<std::string, Tensor>>& inputs) {
return session_->Run(inputs, {}, {"output"}, nullptr);
}
// Dispatches to FuzzImpl; small amount of sugar to keep the code
// of the per-op fuzzers tiny.
void Fuzz(const T&... args) {
absl::Status status = InitIfNeeded();
TF_CHECK_OK(status) << "Fuzzer graph initialization failed: "
<< status.message();
// No return value from fuzzing: Success is defined as "did not
// crash". The actual application results are irrelevant.
FuzzImpl(args...);
}
private:
bool initialized_;
std::unique_ptr<Session> session_;
};
} // end namespace fuzzing
} // end namespace tensorflow
#endif // TENSORFLOW_SECURITY_FUZZING_CC_FUZZ_SESSION_H_
@@ -0,0 +1,36 @@
/* 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 <cassert>
#include <string>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "absl/strings/match.h"
#include "tensorflow/core/platform/path.h"
// This is a fuzzer for tensorflow::io::JoinPath.
namespace {
void FuzzTest(std::string_view first, std::string_view second) {
std::string path = tensorflow::io::JoinPath(first, second);
// Assert path contains strings
assert(absl::StrContains(path, first));
assert(absl::StrContains(path, second));
}
FUZZ_TEST(CC_FUZZING, FuzzTest);
} // namespace
+142
View File
@@ -0,0 +1,142 @@
# Fuzzing TensorFlow ops with GFT
# Most ops have a similar set of dependencies and a similar fuzzing
# infrastructure. Hence, we gather everything in one single place.
# Note that these fuzzers cover a large part of TF, they are not granular.
load(
"//tensorflow/security/fuzzing:tf_fuzzing.bzl",
"tf_cc_fuzz_test",
)
# copybara:uncomment package(default_applicable_licenses = ["//tensorflow:license"])
# A trivial fuzzer with no pre-specified corpus.
tf_cc_fuzz_test(
name = "identity_fuzz",
srcs = ["identity_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_shape_domains",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "concat_fuzz",
srcs = ["concat_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_shape_domains",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "add_fuzz",
srcs = ["add_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"//tensorflow/security/fuzzing/cc/core/framework:datatype_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_shape_domains",
],
)
tf_cc_fuzz_test(
name = "matmul_fuzz",
srcs = ["matmul_fuzz.cc"],
tags = [
"no_oss",
"noasan", # b/283972985
],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/core/kernels:matmul_op",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
],
)
tf_cc_fuzz_test(
name = "bincount_fuzz",
srcs = ["bincount_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/core/kernels:bincount_op",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_shape_domains",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "string_to_number_fuzz",
srcs = ["string_to_number_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/core/kernels:string_to_number_op",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "string_ops_fuzz",
srcs = ["string_ops_fuzz.cc"],
tags = ["no_oss"],
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/core/kernels:string",
"//tensorflow/core/kernels:string_split_op",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
],
)
tf_cc_fuzz_test(
name = "general_ops_fuzz",
srcs = ["general_ops_fuzz.cc"],
shard_count = 5,
deps = [
"//tensorflow/cc:cc_ops",
"//tensorflow/core/framework:tensor",
"//tensorflow/core/framework:types_proto_cc",
"//tensorflow/core/kernels:array",
"//tensorflow/core/kernels:decode_wav_op",
"//tensorflow/core/kernels/image",
"//tensorflow/core/kernels/image:decode_image_op",
"//tensorflow/core/ops:audio_ops_op_lib",
"//tensorflow/security/fuzzing/cc:fuzz_session",
"//tensorflow/security/fuzzing/cc/core/framework:tensor_domains",
],
)
@@ -0,0 +1,37 @@
// 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.
#include "fuzztest/fuzztest.h"
#include "tensorflow/cc/ops/math_ops.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/core/framework/datatype_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_shape_domains.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
// Creates FuzzIdentity class that wraps a single operation node session.
BINARY_INPUT_OP_FUZZER(DT_UINT8, DT_UINT8, Add);
// Setup up fuzzing test.
FUZZ_TEST_F(FuzzAdd, Fuzz)
.WithDomains(AnyValidNumericTensor(AnyValidTensorShape(3, 0, 5),
AnyValidDataType()),
AnyValidNumericTensor(AnyValidTensorShape(3, 0, 5),
AnyValidDataType()));
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,70 @@
// 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.
#include <cstdint>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_shape_domains.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
// Creates FuzzBincount class that wraps a single operation node session.
class FuzzBincount : public FuzzSession<Tensor, int32_t, Tensor> {
void BuildGraph(const Scope& scope) override {
auto arr = tensorflow::ops::Placeholder(scope.WithOpName("arr"), DT_INT32);
auto size =
tensorflow::ops::Placeholder(scope.WithOpName("size"), DT_INT32);
auto weights =
tensorflow::ops::Placeholder(scope.WithOpName("weights"), DT_INT32);
tensorflow::ops::Bincount(scope.WithOpName("output"), arr, size, weights);
}
void FuzzImpl(const Tensor& arr, const int32_t& nbins,
const Tensor& weights) final {
Tensor size(DT_INT32, {});
size.flat<int32_t>()(0) = nbins;
absl::Status s = RunInputsWithStatus(
{{"arr", arr}, {"size", size}, {"weights", weights}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
// Setup up fuzzing test.
// TODO(unda, b/275737422): Make the values in arr be within [0, size) with high
// chance
FUZZ_TEST_F(FuzzBincount, Fuzz)
.WithDomains(fuzzing::AnyValidNumericTensor(fuzzing::AnyValidTensorShape(
/*max_rank=*/5,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/10),
fuzztest::Just(DT_INT32)),
fuzztest::InRange<int32_t>(0, 10),
fuzzing::AnyValidNumericTensor(fuzzing::AnyValidTensorShape(
/*max_rank=*/5,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/10),
fuzztest::Just(DT_INT32)));
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,72 @@
// 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.
#include <cstdint>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_shape_domains.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
// Creates FuzzConcat class that wraps a single operation node session.
class FuzzConcat : public FuzzSession<Tensor, Tensor, int32_t> {
void BuildGraph(const Scope& scope) override {
auto value1 =
tensorflow::ops::Placeholder(scope.WithOpName("value1"), DT_INT32);
Input value1_input(value1);
auto value2 =
tensorflow::ops::Placeholder(scope.WithOpName("value2"), DT_INT32);
Input value2_input(value2);
InputList values_input_list({value1_input, value2_input});
auto axis =
tensorflow::ops::Placeholder(scope.WithOpName("axis"), DT_INT32);
tensorflow::ops::Concat(scope.WithOpName("output"), values_input_list,
axis);
}
void FuzzImpl(const Tensor& value1, const Tensor& value2,
const int32_t& axis) final {
Tensor axis_tensor(DT_INT32, {});
axis_tensor.scalar<int32_t>()() = axis;
absl::Status s = RunInputsWithStatus(
{{"value1", value1}, {"value2", value2}, {"axis", axis_tensor}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
// Setup up fuzzing test.
FUZZ_TEST_F(FuzzConcat, Fuzz)
.WithDomains(fuzzing::AnyValidNumericTensor(fuzzing::AnyValidTensorShape(
/*max_rank=*/5,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/10),
fuzztest::Just(DT_INT32)),
fuzzing::AnyValidNumericTensor(fuzzing::AnyValidTensorShape(
/*max_rank=*/5,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/10),
fuzztest::Just(DT_INT32)),
fuzztest::InRange<int32_t>(0, 6));
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,100 @@
// Copyright 2023 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.
#include "fuzztest/fuzztest.h"
#include "tensorflow/cc/ops/array_ops.h"
#include "tensorflow/cc/ops/audio_ops.h"
#include "tensorflow/cc/ops/image_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow::fuzzing {
// Image op fuzzers
// DecodePng
SINGLE_INPUT_OP_FUZZER(DT_STRING, DecodePng);
class FuzzDecodePngValidInput : public FuzzDecodePng {};
FUZZ_TEST_F(FuzzDecodePngValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")));
class FuzzDecodePngArbitraryInput : public FuzzDecodePng {};
FUZZ_TEST_F(FuzzDecodePngArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}));
// DecodeJpeg
SINGLE_INPUT_OP_FUZZER(DT_STRING, DecodeJpeg);
class FuzzDecodeJpegValidInput : public FuzzDecodeJpeg {};
FUZZ_TEST_F(FuzzDecodeJpegValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")));
class FuzzDecodeJpegArbitraryInput : public FuzzDecodeJpeg {};
FUZZ_TEST_F(FuzzDecodeJpegArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}));
// DecodeGif
SINGLE_INPUT_OP_FUZZER(DT_STRING, DecodeGif);
class FuzzDecodeGifValidInput : public FuzzDecodeGif {};
FUZZ_TEST_F(FuzzDecodeGifValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")));
class FuzzDecodeGifArbitraryInput : public FuzzDecodeGif {};
FUZZ_TEST_F(FuzzDecodeGifArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}));
// DecodeImage
SINGLE_INPUT_OP_FUZZER(DT_STRING, DecodeImage);
class FuzzDecodeImageValidInput : public FuzzDecodeImage {};
FUZZ_TEST_F(FuzzDecodeImageValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")));
class FuzzDecodeImageArbitraryInput : public FuzzDecodeImage {};
FUZZ_TEST_F(FuzzDecodeImageArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}));
// DecodeBmp
SINGLE_INPUT_OP_FUZZER(DT_STRING, DecodeBmp);
class FuzzDecodeBmpValidInput : public FuzzDecodeBmp {};
FUZZ_TEST_F(FuzzDecodeBmpValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")));
class FuzzDecodeBmpArbitraryInput : public FuzzDecodeBmp {};
FUZZ_TEST_F(FuzzDecodeBmpArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}));
// DecodeAndCropJpeg
BINARY_INPUT_OP_FUZZER(DT_STRING, DT_INT32, DecodeAndCropJpeg);
class FuzzDecodeAndCropJpegValidInput : public FuzzDecodeAndCropJpeg {};
FUZZ_TEST_F(FuzzDecodeAndCropJpegValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")),
fuzzing::AnyValidNumericTensor({}, DT_INT32, 0, 4096));
class FuzzDecodeAndCropJpegArbitraryInput : public FuzzDecodeAndCropJpeg {};
FUZZ_TEST_F(FuzzDecodeAndCropJpegArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}),
fuzzing::AnyValidNumericTensor({}, DT_INT32, 0, 4096));
// Audio op fuzzers
// DecodeWav
SINGLE_INPUT_OP_FUZZER(DT_STRING, DecodeWav);
class FuzzDecodeWavValidInput : public FuzzDecodeWav {};
FUZZ_TEST_F(FuzzDecodeWavValidInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({},
fuzztest::InRegexp("[-.0-9]+")));
class FuzzDecodeWavArbitraryInput : public FuzzDecodeWav {};
FUZZ_TEST_F(FuzzDecodeWavArbitraryInput, Fuzz)
.WithDomains(fuzzing::AnyValidStringTensor({}));
} // end namespace tensorflow::fuzzing
@@ -0,0 +1,53 @@
// 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.
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_shape_domains.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
// Creates FuzzIdentity class that wraps a single operation node session.
class FuzzIdentity : public FuzzSession<Tensor> {
void BuildGraph(const Scope& scope) override {
auto op_node =
tensorflow::ops::Placeholder(scope.WithOpName("input"), DT_INT32);
tensorflow::ops::Identity(scope.WithOpName("output"), op_node);
}
void FuzzImpl(const Tensor& input_tensor) final {
absl::Status s = RunInputsWithStatus({{"input", input_tensor}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
// Setup up fuzzing test.
FUZZ_TEST_F(FuzzIdentity, Fuzz)
.WithDomains(fuzzing::AnyValidNumericTensor(fuzzing::AnyValidTensorShape(
/*max_rank=*/5,
/*dim_lower_bound=*/0,
/*dim_upper_bound=*/10),
fuzztest::Just(DT_INT32)));
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,33 @@
// 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.
#include "fuzztest/fuzztest.h"
#include "tensorflow/cc/ops/math_ops.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/core/framework/tensor_domains.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
// Creates FuzzIdentity class that wraps a single operation node session.
BINARY_INPUT_OP_FUZZER(DT_INT32, DT_INT32, MatMul);
// Setup up fuzzing test.
FUZZ_TEST_F(FuzzMatMul, Fuzz)
.WithDomains(fuzzing::AnySmallValidNumericTensor(),
fuzzing::AnySmallValidNumericTensor());
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,119 @@
// Copyright 2023 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.
#include <string>
#include "fuzztest/fuzztest.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
class FuzzStringOpsStringSplit : public FuzzSession<std::string, std::string> {
void BuildGraph(const Scope& scope) override {
auto op_node =
tensorflow::ops::Placeholder(scope.WithOpName("input"), DT_STRING);
auto op_node2 =
tensorflow::ops::Placeholder(scope.WithOpName("delimiter"), DT_STRING);
tensorflow::ops::StringSplit(scope.WithOpName("output"), op_node, op_node2);
}
void FuzzImpl(const std::string& input_string,
const std::string& separator_string) final {
Tensor input_tensor(tensorflow::DT_STRING, {2});
auto svec = input_tensor.flat<tstring>();
svec(0) = input_string.c_str();
svec(1) = input_string.c_str();
Tensor separator_tensor(tensorflow::DT_STRING, TensorShape({}));
separator_tensor.scalar<tensorflow::tstring>()() = separator_string;
absl::Status s = RunInputsWithStatus(
{{"input", input_tensor}, {"delimiter", separator_tensor}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
FUZZ_TEST_F(FuzzStringOpsStringSplit, Fuzz)
.WithDomains(fuzztest::OneOf(fuzztest::InRegexp("[-.0-9]+"),
fuzztest::Arbitrary<std::string>()),
fuzztest::OneOf(fuzztest::InRegexp("[-.0-9]+"),
fuzztest::Arbitrary<std::string>()));
class FuzzStringOpsStringSplitV2
: public FuzzSession<std::string, std::string> {
void BuildGraph(const Scope& scope) override {
auto op_node =
tensorflow::ops::Placeholder(scope.WithOpName("input"), DT_STRING);
auto op_node2 =
tensorflow::ops::Placeholder(scope.WithOpName("separator"), DT_STRING);
tensorflow::ops::StringSplitV2(scope.WithOpName("output"), op_node,
op_node2);
}
void FuzzImpl(const std::string& input_string,
const std::string& separator_string) final {
Tensor input_tensor(tensorflow::DT_STRING, {2});
auto svec = input_tensor.flat<tstring>();
svec(0) = input_string.c_str();
svec(1) = input_string.c_str();
Tensor separator_tensor(tensorflow::DT_STRING, TensorShape({}));
separator_tensor.scalar<tensorflow::tstring>()() = separator_string;
absl::Status s = RunInputsWithStatus(
{{"input", input_tensor}, {"separator", separator_tensor}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
FUZZ_TEST_F(FuzzStringOpsStringSplitV2, Fuzz)
.WithDomains(fuzztest::OneOf(fuzztest::InRegexp("[-.0-9]+"),
fuzztest::Arbitrary<std::string>()),
fuzztest::OneOf(fuzztest::InRegexp("[-.0-9]+"),
fuzztest::Arbitrary<std::string>()));
class FuzzStringOpsStringUpper : public FuzzSession<std::string> {
void BuildGraph(const Scope& scope) override {
auto op_node =
tensorflow::ops::Placeholder(scope.WithOpName("input"), DT_STRING);
tensorflow::ops::StringUpper(scope.WithOpName("output"), op_node);
}
void FuzzImpl(const std::string& input_string) final {
Tensor input_tensor(tensorflow::DT_STRING, TensorShape({}));
input_tensor.scalar<tensorflow::tstring>()() = input_string;
absl::Status s = RunInputsWithStatus({{"input", input_tensor}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
FUZZ_TEST_F(FuzzStringOpsStringUpper, Fuzz)
.WithDomains(fuzztest::OneOf(fuzztest::InRegexp("[-.0-9]+"),
fuzztest::Arbitrary<std::string>()));
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,49 @@
// 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.
#include <string>
#include "fuzztest/fuzztest.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/types.pb.h"
#include "tensorflow/security/fuzzing/cc/fuzz_session.h"
namespace tensorflow {
namespace fuzzing {
// Creates FuzzStringToNumber class that wraps a single operation node session.
class FuzzStringToNumber : public FuzzSession<std::string> {
void BuildGraph(const Scope& scope) override {
auto op_node =
tensorflow::ops::Placeholder(scope.WithOpName("input"), DT_STRING);
tensorflow::ops::StringToNumber(scope.WithOpName("output"), op_node);
}
void FuzzImpl(const std::string& input_string) final {
Tensor input_tensor(tensorflow::DT_STRING, TensorShape({}));
input_tensor.scalar<tensorflow::tstring>()() = input_string;
absl::Status s = RunInputsWithStatus({{"input", input_tensor}});
if (!s.ok()) {
LOG(ERROR) << "Execution failed: " << s.message();
}
}
};
// Setup up fuzzing test.
FUZZ_TEST_F(FuzzStringToNumber, Fuzz)
.WithDomains(fuzztest::OneOf(fuzztest::InRegexp("[-.0-9]+"),
fuzztest::Arbitrary<std::string>()));
} // end namespace fuzzing
} // end namespace tensorflow
@@ -0,0 +1,46 @@
/* 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 <cassert>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "tensorflow/core/platform/path.h"
#include "tensorflow/core/platform/stringpiece.h"
// This is a fuzzer for tensorflow::io::ParseURI.
namespace {
void FuzzTest(std::string_view uri) {
absl::string_view scheme, host, path;
tensorflow::io::ParseURI(uri, &scheme, &host, &path);
// If a path is invalid.
if (path == uri) {
assert(host.empty());
assert(scheme.empty());
} else {
assert(absl::StrContains(uri, host));
assert(absl::StrContains(uri, scheme));
assert(absl::StrContains(uri, path));
assert(absl::StrContains(uri, "://"));
}
}
FUZZ_TEST(CC_FUZZING, FuzzTest);
} // namespace
@@ -0,0 +1,48 @@
/* 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 <cassert>
#include <cstddef>
#include <string>
#include <string_view>
#include "fuzztest/fuzztest.h"
#include "absl/status/status.h"
#include "tensorflow/core/platform/status.h"
#include "tensorflow/security/fuzzing/cc/fuzz_domains.h"
// This is a fuzzer for `tensorflow::Status`. Since `Status` is used almost
// everywhere, we need to ensure that the common functionality is safe. We don't
// expect many crashes from this fuzzer since we only create a status and then
// look at the error message from it but this is a good test of the fuzzing
// infrastructure, with minimal dependencies (thus, it is a good test to weed
// out linker bloat and other linker issues).
namespace {
void FuzzTest(absl::StatusCode error_code, std::string_view error_message) {
absl::Status s = absl::Status(error_code, error_message);
const std::string actual_message = s.ToString();
const std::size_t pos = actual_message.rfind(error_message);
assert(pos != std::string::npos); // Suffix is error message
assert(pos > 0); // Prefix is error code
// In some build configurations `assert` is a no-op. This causes `pos` to be
// unused and then produces an error if also compiling with `-Werror`.
(void)pos;
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(helper::AnyErrorCode(), fuzztest::Arbitrary<std::string>());
} // namespace
@@ -0,0 +1,48 @@
/* 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 <string>
#include "fuzztest/fuzztest.h"
#include "absl/status/status.h"
#include "tensorflow/core/platform/status.h"
#include "tensorflow/security/fuzzing/cc/fuzz_domains.h"
// This is a fuzzer for `tensorflow::StatusGroup`. Since `Status` is used almost
// everywhere, we need to ensure that the common functionality is safe. We don't
// expect many crashes from this fuzzer
namespace {
void FuzzTest(absl::StatusCode error_code, bool is_derived) {
const std::string error_message = "ERROR";
tensorflow::StatusGroup sg;
absl::Status s = absl::Status(error_code, error_message);
if (is_derived) {
absl::Status derived_s = tensorflow::StatusGroup::MakeDerived(s);
sg.Update(derived_s);
} else {
sg.Update(s);
}
// Ignore warnings that these values are unused
sg.as_summary_status().IgnoreError();
sg.as_concatenated_status().IgnoreError();
sg.AttachLogMessages();
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(helper::AnyErrorCode(), fuzztest::Arbitrary<bool>());
} // namespace
@@ -0,0 +1,41 @@
/* 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 <string>
#include "fuzztest/fuzztest.h"
#include "absl/strings/string_view.h"
#include "tensorflow/core/platform/str_util.h"
#include "tensorflow/core/platform/stringpiece.h"
// This is a fuzzer for tensorflow::str_util::StringReplace
namespace {
void FuzzTest(bool all_flag, std::string s, std::string oldsub,
std::string newsub) {
absl::string_view sp(s);
absl::string_view oldsubp(oldsub);
absl::string_view newsubp(newsub);
std::string subbed =
tensorflow::str_util::StringReplace(sp, oldsubp, newsubp, all_flag);
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(/*all_flag=*/fuzztest::Arbitrary<bool>(),
/*s=*/fuzztest::Arbitrary<std::string>().WithSize(10),
/*oldsub=*/fuzztest::Arbitrary<std::string>().WithSize(5),
/*newsub=*/fuzztest::Arbitrary<std::string>());
} // namespace
@@ -0,0 +1,51 @@
/* 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 <cassert>
#include <string>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "absl/strings/str_format.h"
#include "tensorflow/core/platform/stringprintf.h"
// This is a fuzzer for tensorflow::strings::Printf
namespace {
void FuzzTest(const std::vector<std::string> ss) {
const std::string all = ss[0] + ss[1] + ss[2];
int n[4] = {-1, -1, -1, -1};
const std::string ret = tensorflow::strings::Printf(
"%n%s%n%s%n%s%n", absl::FormatCountCapture(&n[0]), ss[0].c_str(),
absl::FormatCountCapture(&n[1]), ss[1].c_str(),
absl::FormatCountCapture(&n[2]), ss[2].c_str(),
absl::FormatCountCapture(&n[3]));
int size_so_far = 0;
for (int i = 0; i < 3; i++) {
assert(n[i] >= 0);
assert(n[i] <= size_so_far);
size_so_far += ss[i].size();
}
assert(n[3] >= 0);
assert(n[3] <= size_so_far);
assert(ret.size() == n[3]);
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(fuzztest::Arbitrary<std::vector<std::string>>().WithSize(3));
} // namespace
@@ -0,0 +1,42 @@
/* Copyright 2017 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 <fuzzer/FuzzedDataProvider.h>
#include <string>
#include "fuzztest/fuzztest.h"
#include "xla/hlo/parser/hlo_parser.h"
#include "xla/text_literal_reader.h"
#include "xla/tsl/platform/env.h"
namespace xla {
namespace {
void FuzzFileRead(std::string data) {
std::string fname = "/tmp/ReadsR3File.txt";
if (!tsl::WriteStringToFile(tsl::Env::Default(), fname, data).ok()) {
return;
}
TextLiteralReader::ReadPath(fname).IgnoreError();
}
FUZZ_TEST(TextReaderFuzzer, FuzzFileRead);
void FuzzHLOParseUnverified(std::string data) {
xla::ParseAndReturnUnverifiedModule(data).IgnoreError();
}
FUZZ_TEST(TextReaderFuzzer, FuzzHLOParseUnverified);
} // namespace
} // namespace xla
@@ -0,0 +1,39 @@
/* 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 <cassert>
#include <string>
#include <vector>
#include "fuzztest/fuzztest.h"
#include "tensorflow/core/platform/tstring.h"
// This is a fuzzer for tensorflow::tstring
namespace {
void FuzzTest(const std::vector<std::string>& ss) {
tensorflow::tstring base = ss[0];
for (int i = 1; i < ss.size(); ++i) {
base.append(ss[i]);
assert(base.size() <= base.capacity());
}
}
FUZZ_TEST(CC_FUZZING, FuzzTest)
.WithDomains(
fuzztest::VectorOf(fuzztest::Arbitrary<std::string>().WithMaxSize(10))
.WithMinSize(1));
} // namespace
@@ -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.
# ==============================================================================
"""This is a Python API fuzzer for tf.constant."""
import atheris
with atheris.instrument_imports():
import sys
import tensorflow as tf
def TestOneInput(data):
tf.constant(data)
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
@@ -0,0 +1,52 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.DataFormatVecPermute."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
@atheris.instrument_func
def TestOneInput(input_bytes):
"""Test randomized integer fuzzing input for tf.raw_ops.DataFormatVecPermute."""
fh = FuzzingHelper(input_bytes)
dtype = fh.get_tf_dtype()
# Max shape can be 8 in length and randomized from 0-8 without running into
# a OOM error.
shape = fh.get_int_list(min_length=0, max_length=8, min_int=0, max_int=8)
seed = fh.get_int()
try:
x = tf.random.uniform(shape=shape, dtype=dtype, seed=seed)
src_format_digits = str(fh.get_int(min_int=0, max_int=999999999))
dest_format_digits = str(fh.get_int(min_int=0, max_int=999999999))
_ = tf.raw_ops.DataFormatVecPermute(
x,
src_format=src_format_digits,
dst_format=dest_format_digits,
name=fh.get_string())
except (tf.errors.InvalidArgumentError, ValueError, TypeError):
pass
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == '__main__':
main()
@@ -0,0 +1,48 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.ImmutableConst."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
_DEFAULT_FILENAME = '/tmp/test.txt'
@atheris.instrument_func
def TestOneInput(input_bytes):
"""Test randomized integer fuzzing input for tf.raw_ops.ImmutableConst."""
fh = FuzzingHelper(input_bytes)
dtype = fh.get_tf_dtype()
shape = fh.get_int_list()
try:
with open(_DEFAULT_FILENAME, 'w') as f:
f.write(fh.get_string())
_ = tf.raw_ops.ImmutableConst(
dtype=dtype, shape=shape, memory_region_name=_DEFAULT_FILENAME)
except (tf.errors.InvalidArgumentError, tf.errors.InternalError,
UnicodeEncodeError, UnicodeDecodeError):
pass
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == '__main__':
main()
+12
View File
@@ -0,0 +1,12 @@
load("@xla//third_party/rules_python/python:py_library.bzl", "py_library")
# copybara:uncomment package(default_applicable_licenses = ["//tensorflow:license"])
# A library of python types used to annotate ops
py_library(
name = "annotation_types",
srcs = ["annotation_types.py"],
strict_deps = True,
visibility = ["//tensorflow/python/framework:__pkg__"],
deps = ["//tensorflow/python/framework:dtypes"],
)
@@ -0,0 +1,66 @@
# Copyright 2023 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.
# ==============================================================================
"""Library of types used for type annotation."""
from tensorflow.python.framework import dtypes as _dtypes
class DTypeAnnotation:
pass
def _create_dtype_wrapper(name, underlying_dtype: _dtypes.DType):
return type(name, (DTypeAnnotation,), {"underlying_dtype": underlying_dtype})
BFloat16 = _create_dtype_wrapper("BFloat16", _dtypes.bfloat16)
Bool = _create_dtype_wrapper("Bool", _dtypes.bool)
Complex128 = _create_dtype_wrapper("Complex128", _dtypes.complex128)
Complex64 = _create_dtype_wrapper("Complex64", _dtypes.complex64)
Float8e4m3fn = _create_dtype_wrapper("Float8e4m3fn", _dtypes.float8_e4m3fn)
Float8e5m2 = _create_dtype_wrapper("Float8e5m2", _dtypes.float8_e5m2)
Float8e4m3fnuz = _create_dtype_wrapper(
"Float8e4m3fnuz", _dtypes.float8_e4m3fnuz
)
Float8e4m3b11fnuz = _create_dtype_wrapper(
"Float8e4m3b11fnuz", _dtypes.float8_e4m3b11fnuz
)
Float8e5m2fnuz = _create_dtype_wrapper(
"Float8e5m2fnuz", _dtypes.float8_e5m2fnuz
)
Float4e2m1fn = _create_dtype_wrapper("Float4e2m1fn", _dtypes.float4_e2m1fn)
Float16 = _create_dtype_wrapper("Float16", _dtypes.float16)
Float32 = _create_dtype_wrapper("Float32", _dtypes.float32)
Float64 = _create_dtype_wrapper("Float64", _dtypes.float64)
Half = _create_dtype_wrapper("Half", _dtypes.float16)
Int2 = _create_dtype_wrapper("Int2", _dtypes.int2)
Int4 = _create_dtype_wrapper("Int4", _dtypes.int4)
Int8 = _create_dtype_wrapper("Int8", _dtypes.int8)
Int16 = _create_dtype_wrapper("Int16", _dtypes.int16)
Int32 = _create_dtype_wrapper("Int32", _dtypes.int32)
Int64 = _create_dtype_wrapper("Int64", _dtypes.int64)
UInt2 = _create_dtype_wrapper("UInt2", _dtypes.uint2)
UInt4 = _create_dtype_wrapper("UInt4", _dtypes.uint4)
UInt8 = _create_dtype_wrapper("UInt8", _dtypes.uint8)
UInt16 = _create_dtype_wrapper("UInt16", _dtypes.uint16)
UInt32 = _create_dtype_wrapper("UInt32", _dtypes.uint32)
UInt64 = _create_dtype_wrapper("UInt64", _dtypes.uint64)
QInt8 = _create_dtype_wrapper("QInt8", _dtypes.qint8)
QInt16 = _create_dtype_wrapper("QInt16", _dtypes.qint16)
QInt32 = _create_dtype_wrapper("QInt32", _dtypes.qint32)
QUInt16 = _create_dtype_wrapper("QUInt16", _dtypes.quint16)
QUInt8 = _create_dtype_wrapper("QUInt8", _dtypes.quint8)
Resource = _create_dtype_wrapper("Resource", _dtypes.resource)
String = _create_dtype_wrapper("String", _dtypes.string)
Variant = _create_dtype_wrapper("Variant", _dtypes.variant)
@@ -0,0 +1,216 @@
# Copyright 2021 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.
# ==============================================================================
"""Helper class for TF Python fuzzing."""
import atheris
import tensorflow as tf
_MIN_INT = -10000
_MAX_INT = 10000
_MIN_FLOAT = -10000.0
_MAX_FLOAT = 10000.0
_MIN_LENGTH = 0
_MAX_LENGTH = 10000
# Max shape can be 8 in length and randomized from 0-8 without running into an
# OOM error.
_MIN_SIZE = 0
_MAX_SIZE = 8
_TF_DTYPES = [
tf.half, tf.float16, tf.float32, tf.float64, tf.bfloat16, tf.complex64,
tf.complex128, tf.int8, tf.uint8, tf.uint16, tf.uint32, tf.uint64, tf.int16,
tf.int32, tf.int64, tf.bool, tf.string, tf.qint8, tf.quint8, tf.qint16,
tf.quint16, tf.qint32, tf.resource, tf.variant
]
# All types supported by tf.random.uniform
_TF_RANDOM_DTYPES = [tf.float16, tf.float32, tf.float64, tf.int32, tf.int64]
class FuzzingHelper(object):
"""FuzzingHelper makes handling FuzzedDataProvider easier with TensorFlow Python fuzzing."""
def __init__(self, input_bytes):
"""FuzzingHelper initializer.
Args:
input_bytes: Input randomized bytes used to create a FuzzedDataProvider.
"""
self.fdp = atheris.FuzzedDataProvider(input_bytes)
def get_bool(self):
"""Consume a bool.
Returns:
Consumed a bool based on input bytes and constraints.
"""
return self.fdp.ConsumeBool()
def get_int(self, min_int=_MIN_INT, max_int=_MAX_INT):
"""Consume a signed integer with given constraints.
Args:
min_int: Minimum allowed integer.
max_int: Maximum allowed integer.
Returns:
Consumed integer based on input bytes and constraints.
"""
return self.fdp.ConsumeIntInRange(min_int, max_int)
def get_float(self, min_float=_MIN_FLOAT, max_float=_MAX_FLOAT):
"""Consume a float with given constraints.
Args:
min_float: Minimum allowed float.
max_float: Maximum allowed float.
Returns:
Consumed float based on input bytes and constraints.
"""
return self.fdp.ConsumeFloatInRange(min_float, max_float)
def get_int_list(self,
min_length=_MIN_LENGTH,
max_length=_MAX_LENGTH,
min_int=_MIN_INT,
max_int=_MAX_INT):
"""Consume a signed integer list with given constraints.
Args:
min_length: The minimum length of the list.
max_length: The maximum length of the list.
min_int: Minimum allowed integer.
max_int: Maximum allowed integer.
Returns:
Consumed integer list based on input bytes and constraints.
"""
length = self.get_int(min_length, max_length)
return self.fdp.ConsumeIntListInRange(length, min_int, max_int)
def get_float_list(self, min_length=_MIN_LENGTH, max_length=_MAX_LENGTH):
"""Consume a float list with given constraints.
Args:
min_length: The minimum length of the list.
max_length: The maximum length of the list.
Returns:
Consumed integer list based on input bytes and constraints.
"""
length = self.get_int(min_length, max_length)
return self.fdp.ConsumeFloatListInRange(length, _MIN_FLOAT, _MAX_FLOAT)
def get_int_or_float_list(self,
min_length=_MIN_LENGTH,
max_length=_MAX_LENGTH):
"""Consume a signed integer or float list with given constraints based on a consumed bool.
Args:
min_length: The minimum length of the list.
max_length: The maximum length of the list.
Returns:
Consumed integer or float list based on input bytes and constraints.
"""
if self.get_bool():
return self.get_int_list(min_length, max_length)
else:
return self.get_float_list(min_length, max_length)
def get_tf_dtype(self, allowed_set=None):
"""Return a random tensorflow dtype.
Args:
allowed_set: An allowlisted set of dtypes to choose from instead of all of
them.
Returns:
A random type from the list containing all TensorFlow types.
"""
if allowed_set:
index = self.get_int(0, len(allowed_set) - 1)
if allowed_set[index] not in _TF_DTYPES:
raise tf.errors.InvalidArgumentError(
None, None,
'Given dtype {} is not accepted.'.format(allowed_set[index]))
return allowed_set[index]
else:
index = self.get_int(0, len(_TF_DTYPES) - 1)
return _TF_DTYPES[index]
def get_string(self, byte_count=_MAX_INT):
"""Consume a string with given constraints based on a consumed bool.
Args:
byte_count: Byte count that defaults to _MAX_INT.
Returns:
Consumed string based on input bytes and constraints.
"""
return self.fdp.ConsumeString(byte_count)
def get_random_numeric_tensor(self,
dtype=None,
min_size=_MIN_SIZE,
max_size=_MAX_SIZE,
min_val=_MIN_INT,
max_val=_MAX_INT):
"""Return a tensor of random shape and values.
Generated tensors are capped at dimension sizes of 8, as 2^32 bytes of
requested memory crashes the fuzzer (see b/34190148).
Returns only type that tf.random.uniform can generate. If you need a
different type, consider using tf.cast.
Args:
dtype: Type of tensor, must of one of the following types: float16,
float32, float64, int32, or int64
min_size: Minimum size of returned tensor
max_size: Maximum size of returned tensor
min_val: Minimum value in returned tensor
max_val: Maximum value in returned tensor
Returns:
Tensor of random shape filled with uniformly random numeric values.
"""
# Max shape can be 8 in length and randomized from 0-8 without running into
# an OOM error.
if max_size > 8:
raise tf.errors.InvalidArgumentError(
None, None,
'Given size of {} will result in an OOM error'.format(max_size))
seed = self.get_int()
shape = self.get_int_list(
min_length=min_size,
max_length=max_size,
min_int=min_size,
max_int=max_size)
if dtype is None:
dtype = self.get_tf_dtype(allowed_set=_TF_RANDOM_DTYPES)
elif dtype not in _TF_RANDOM_DTYPES:
raise tf.errors.InvalidArgumentError(
None, None,
'Given dtype {} is not accepted in get_random_numeric_tensor'.format(
dtype))
return tf.random.uniform(
shape=shape, minval=min_val, maxval=max_val, dtype=dtype, seed=seed)
@@ -0,0 +1,44 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.RaggedCountSparseOutput."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
@atheris.instrument_func
def TestOneInput(input_bytes):
"""Test randomized integer/float fuzzing input for tf.raw_ops.RaggedCountSparseOutput."""
fh = FuzzingHelper(input_bytes)
splits = fh.get_int_list()
values = fh.get_int_or_float_list()
weights = fh.get_int_list()
try:
_, _, _, = tf.raw_ops.RaggedCountSparseOutput(
splits=splits, values=values, weights=weights, binary_output=False)
except tf.errors.InvalidArgumentError:
pass
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
@@ -0,0 +1,67 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for tf.raw_ops.SparseCountSparseOutput."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
@atheris.instrument_func
def TestOneInput(input_bytes):
"""Test randomized integer fuzzing input for tf.raw_ops.SparseCountSparseOutput."""
fh = FuzzingHelper(input_bytes)
shape1 = fh.get_int_list(min_length=0, max_length=8, min_int=0, max_int=8)
shape2 = fh.get_int_list(min_length=0, max_length=8, min_int=0, max_int=8)
shape3 = fh.get_int_list(min_length=0, max_length=8, min_int=0, max_int=8)
shape4 = fh.get_int_list(min_length=0, max_length=8, min_int=0, max_int=8)
seed = fh.get_int()
indices = tf.random.uniform(
shape=shape1, minval=0, maxval=1000, dtype=tf.int64, seed=seed)
values = tf.random.uniform(
shape=shape2, minval=0, maxval=1000, dtype=tf.int64, seed=seed)
dense_shape = tf.random.uniform(
shape=shape3, minval=0, maxval=1000, dtype=tf.int64, seed=seed)
weights = tf.random.uniform(
shape=shape4, minval=0, maxval=1000, dtype=tf.int64, seed=seed)
binary_output = fh.get_bool()
minlength = fh.get_int()
maxlength = fh.get_int()
name = fh.get_string()
try:
_, _, _, = tf.raw_ops.SparseCountSparseOutput(
indices=indices,
values=values,
dense_shape=dense_shape,
weights=weights,
binary_output=binary_output,
minlength=minlength,
maxlength=maxlength,
name=name)
except tf.errors.InvalidArgumentError:
pass
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
@@ -0,0 +1,84 @@
# Copyright 2021 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.
# ==============================================================================
"""This is a Python API fuzzer for v1 vs v2 API comparison."""
import atheris
with atheris.instrument_imports():
import sys
from python_fuzzing import FuzzingHelper
import tensorflow as tf
@atheris.instrument_func
def TestOneInput(input_bytes):
"""Test randomized integer fuzzing input for v1 vs v2 APIs."""
fh = FuzzingHelper(input_bytes)
# Comparing tf.math.angle with tf.compat.v1.angle.
input_supported_dtypes = [tf.float32, tf.float64]
random_dtype_index = fh.get_int(min_int=0, max_int=1)
input_dtype = input_supported_dtypes[random_dtype_index]
input_shape = fh.get_int_list(
min_length=0, max_length=6, min_int=0, max_int=10)
seed = fh.get_int()
input_tensor = tf.random.uniform(
shape=input_shape, dtype=input_dtype, seed=seed, maxval=10)
name = fh.get_string(5)
v2_output = tf.math.angle(input=input_tensor, name=name)
v1_output = tf.compat.v1.angle(input=input_tensor, name=name)
try:
tf.debugging.assert_equal(v1_output, v2_output)
tf.debugging.assert_equal(v1_output.shape, v2_output.shape)
except Exception as e: # pylint: disable=broad-except
print("Input tensor: {}".format(input_tensor))
print("Input dtype: {}".format(input_dtype))
print("v1_output: {}".format(v1_output))
print("v2_output: {}".format(v2_output))
raise e
# Comparing tf.debugging.assert_integer with tf.compat.v1.assert_integer.
x_supported_dtypes = [
tf.float16, tf.float32, tf.float64, tf.int32, tf.int64, tf.string
]
random_dtype_index = fh.get_int(min_int=0, max_int=5)
x_dtype = x_supported_dtypes[random_dtype_index]
x_shape = fh.get_int_list(min_length=0, max_length=6, min_int=0, max_int=10)
seed = fh.get_int()
try:
x = tf.random.uniform(shape=x_shape, dtype=x_dtype, seed=seed, maxval=10)
except ValueError:
x = tf.constant(["test_string"])
message = fh.get_string(128)
name = fh.get_string(128)
try:
v2_output = tf.debugging.assert_integer(x=x, message=message, name=name)
except Exception as e: # pylint: disable=broad-except
v2_output = e
try:
v1_output = tf.compat.v1.assert_integer(x=x, message=message, name=name)
except Exception as e: # pylint: disable=broad-except
v1_output = e
if v1_output and v2_output:
assert type(v2_output) == type(v1_output) # pylint: disable=unidiomatic-typecheck
assert v2_output.args == v1_output.args
def main():
atheris.Setup(sys.argv, TestOneInput, enable_python_coverage=True)
atheris.Fuzz()
if __name__ == "__main__":
main()
+117
View File
@@ -0,0 +1,117 @@
"""Definitions for rules to fuzz TensorFlow."""
load("@rules_cc//cc:cc_test.bzl", "cc_test")
load("@rules_python//python:py_test.bzl", "py_test")
# TensorFlow fuzzing can be done in open source too, as it is in oss-fuzz.com
# tf_cc_fuzz_test is a cc_test modified to include fuzzing support and dependencies for go/fuzztest.
def tf_cc_fuzz_test(
name,
# Bug reporting component (unused in oss)
componentid = None,
# Additional cc_test control
data = [],
deps = [],
tags = [],
**kwargs):
"""Specify how to build a TensorFlow fuzz target.
Args:
name: Mandatory name of the fuzzer target.
componentid: The buganizer component ID for filing bugs
found by this fuzz test. By default, we use TensorFlow Security
component.
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
# Fuzzers in open source must be run manually
tags = tags + ["manual"]
# Now, redirect to cc_test
cc_test(
name = name,
deps = deps + [
"@com_google_fuzztest//fuzztest",
"@com_google_fuzztest//fuzztest:fuzztest_gtest_main",
],
data = data,
tags = tags,
linkstatic = 1,
**kwargs
)
# tf_py_fuzz_target is a py_test modified to include fuzzing support.
def tf_py_fuzz_target(
name,
# Fuzzing specific arguments
fuzzing_dict = [],
corpus = [],
parsers = [],
# Reporting bugs arguments, not used in open source
componentid = None,
hotlists = [],
# Additional py_test control
python_version = None,
data = [],
deps = [],
tags = [],
# Remaining py_test arguments
**kwargs):
"""Specify how to build a TensorFlow Python 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.
python_version: Python version to run target with.
data: Additional data dependencies passed to the underlying py_test rule.
deps: An optional list of dependencies for the code you're fuzzing.
tags: Additional tags passed to the underlying py_test rule.
**kwargs: Collects all remaining arguments and passes them to the
underlying py_test rule generated by the macro.
"""
componentid = None
hotlists = None
python_version = python_version or "PY3"
# Fuzzers in open source must be run manually
tags = tags + ["manual"]
# Now, redirect to py_test
py_test(
name = name,
python_version = python_version,
deps = deps,
data = data,
tags = tags,
**kwargs
)