--- /dev/null
+From 604398efa294046646c0dfce03939cfb9d371b86 Mon Sep 17 00:00:00 2001
+From: Yong Tang <yong.tang.github@outlook.com>
+Date: Sat, 8 Aug 2020 00:47:35 +0000
+Subject: [PATCH 1/4] Fix segmentation fault in tf.image.crop_and_resize when
+ boxes is inf or nan
+
+This fix tries to address the issue raised in 42129 where segmentation fault
+happened in tf.image.crop_and_resize when boxes is inf or nan.
+
+This fix adds the check to make sure boxes is not inf or nan (isfinite)
+
+This fix fixes 42129.
+
+Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
+Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
+---
+ tensorflow/core/kernels/crop_and_resize_op.cc | 12 ++++++++++++
+ tensorflow/python/ops/image_ops_test.py | 11 +++++++++++
+ 2 files changed, 23 insertions(+)
+
+diff --git a/tensorflow/core/kernels/crop_and_resize_op.cc b/tensorflow/core/kernels/crop_and_resize_op.cc
+index 99d01b4..23944e6 100644
+--- a/tensorflow/core/kernels/crop_and_resize_op.cc
++++ b/tensorflow/core/kernels/crop_and_resize_op.cc
+@@ -65,6 +65,18 @@ static inline Status ParseAndCheckBoxSizes(const Tensor& boxes,
+ if (boxes.dim_size(1) != 4) {
+ return errors::InvalidArgument("boxes must have 4 columns");
+ }
++ for (int64 i = 0; i < *num_boxes; i++) {
++ for (int64 j = 0; j < 4; j++) {
++ if (!isfinite(boxes.tensor<float, 2>()(i, j))) {
++ return errors::InvalidArgument(
++ "boxes values must be finite, received boxes[", i, "]: ",
++ boxes.tensor<float, 2>()(i, 0), ", ",
++ boxes.tensor<float, 2>()(i, 1), ", ",
++ boxes.tensor<float, 2>()(i, 2), ", ",
++ boxes.tensor<float, 2>()(i, 3));
++ }
++ }
++ }
+ // The shape of 'box_index' is [num_boxes].
+ if (box_index.dims() != 1) {
+ return errors::InvalidArgument("box_index must be 1-D",
+diff --git a/tensorflow/python/ops/image_ops_test.py b/tensorflow/python/ops/image_ops_test.py
+index e724933..1d3d632 100644
+--- a/tensorflow/python/ops/image_ops_test.py
++++ b/tensorflow/python/ops/image_ops_test.py
+@@ -4393,6 +4393,17 @@ class DecodeImageTest(test_util.TensorFlowTestCase):
+ image0, image1 = self.evaluate([image0, image1])
+ self.assertAllEqual(image0, image1)
+
++ def testImageCropAndResize(self):
++ # Test case for GitHub issue 42129
++ message = "boxes values must be finite"
++ with self.assertRaisesRegex(
++ (errors.InvalidArgumentError, ValueError), message):
++ v = image_ops_impl.crop_and_resize_v2(
++ image=array_ops.zeros((2, 1, 1, 1)),
++ boxes=[[1.0e+40, 0, 0, 0]],
++ box_indices=[1],
++ crop_size=[1, 1])
++ self.evaluate(v)
+
+ if __name__ == "__main__":
+ googletest.main()
+--
+2.7.4
+
--- /dev/null
+From e43d9728458891e72adb2c62004da5af8489ba26 Mon Sep 17 00:00:00 2001
+From: Mihai Maruseac <mihaimaruseac@google.com>
+Date: Mon, 7 Dec 2020 11:15:21 -0800
+Subject: [PATCH 3/4] Validate that `DataFormat*` attributes form a
+ permutation.
+
+The `src_format` and `dst_format` attributes for the `DataFormatDimMap` and `DataFormatVecPermute` raw ops are supposed to determine a permutation. However, this was not validated and could result in unitialized memory accesses as well as writes outside of bounds and potential crashes.
+
+While here, we also test that the format attributes have the needed length, add tests for all validation failure cases, remove unnecessary calls to `strings::StrCat`, and fix a few grammar errors.
+
+This will be cherry-picked on the supported release branches.
+
+PiperOrigin-RevId: 346135579
+Change-Id: I1c76392382c89ad8f072d5bc93d70669851eb404
+
+Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
+---
+ tensorflow/core/kernels/data_format_ops.cc | 59 +++++++++++++++++--
+ tensorflow/python/ops/nn_test.py | 95 ++++++++++++++++++++++++++++++
+ 2 files changed, 150 insertions(+), 4 deletions(-)
+
+diff --git a/tensorflow/core/kernels/data_format_ops.cc b/tensorflow/core/kernels/data_format_ops.cc
+index 27020cd..329a1d8 100644
+--- a/tensorflow/core/kernels/data_format_ops.cc
++++ b/tensorflow/core/kernels/data_format_ops.cc
+@@ -18,16 +18,52 @@ limitations under the License.
+ #define EIGEN_USE_THREADS
+
+ #include "tensorflow/core/kernels/data_format_ops.h"
++
++#include <map>
++
+ #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
+ #include "tensorflow/core/framework/op_kernel.h"
+ #include "tensorflow/core/framework/register_types.h"
+ #include "tensorflow/core/framework/tensor.h"
++#include "tensorflow/core/platform/errors.h"
+
+ namespace tensorflow {
+
+ typedef Eigen::ThreadPoolDevice CPUDevice;
+ typedef Eigen::GpuDevice GPUDevice;
+
++// Ensure that `src` and `dst` define a valid permutation.
++// Ops defined in this file assume that user specifies a permutation via two
++// string attributes. This check validates that these attributes properly define
++// it to prevent security vulnerabilities.
++static bool IsValidPermutation(const std::string& src, const std::string& dst) {
++ if (src.size() != dst.size()) {
++ return false;
++ }
++
++ std::map<char, bool> characters;
++
++ // Every character in `src` must be present only once
++ for (const auto c : src) {
++ if (characters[c]) {
++ return false;
++ }
++ characters[c] = true;
++ }
++
++ // Every character in `dst` must show up in `src` exactly once
++ for (const auto c : dst) {
++ if (!characters[c]) {
++ return false;
++ }
++ characters[c] = false;
++ }
++
++ // At this point, characters[] has been switched to true and false exactly
++ // once for all character in `src` (and `dst`) so we have a valid permutation
++ return true;
++}
++
+ template <typename Device, typename T>
+ class DataFormatDimMapOp : public OpKernel {
+ public:
+@@ -38,12 +74,13 @@ class DataFormatDimMapOp : public OpKernel {
+ string dst_format;
+ OP_REQUIRES_OK(context, context->GetAttr("dst_format", &dst_format));
+ OP_REQUIRES(context, src_format.size() == 4,
+- errors::InvalidArgument(strings::StrCat(
+- "Source format must of length 4, received src_format = ",
+- src_format)));
++ errors::InvalidArgument(
++ "Source format must be of length 4, received "
++ "src_format = ",
++ src_format));
+ OP_REQUIRES(
+ context, dst_format.size() == 4,
+- errors::InvalidArgument(strings::StrCat(
++ errors::InvalidArgument(
+ "Destination format must of length 4, received dst_format = ",
+ dst_format)));
+ dst_idx_ = Tensor(DT_INT32, {static_cast<int64>(src_format.size())});
+@@ -77,8 +114,22 @@ class DataFormatVecPermuteOp : public OpKernel {
+ : OpKernel(context) {
+ string src_format;
+ OP_REQUIRES_OK(context, context->GetAttr("src_format", &src_format));
++ OP_REQUIRES(context, src_format.size() == 4 || src_format.size() == 5,
++ errors::InvalidArgument(
++ "Source format must be of length 4 or 5, received "
++ "src_format = ",
++ src_format));
+ string dst_format;
+ OP_REQUIRES_OK(context, context->GetAttr("dst_format", &dst_format));
++ OP_REQUIRES(context, dst_format.size() == 4 || dst_format.size() == 5,
++ errors::InvalidArgument("Destination format must be of length "
++ "4 or 5, received dst_format = ",
++ dst_format));
++ OP_REQUIRES(
++ context, IsValidPermutation(src_format, dst_format),
++ errors::InvalidArgument(
++ "Destination and source format must determine a permutation, got ",
++ src_format, " and ", dst_format));
+ src_format_ = src_format;
+ dst_format_ = dst_format;
+ }
+diff --git a/tensorflow/python/ops/nn_test.py b/tensorflow/python/ops/nn_test.py
+index 82fab74..fddf883 100644
+--- a/tensorflow/python/ops/nn_test.py
++++ b/tensorflow/python/ops/nn_test.py
+@@ -26,6 +26,7 @@ from six.moves import xrange # pylint: disable=redefined-builtin
+
+ from tensorflow.python.framework import constant_op
+ from tensorflow.python.framework import dtypes
++from tensorflow.python.framework import errors
+ from tensorflow.python.framework import ops
+ from tensorflow.python.framework import test_util
+ from tensorflow.python.ops import array_ops
+@@ -1162,6 +1163,7 @@ class DataFormatDimMapTest(test_lib.TestCase):
+ y_val = self.evaluate(y)
+ self.assertAllEqual(y_val, y_val_expected)
+
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
+ def testArbitraryASCII(self):
+ x_val = [-4, -3, -2, -1, 0, 1, 2, 3]
+ y_val_expected = [3, 2, 1, 0, 3, 2, 1, 0]
+@@ -1171,6 +1173,45 @@ class DataFormatDimMapTest(test_lib.TestCase):
+ y_val = self.evaluate(y)
+ self.assertAllEqual(y_val, y_val_expected)
+
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testInvalidLength(self):
++ x = [-4, -3, -2, -1, 0, 1, 2, 3]
++ with self.assertRaisesRegex(errors.InvalidArgumentError,
++ "Source format must be of length 4 or 5"):
++ op = nn_ops.data_format_dim_map(
++ x, src_format="12345678", dst_format="87654321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testDuplicateSrc(self):
++ x = [-4, -3, -2, -1, 0, 1, 2, 3]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Destination and source format must determine a permutation"):
++ op = nn_ops.data_format_dim_map(x, src_format="1233", dst_format="4321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testDuplicateDst(self):
++ x = [-4, -3, -2, -1, 0, 1, 2, 3]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Destination and source format must determine a permutation"):
++ op = nn_ops.data_format_dim_map(x, src_format="1234", dst_format="3321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testExtraSpecifiers(self):
++ x = [-4, -3, -2, -1, 0, 1, 2, 3]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Destination and source format must determine a permutation"):
++ op = nn_ops.data_format_dim_map(x, src_format="1234", dst_format="5321")
++ with test_util.use_gpu():
++ self.evaluate(op)
+
+ class DataFormatVectorPermuteTest(test_lib.TestCase):
+
+@@ -1238,6 +1279,60 @@ class DataFormatVectorPermuteTest(test_lib.TestCase):
+ y_val = self.evaluate(y)
+ self.assertAllEqual(y_val, [[7, 4], [4, 5], [5, 1], [9, 3]])
+
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testInvalidLength(self):
++ x = [0, 1, 2, 3]
++ with self.assertRaisesRegex(errors.InvalidArgumentError,
++ "Source format must be of length 4 or 5"):
++ op = nn_ops.data_format_vec_permute(
++ x, src_format="12345678", dst_format="87654321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testDuplicateSrc(self):
++ x = [0, 1, 2, 3]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Destination and source format must determine a permutation"):
++ op = nn_ops.data_format_vec_permute(
++ x, src_format="1233", dst_format="4321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testDuplicateDst(self):
++ x = [0, 1, 2, 3]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Destination and source format must determine a permutation"):
++ op = nn_ops.data_format_vec_permute(
++ x, src_format="1234", dst_format="3321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def testExtraSpecifiers(self):
++ x = [0, 1, 2, 3]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Destination and source format must determine a permutation"):
++ op = nn_ops.data_format_vec_permute(
++ x, src_format="1234", dst_format="5321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
++ @test_util.disable_xla("XLA catches the error and rethrows as different one")
++ def test2DNoWH(self):
++ x = [[0, 1], [2, 3]]
++ with self.assertRaisesRegex(
++ errors.InvalidArgumentError,
++ "Format specifier must contain H and W for 2D case"):
++ op = nn_ops.data_format_vec_permute(
++ x, src_format="1234", dst_format="4321")
++ with test_util.use_gpu():
++ self.evaluate(op)
++
+
+ if __name__ == "__main__":
+ test_lib.main()
+--
+2.7.4
+
--- /dev/null
+From 8b8ca5468ad7eb127d9d17faf872b45a78935626 Mon Sep 17 00:00:00 2001
+From: Mihai Maruseac <mihaimaruseac@google.com>
+Date: Fri, 20 Dec 2019 15:33:46 -0800
+Subject: [PATCH 4/4] Fix segfault when attempting to convert string to
+ float16.
+
+To make sure this gets fixed, add test for converting string to any numeric type.
+
+PiperOrigin-RevId: 286650886
+Change-Id: I81f770ec2bbd33a863e8057ce198c679912fa8e0
+
+Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com>
+---
+ tensorflow/python/BUILD | 11 +++++
+ tensorflow/python/framework/constant_op_test.py | 61 +++++++++++++++++++++++++
+ tensorflow/python/lib/core/py_seq_tensor.cc | 24 ++++++++--
+ 3 files changed, 93 insertions(+), 3 deletions(-)
+ create mode 100644 tensorflow/python/framework/constant_op_test.py
+
+diff --git a/tensorflow/python/BUILD b/tensorflow/python/BUILD
+index 8c0e95e..4ad1541 100644
+--- a/tensorflow/python/BUILD
++++ b/tensorflow/python/BUILD
+@@ -1108,6 +1108,17 @@ py_library(
+ )
+
+ py_test(
++ name = "framework_constant_op_test",
++ size = "small",
++ srcs = ["framework/constant_op_test.py"],
++ main = "framework/constant_op_test.py",
++ python_version = "PY3",
++ deps = [
++ ":constant_op",
++ ],
++)
++
+++tf_py_test(
+ name = "framework_registry_test",
+ size = "small",
+ srcs = ["framework/registry_test.py"],
+diff --git a/tensorflow/python/framework/constant_op_test.py b/tensorflow/python/framework/constant_op_test.py
+new file mode 100644
+index 0000000..da0fb64
+--- /dev/null
++++ b/tensorflow/python/framework/constant_op_test.py
+@@ -0,0 +1,61 @@
++# 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.
++# ==============================================================================
++"""Tests for tensorflow.python.framework.constant_op."""
++
++from __future__ import absolute_import
++from __future__ import division
++from __future__ import print_function
++
++from absl.testing import parameterized
++
++from tensorflow.python.framework import constant_op
++from tensorflow.python.framework import dtypes
++from tensorflow.python.framework import ops
++from tensorflow.python.platform import test
++
++
++class ConstantOpTest(test.TestCase, parameterized.TestCase):
++
++ @parameterized.parameters(
++ dtypes.bfloat16,
++ dtypes.complex128,
++ dtypes.complex64,
++ dtypes.double,
++ dtypes.float16,
++ dtypes.float32,
++ dtypes.float64,
++ dtypes.half,
++ dtypes.int16,
++ dtypes.int32,
++ dtypes.int64,
++ dtypes.int8,
++ dtypes.qint16,
++ dtypes.qint32,
++ dtypes.qint8,
++ dtypes.quint16,
++ dtypes.quint8,
++ dtypes.uint16,
++ dtypes.uint32,
++ dtypes.uint64,
++ dtypes.uint8,
++ )
++ def test_convert_string_to_number(self, dtype):
++ with self.assertRaises(TypeError):
++ constant_op.constant("hello", dtype)
++
++
++if __name__ == "__main__":
++ ops.enable_eager_execution()
++ test.main()
+diff --git a/tensorflow/python/lib/core/py_seq_tensor.cc b/tensorflow/python/lib/core/py_seq_tensor.cc
+index f681cff..418fa3b 100644
+--- a/tensorflow/python/lib/core/py_seq_tensor.cc
++++ b/tensorflow/python/lib/core/py_seq_tensor.cc
+@@ -21,6 +21,7 @@ limitations under the License.
+ #include "tensorflow/core/lib/core/errors.h"
+ #include "tensorflow/core/lib/core/stringpiece.h"
+ #include "tensorflow/core/lib/strings/str_util.h"
++#include "tensorflow/core/platform/macros.h"
+ #include "tensorflow/core/platform/types.h"
+ #include "tensorflow/python/lib/core/numpy.h"
+ #include "tensorflow/python/lib/core/py_util.h"
+@@ -329,6 +330,21 @@ DEFINE_HELPER(ConvertInt32, int32, DT_INT32, ConvertOneInt32);
+
+ // Floating-point support
+
++// Returns `true` if `out` overflows when converted from `as_double`.
++template <class T>
++static inline bool CheckForOverflow(double as_double, T* out) {
++ return (sizeof(T) < sizeof(double) && std::isinf(*out) &&
++ std::isfinite(as_double));
++}
++
++// There is no `std::isinf` that takes `Eigen::half` as argument but Eigen
++// provides `Eigen::half_impl::isinf` instead.
++template <>
++inline bool CheckForOverflow<Eigen::half>(double as_double, Eigen::half* out) {
++ return (sizeof(Eigen::half) < sizeof(double) &&
++ Eigen::half_impl::isinf(*out) && std::isfinite(as_double));
++}
++
+ template <class T>
+ const char* ConvertOneFloat(PyObject* v, T* out) {
+ if (TF_PREDICT_TRUE(PyFloat_Check(v))) {
+@@ -337,12 +353,12 @@ const char* ConvertOneFloat(PyObject* v, T* out) {
+ }
+ #if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(v)) {
+- *out = PyInt_AS_LONG(v);
++ *out = static_cast<T>(PyInt_AS_LONG(v));
+ return nullptr;
+ }
+ #endif
+ if (PyLong_Check(v)) {
+- *out = PyLong_AsDouble(v);
++ *out = static_cast<T>(PyLong_AsDouble(v));
+ if (PyErr_Occurred()) return ErrorOutOfRangeDouble;
+ return nullptr;
+ }
+@@ -471,7 +487,9 @@ Status PySeqToTensor(PyObject* obj, PyObject* dtype, Tensor* ret) {
+ break;
+
+ case DT_HALF:
+- RETURN_STRING_AS_STATUS(ConvertNumpyHalf(obj, shape, ret));
++ if (NumpyHalfConverter::Convert(obj, &state, ret) == nullptr)
++ return Status::OK();
++ break;
+
+ case DT_INT64:
+ if (ConvertInt64(obj, shape, ret) == nullptr) return Status::OK();
+--
+2.7.4
+