diff --git a/CVE-2021-29512_CVE-2021-29514.patch b/CVE-2021-29512_CVE-2021-29514.patch new file mode 100644 index 0000000000000000000000000000000000000000..c497636be32952a5b5df44c4ad096e3591b5f11b --- /dev/null +++ b/CVE-2021-29512_CVE-2021-29514.patch @@ -0,0 +1,32 @@ +From eebb96c2830d48597d055d247c0e9aebaea94cd5 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Tue, 13 Apr 2021 14:18:51 -0700 +Subject: [PATCH] Fix an invalid address vulnerability in + `tf.raw_ops.RaggedBincount`. + +PiperOrigin-RevId: 368293153 +Change-Id: I4b4e493d3fd05e7dc55a55de3a041a80a4f275c3 +--- + tensorflow/core/kernels/bincount_op.cc | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/tensorflow/core/kernels/bincount_op.cc b/tensorflow/core/kernels/bincount_op.cc +index 35911ee5d5540..258266ab29d33 100644 +--- a/tensorflow/core/kernels/bincount_op.cc ++++ b/tensorflow/core/kernels/bincount_op.cc +@@ -420,6 +420,15 @@ class RaggedBincountOp : public OpKernel { + int num_values = values.size(); + int batch_idx = 0; + ++ OP_REQUIRES(ctx, splits(0) == 0, ++ errors::InvalidArgument("Splits must start with 0, not with ", ++ splits(0))); ++ ++ OP_REQUIRES(ctx, splits(num_rows) == num_values, ++ errors::InvalidArgument( ++ "Splits must end with the number of values, got ", ++ splits(num_rows), " instead of ", num_values)); ++ + Tensor* out_t; + OP_REQUIRES_OK( + ctx, ctx->allocate_output(0, TensorShape({num_rows, size}), &out_t)); diff --git a/CVE-2021-29519.patch b/CVE-2021-29519.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d07edad9a7fafca34ab9727b60d465ccd93de5f --- /dev/null +++ b/CVE-2021-29519.patch @@ -0,0 +1,143 @@ +From b1cc5e5a50e7cee09f2c6eb48eb40ee9c4125025 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Thu, 15 Apr 2021 13:03:19 -0700 +Subject: [PATCH] Fix `tf.raw_ops.SparseCross` failing CHECK. + +PiperOrigin-RevId: 368701671 +Change-Id: Id805729dd9ba0bda36e4bb309408129b55fb649d +--- + tensorflow/core/kernels/sparse_cross_op.cc | 55 +++++++++++++++++++--- + 1 file changed, 48 insertions(+), 7 deletions(-) + +diff --git a/tensorflow/core/kernels/sparse_cross_op.cc b/tensorflow/core/kernels/sparse_cross_op.cc +index 583235b4a309b..43b3bedc74503 100644 +--- a/tensorflow/core/kernels/sparse_cross_op.cc ++++ b/tensorflow/core/kernels/sparse_cross_op.cc +@@ -27,6 +27,7 @@ limitations under the License. + #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/lib/core/stringpiece.h" + #include "tensorflow/core/lib/strings/str_util.h" + #include "tensorflow/core/platform/fingerprint.h" +@@ -460,10 +461,19 @@ int64 CalculateBatchSize(const OpInputList& shapes_list_in, + Status ValidateInput(const OpInputList& indices_list_in, + const OpInputList& values_list_in, + const OpInputList& shapes_list_in, +- const OpInputList& dense_list_in) { ++ const OpInputList& dense_list_in, ++ const DataType& internal_type) { + const auto size = indices_list_in.size(); ++ // Only perform internal_type check for SparseCrossOp. ++ // Check if the internal_type is not invalid before doing so. ++ bool check_type = internal_type != DT_INVALID; + // Validates indices_list_in OpInputList. + for (int i = 0; i < size; i++) { ++ if (check_type && indices_list_in[i].dtype() != DT_INT64) { ++ return errors::InvalidArgument("Input indices should be of type ", ++ DT_INT64, " but received ", ++ indices_list_in[i].dtype()); ++ } + if (!TensorShapeUtils::IsMatrix(indices_list_in[i].shape())) { + return errors::InvalidArgument( + "Input indices should be a matrix but received shape ", +@@ -482,6 +492,14 @@ Status ValidateInput(const OpInputList& indices_list_in, + values_list_in.size()); + } + for (int i = 0; i < size; i++) { ++ // Make sure to avoid the expected type to be string, but input values to be ++ // int64. ++ if (check_type && internal_type == DT_STRING && ++ values_list_in[i].dtype() == DT_INT64) { ++ return errors::InvalidArgument("Input values should be of internal type ", ++ internal_type, " but received ", ++ values_list_in[i].dtype()); ++ } + if (!TensorShapeUtils::IsVector(values_list_in[i].shape())) { + return errors::InvalidArgument( + "Input values should be a vector but received shape ", +@@ -502,6 +520,11 @@ Status ValidateInput(const OpInputList& indices_list_in, + shapes_list_in.size()); + } + for (int i = 0; i < size; i++) { ++ if (check_type && shapes_list_in[i].dtype() != DT_INT64) { ++ return errors::InvalidArgument("Input shape should be of type ", DT_INT64, ++ " but received ", ++ shapes_list_in[i].dtype()); ++ } + if (!TensorShapeUtils::IsVector(shapes_list_in[i].shape())) { + return errors::InvalidArgument( + "Input shapes should be a vector but received shape ", +@@ -517,6 +540,14 @@ Status ValidateInput(const OpInputList& indices_list_in, + + // Validates dense_list_in OpInputList + for (int i = 0; i < dense_list_in.size(); ++i) { ++ // Make sure to avoid the expected type to be string, but input values to be ++ // int64. ++ if (check_type && internal_type == DT_STRING && ++ dense_list_in[i].dtype() == DT_INT64) { ++ return errors::InvalidArgument("Dense inputs should be of internal type ", ++ internal_type, " but received ", ++ dense_list_in[i].dtype()); ++ } + if (!TensorShapeUtils::IsMatrix(dense_list_in[i].shape())) { + return errors::InvalidArgument( + "Dense inputs should be a matrix but received shape ", +@@ -698,6 +729,7 @@ class SparseCrossOp : public OpKernel { + int64 signed_hash_key_; + OP_REQUIRES_OK(context, context->GetAttr("hash_key", &signed_hash_key_)); + hash_key_ = static_cast(signed_hash_key_); ++ OP_REQUIRES_OK(context, context->GetAttr("internal_type", &internal_type_)); + } + + void Compute(OpKernelContext* context) override { +@@ -711,8 +743,10 @@ class SparseCrossOp : public OpKernel { + OP_REQUIRES_OK(context, + context->input_list("dense_inputs", &dense_list_in)); + +- OP_REQUIRES_OK(context, ValidateInput(indices_list_in, values_list_in, +- shapes_list_in, dense_list_in)); ++ DataType internal_type = internal_type_; ++ OP_REQUIRES_OK( ++ context, ValidateInput(indices_list_in, values_list_in, shapes_list_in, ++ dense_list_in, internal_type)); + + std::vector>> columns = + GenerateColumnsFromInput(indices_list_in, values_list_in, +@@ -756,6 +790,7 @@ class SparseCrossOp : public OpKernel { + private: + int64 num_buckets_; + uint64 hash_key_; ++ DataType internal_type_; + }; + + class SparseCrossV2Op : public OpKernel { +@@ -773,8 +808,11 @@ class SparseCrossV2Op : public OpKernel { + OP_REQUIRES_OK(context, + context->input_list("dense_inputs", &dense_list_in)); + +- OP_REQUIRES_OK(context, ValidateInput(indices_list_in, values_list_in, +- shapes_list_in, dense_list_in)); ++ // Set internal_type to invalid_type so that the check will be ignored. ++ DataType internal_type = DT_INVALID; ++ OP_REQUIRES_OK( ++ context, ValidateInput(indices_list_in, values_list_in, shapes_list_in, ++ dense_list_in, internal_type)); + + const Tensor* sep_t; + OP_REQUIRES_OK(context, context->input("sep", &sep_t)); +@@ -832,8 +870,11 @@ class SparseCrossHashedOp : public OpKernel { + OP_REQUIRES_OK(context, + context->input_list("dense_inputs", &dense_list_in)); + +- OP_REQUIRES_OK(context, ValidateInput(indices_list_in, values_list_in, +- shapes_list_in, dense_list_in)); ++ // Set internal_type to invalid_type so that the check will be ignored. ++ DataType internal_type = DT_INVALID; ++ OP_REQUIRES_OK( ++ context, ValidateInput(indices_list_in, values_list_in, shapes_list_in, ++ dense_list_in, internal_type)); + + const Tensor* num_buckets_t; + OP_REQUIRES_OK(context, context->input("num_buckets", &num_buckets_t)); diff --git a/CVE-2021-29520.patch b/CVE-2021-29520.patch new file mode 100644 index 0000000000000000000000000000000000000000..110468a8cd24c60d120948e1392984de7c742273 --- /dev/null +++ b/CVE-2021-29520.patch @@ -0,0 +1,102 @@ +From 8f37b52e1320d8d72a9529b2468277791a261197 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 19 Apr 2021 13:46:32 -0700 +Subject: [PATCH] Validate some shape requirements for `Conv3DBackpropFilter*` + and `Conv3DBackpropInput*` ops. + +Older versions of Eigen might otherwise crash / produce OOB read on specially crafted inputs. + +PiperOrigin-RevId: 369293977 +Change-Id: I58f51445a93936d7cf8e616f75de17677df36718 +--- + tensorflow/core/kernels/conv_grad_ops_3d.cc | 56 +++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/tensorflow/core/kernels/conv_grad_ops_3d.cc b/tensorflow/core/kernels/conv_grad_ops_3d.cc +index f736a12fb1ca3..8c72d01578d6d 100644 +--- a/tensorflow/core/kernels/conv_grad_ops_3d.cc ++++ b/tensorflow/core/kernels/conv_grad_ops_3d.cc +@@ -239,6 +239,20 @@ class Conv3DBackpropInputOp : public OpKernel { + input_shape = context->input(0).shape(); + } + ++ OP_REQUIRES( ++ context, input_shape.dim_size(4) == filter_shape.dim_size(3), ++ errors::InvalidArgument("input and filter_sizes must have the same " ++ "number of channels. Got ", ++ input_shape.dim_size(4), " for input and ", ++ filter_shape.dim_size(3), " for filter_sizes")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dim_size(4) == filter_shape.dim_size(4), ++ errors::InvalidArgument("out_backprop and filter_sizes must have the " ++ "same number of channels. Got ", ++ out_backprop_shape.dim_size(4), ++ " for out_backprop and ", ++ filter_shape.dim_size(4), " for filter_sizes")); ++ + ConvBackpropDimensions dims; + OP_REQUIRES_OK(context, ConvBackpropComputeDimensions( + "Conv3DBackpropInputOp", /*num_spatial_dims=*/3, +@@ -346,6 +360,20 @@ class Conv3DCustomBackpropInputOp : public OpKernel { + input_shape = context->input(0).shape(); + } + ++ OP_REQUIRES( ++ context, input_shape.dim_size(4) == filter_shape.dim_size(3), ++ errors::InvalidArgument("input and filter_sizes must have the same " ++ "number of channels. Got ", ++ input_shape.dim_size(4), " for input and ", ++ filter_shape.dim_size(3), " for filter_sizes")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dim_size(4) == filter_shape.dim_size(4), ++ errors::InvalidArgument("out_backprop and filter_sizes must have the " ++ "same number of channels. Got ", ++ out_backprop_shape.dim_size(4), ++ " for out_backprop and ", ++ filter_shape.dim_size(4), " for filter_sizes")); ++ + ConvBackpropDimensions dims; + OP_REQUIRES_OK(context, ConvBackpropComputeDimensions( + "Conv3DBackpropInputOp", /*num_spatial_dims=*/3, +@@ -696,6 +724,20 @@ class Conv3DBackpropFilterOp : public OpKernel { + filter_shape = context->input(1).shape(); + } + ++ OP_REQUIRES( ++ context, input_shape.dim_size(4) == filter_shape.dim_size(3), ++ errors::InvalidArgument("input and filter_sizes must have the same " ++ "number of channels. Got ", ++ input_shape.dim_size(4), " for input and ", ++ filter_shape.dim_size(3), " for filter_sizes")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dim_size(4) == filter_shape.dim_size(4), ++ errors::InvalidArgument("out_backprop and filter_sizes must have the " ++ "same number of channels. Got ", ++ out_backprop_shape.dim_size(4), ++ " for out_backprop and ", ++ filter_shape.dim_size(4), " for filter_sizes")); ++ + ConvBackpropDimensions dims; + OP_REQUIRES_OK(context, + ConvBackpropComputeDimensions( +@@ -808,6 +850,20 @@ class Conv3DCustomBackpropFilterOp : public OpKernel { + filter_shape = context->input(1).shape(); + } + ++ OP_REQUIRES( ++ context, input_shape.dim_size(4) == filter_shape.dim_size(3), ++ errors::InvalidArgument("input and filter_sizes must have the same " ++ "number of channels. Got ", ++ input_shape.dim_size(4), " for input and ", ++ filter_shape.dim_size(3), " for filter_sizes")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dim_size(4) == filter_shape.dim_size(4), ++ errors::InvalidArgument("out_backprop and filter_sizes must have the " ++ "same number of channels. Got ", ++ out_backprop_shape.dim_size(4), ++ " for out_backprop and ", ++ filter_shape.dim_size(4), " for filter_sizes")); ++ + ConvBackpropDimensions dims; + OP_REQUIRES_OK(context, + ConvBackpropComputeDimensions( diff --git a/CVE-2021-29522.patch b/CVE-2021-29522.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb215cd455a2c4a0018133cd7732afc6d0925f3b --- /dev/null +++ b/CVE-2021-29522.patch @@ -0,0 +1,101 @@ +From 311403edbc9816df80274bd1ea8b3c0c0f22c3fa Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 19 Apr 2021 16:00:40 -0700 +Subject: [PATCH] Eliminate a division by 0 in 3D convolutions. + +Also prevent a CHECK failed introduced in the most recent change. + +PiperOrigin-RevId: 369322073 +Change-Id: I4f609c028f89565fb2b49c3fdd20b63496582bae +--- + tensorflow/core/kernels/conv_grad_ops_3d.cc | 42 +++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/tensorflow/core/kernels/conv_grad_ops_3d.cc b/tensorflow/core/kernels/conv_grad_ops_3d.cc +index 8c72d01578d6d..c0b57a7ae5606 100644 +--- a/tensorflow/core/kernels/conv_grad_ops_3d.cc ++++ b/tensorflow/core/kernels/conv_grad_ops_3d.cc +@@ -239,6 +239,14 @@ class Conv3DBackpropInputOp : public OpKernel { + input_shape = context->input(0).shape(); + } + ++ OP_REQUIRES(context, input_shape.dims() == 5, ++ errors::InvalidArgument("input tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, filter_shape.dims() == 5, ++ errors::InvalidArgument("filter_sizes tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dims() == 5, ++ errors::InvalidArgument("out_backprop tensor must have 5 dimensions")); + OP_REQUIRES( + context, input_shape.dim_size(4) == filter_shape.dim_size(3), + errors::InvalidArgument("input and filter_sizes must have the same " +@@ -360,6 +368,14 @@ class Conv3DCustomBackpropInputOp : public OpKernel { + input_shape = context->input(0).shape(); + } + ++ OP_REQUIRES(context, input_shape.dims() == 5, ++ errors::InvalidArgument("input tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, filter_shape.dims() == 5, ++ errors::InvalidArgument("filter_sizes tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dims() == 5, ++ errors::InvalidArgument("out_backprop tensor must have 5 dimensions")); + OP_REQUIRES( + context, input_shape.dim_size(4) == filter_shape.dim_size(3), + errors::InvalidArgument("input and filter_sizes must have the same " +@@ -444,6 +460,11 @@ class Conv3DCustomBackpropInputOp : public OpKernel { + // contraction compared to sharding and matmuls. + const bool use_parallel_contraction = dims.batch_size == 1; + ++ OP_REQUIRES( ++ context, work_unit_size > 0, ++ errors::InvalidArgument("input, filter_sizes and out_backprop tensors " ++ "must all have at least 1 element")); ++ + const size_t shard_size = + use_parallel_contraction + ? 1 +@@ -724,6 +745,14 @@ class Conv3DBackpropFilterOp : public OpKernel { + filter_shape = context->input(1).shape(); + } + ++ OP_REQUIRES(context, input_shape.dims() == 5, ++ errors::InvalidArgument("input tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, filter_shape.dims() == 5, ++ errors::InvalidArgument("filter_sizes tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dims() == 5, ++ errors::InvalidArgument("out_backprop tensor must have 5 dimensions")); + OP_REQUIRES( + context, input_shape.dim_size(4) == filter_shape.dim_size(3), + errors::InvalidArgument("input and filter_sizes must have the same " +@@ -850,6 +879,14 @@ class Conv3DCustomBackpropFilterOp : public OpKernel { + filter_shape = context->input(1).shape(); + } + ++ OP_REQUIRES(context, input_shape.dims() == 5, ++ errors::InvalidArgument("input tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, filter_shape.dims() == 5, ++ errors::InvalidArgument("filter_sizes tensor must have 5 dimensions")); ++ OP_REQUIRES( ++ context, out_backprop_shape.dims() == 5, ++ errors::InvalidArgument("out_backprop tensor must have 5 dimensions")); + OP_REQUIRES( + context, input_shape.dim_size(4) == filter_shape.dim_size(3), + errors::InvalidArgument("input and filter_sizes must have the same " +@@ -936,6 +973,11 @@ class Conv3DCustomBackpropFilterOp : public OpKernel { + + const int64 work_unit_size = size_A + size_B + size_C; + ++ OP_REQUIRES( ++ context, work_unit_size > 0, ++ errors::InvalidArgument("input, filter_sizes and out_backprop tensors " ++ "must all have at least 1 element")); ++ + const size_t shard_size = + (target_working_set_size + work_unit_size - 1) / work_unit_size; + diff --git a/CVE-2021-29524.patch b/CVE-2021-29524.patch new file mode 100644 index 0000000000000000000000000000000000000000..b12fac657c54409b2c04b6af6be35635d1265cc4 --- /dev/null +++ b/CVE-2021-29524.patch @@ -0,0 +1,26 @@ +From fca9874a9b42a2134f907d2fb46ab774a831404a Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 19 Apr 2021 17:33:11 -0700 +Subject: [PATCH] Prevent another division by zero. + +PiperOrigin-RevId: 369338598 +Change-Id: I55471d363e401fdcf8d259670ad4eef672b731e2 +--- + tensorflow/core/kernels/conv_grad_shape_utils.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/conv_grad_shape_utils.cc b/tensorflow/core/kernels/conv_grad_shape_utils.cc +index 7543ce669923a..805f5809a472e 100644 +--- a/tensorflow/core/kernels/conv_grad_shape_utils.cc ++++ b/tensorflow/core/kernels/conv_grad_shape_utils.cc +@@ -127,6 +127,10 @@ Status ConvBackpropComputeDimensionsV2( + // dimensions of the filter Tensor. + VLOG(2) << "input vs filter_in depth " << dims->in_depth << " " + << filter_shape.dim_size(num_dims - 2); ++ if (filter_shape.dim_size(num_dims - 2) <= 0) { ++ return errors ::InvalidArgument( ++ label, ": filter depth must be strictly greated than zero"); ++ } + if (dims->in_depth % filter_shape.dim_size(num_dims - 2)) { + return errors::InvalidArgument( + label, ": input depth must be evenly divisible by filter depth"); diff --git a/CVE-2021-29527.patch b/CVE-2021-29527.patch new file mode 100644 index 0000000000000000000000000000000000000000..065cec320c0400553ecc4a1cda63426338a617c7 --- /dev/null +++ b/CVE-2021-29527.patch @@ -0,0 +1,49 @@ +From cfa91be9863a91d5105a3b4941096044ab32036b Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 19 Apr 2021 18:58:47 -0700 +Subject: [PATCH] Fix one FPE and remove two CHECK-fails. + +PiperOrigin-RevId: 369349640 +Change-Id: I1fedbfc2b5bab635c5cb51f103d7c9176f79831a +--- + tensorflow/core/kernels/quantized_conv_ops.cc | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/tensorflow/core/kernels/quantized_conv_ops.cc b/tensorflow/core/kernels/quantized_conv_ops.cc +index a4d36cca3e408..a339de8cfc8fa 100644 +--- a/tensorflow/core/kernels/quantized_conv_ops.cc ++++ b/tensorflow/core/kernels/quantized_conv_ops.cc +@@ -18,6 +18,8 @@ limitations under the License. + #include + #include + ++#include "tensorflow/core/platform/errors.h" ++ + #define EIGEN_USE_THREADS + + #define GEMMLOWP_ALLOW_SLOW_SCALAR_FALLBACK +@@ -227,8 +229,12 @@ class Im2ColConvFunctor { + return; + } + +- CHECK_GT(output_width, 0); +- CHECK_GT(output_height, 0); ++ OP_REQUIRES( ++ context, output_width > 0, ++ errors::InvalidArgument("output_width must be strictly positive")); ++ OP_REQUIRES( ++ context, output_height > 0, ++ errors::InvalidArgument("output_height must be strictly positive")); + int filter_left_offset; + int filter_top_offset; + if (padding == VALID) { +@@ -255,6 +261,9 @@ class Im2ColConvFunctor { + // by the width, then the height. This is the standard memory order in the + // image world if it helps to visualize it. + const int filter_value_count = filter_width * filter_height * input_depth; ++ OP_REQUIRES(context, filter_value_count > 0, ++ errors::InvalidArgument( ++ "filter patch must contain at least one element")); + const int64 patches_per_chunk = + kMaxChunkSize / (filter_value_count * sizeof(T1)); + const int64 chunk_value_count = diff --git a/CVE-2021-29528.patch b/CVE-2021-29528.patch new file mode 100644 index 0000000000000000000000000000000000000000..982883c150cdc4fb4c63e2b115cef06076f0b9ef --- /dev/null +++ b/CVE-2021-29528.patch @@ -0,0 +1,27 @@ +From a1b11d2fdd1e51bfe18bb1ede804f60abfa92da6 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 20 Apr 2021 10:52:46 -0700 +Subject: [PATCH] Fix one division by zero + +PiperOrigin-RevId: 369474832 +Change-Id: I1082858ed78d9b2e4738ce30b231955973d49e1e +--- + tensorflow/core/kernels/quantized_mul_op.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/quantized_mul_op.cc b/tensorflow/core/kernels/quantized_mul_op.cc +index 4e191f162662b..fb56f68bf14db 100644 +--- a/tensorflow/core/kernels/quantized_mul_op.cc ++++ b/tensorflow/core/kernels/quantized_mul_op.cc +@@ -347,6 +347,11 @@ class QuantizedMulOp : public OpKernel { + tensor_num_elements = x.NumElements(); + tensor_offset = offset_x; + } ++ if (vector_num_elements == 0) { ++ context->SetStatus( ++ errors::InvalidArgument("vector must have at least 1 element")); ++ return; ++ } + VectorTensorMultiply( + vector_data, vector_offset, vector_num_elements, tensor_data, + tensor_offset, tensor_num_elements, z_data); diff --git a/CVE-2021-29529.patch b/CVE-2021-29529.patch new file mode 100644 index 0000000000000000000000000000000000000000..83fc30fdb525203f1b30cc046c080e4aabbb2633 --- /dev/null +++ b/CVE-2021-29529.patch @@ -0,0 +1,26 @@ +From f851613f8f0fb0c838d160ced13c134f778e3ce7 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 21 Apr 2021 16:20:48 -0700 +Subject: [PATCH] Fix heap buffer overflow caused by rounding. + +This was hard to fix. Due to the way we compute the pixels that influence an output pixel in resized images, for certain input configuration we might have issued a read to a pixel that is outside of boundary of the original image. This is because of floating errors that affected truncation results. + +PiperOrigin-RevId: 369757871 +Change-Id: If89425fff930983829a2168203c11858883eebc9 +--- + tensorflow/core/kernels/quantized_resize_bilinear_op.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/quantized_resize_bilinear_op.cc b/tensorflow/core/kernels/quantized_resize_bilinear_op.cc +index 07453c7e73284..2fd807f6df961 100644 +--- a/tensorflow/core/kernels/quantized_resize_bilinear_op.cc ++++ b/tensorflow/core/kernels/quantized_resize_bilinear_op.cc +@@ -64,6 +64,8 @@ inline void ComputeInterpolationWeights( + std::max(static_cast(in_f), static_cast(0)); + interpolation->upper[i] = + std::min(static_cast(std::ceil(in)), in_size - 1); ++ interpolation->lower[i] = ++ std::min(interpolation->lower[i], interpolation->upper[i]); + interpolation->lerp[i] = in - in_f; + interpolation->ilerp[i] = + static_cast((in - in_f) * (1 << resolution)); diff --git a/CVE-2021-29530.patch b/CVE-2021-29530.patch new file mode 100644 index 0000000000000000000000000000000000000000..5a9652e711174166c3fc44ac669053379d4bd6cc --- /dev/null +++ b/CVE-2021-29530.patch @@ -0,0 +1,117 @@ +From e6a7c7cc18c3aaad1ae0872cb0a959f5c923d2bd Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 20 Apr 2021 14:45:33 -0700 +Subject: [PATCH] Remove `OP_REQUIRES` call from helper function. + +Since `OP_REQUIRES` macro expands to a `return;` (among other), calling it in a helper function only ends the helper function's execution earlier, but the kernel will still run from start to end. Thus, all the expected validations are actually broken/useless as the code ploughs through the next crash anyway. + +PiperOrigin-RevId: 369524386 +Change-Id: I54f6cf9328445675ccc392e661b04336b229c9da +--- + .../core/kernels/sparse/sparse_cholesky_op.cc | 67 ++++++++++--------- + 1 file changed, 34 insertions(+), 33 deletions(-) + +diff --git a/tensorflow/core/kernels/sparse/sparse_cholesky_op.cc b/tensorflow/core/kernels/sparse/sparse_cholesky_op.cc +index 9a939276f0b6c..47ab252317de5 100644 +--- a/tensorflow/core/kernels/sparse/sparse_cholesky_op.cc ++++ b/tensorflow/core/kernels/sparse/sparse_cholesky_op.cc +@@ -17,6 +17,8 @@ limitations under the License. + #include + #include + ++#include "tensorflow/core/framework/op_requires.h" ++ + #define EIGEN_USE_THREADS + + #include "third_party/eigen3/Eigen/Core" +@@ -82,8 +84,8 @@ class CSRSparseCholeskyCPUOp : public OpKernel { + + int64 num_rows; + int batch_size; +- ValidateInputs(ctx, *input_matrix, input_permutation_indices, &batch_size, +- &num_rows); ++ OP_REQUIRES_OK(ctx, ValidateInputs(*input_matrix, input_permutation_indices, ++ &batch_size, &num_rows)); + + // Allocate batch pointers. + Tensor batch_ptr(cpu_allocator(), DT_INT32, TensorShape({batch_size + 1})); +@@ -226,49 +228,48 @@ class CSRSparseCholeskyCPUOp : public OpKernel { + } + + private: +- void ValidateInputs(OpKernelContext* ctx, +- const CSRSparseMatrix& sparse_matrix, +- const Tensor& permutation_indices, int* batch_size, +- int64* num_rows) { +- OP_REQUIRES(ctx, sparse_matrix.dtype() == DataTypeToEnum::value, +- errors::InvalidArgument( +- "Asked for a CSRSparseMatrix of type ", +- DataTypeString(DataTypeToEnum::value), +- " but saw dtype: ", DataTypeString(sparse_matrix.dtype()))); ++ Status ValidateInputs(const CSRSparseMatrix& sparse_matrix, ++ const Tensor& permutation_indices, int* batch_size, ++ int64* num_rows) { ++ if (sparse_matrix.dtype() != DataTypeToEnum::value) ++ return errors::InvalidArgument( ++ "Asked for a CSRSparseMatrix of type ", ++ DataTypeString(DataTypeToEnum::value), ++ " but saw dtype: ", DataTypeString(sparse_matrix.dtype())); + + const Tensor& dense_shape = sparse_matrix.dense_shape(); + const int rank = dense_shape.dim_size(0); +- OP_REQUIRES(ctx, rank == 2 || rank == 3, +- errors::InvalidArgument("sparse matrix must have rank 2 or 3; ", +- "but dense_shape has size ", rank)); ++ if (rank < 2 || rank > 3) ++ return errors::InvalidArgument("sparse matrix must have rank 2 or 3; ", ++ "but dense_shape has size ", rank); + const int row_dim = (rank == 2) ? 0 : 1; + auto dense_shape_vec = dense_shape.vec(); + *num_rows = dense_shape_vec(row_dim); + const int64 num_cols = dense_shape_vec(row_dim + 1); +- OP_REQUIRES(ctx, *num_rows == num_cols, +- errors::InvalidArgument("sparse matrix must be square; got: ", +- *num_rows, " != ", num_cols)); ++ if (*num_rows != num_cols) ++ return errors::InvalidArgument( ++ "sparse matrix must be square; got: ", *num_rows, " != ", num_cols); + const TensorShape& perm_shape = permutation_indices.shape(); +- OP_REQUIRES( +- ctx, perm_shape.dims() + 1 == rank, +- errors::InvalidArgument( +- "sparse matrix must have the same rank as permutation; got: ", rank, +- " != ", perm_shape.dims(), " + 1.")); +- OP_REQUIRES( +- ctx, perm_shape.dim_size(rank - 2) == *num_rows, +- errors::InvalidArgument( +- "permutation must have the same number of elements in each batch " +- "as the number of rows in sparse matrix; got: ", +- perm_shape.dim_size(rank - 2), " != ", *num_rows)); ++ if (perm_shape.dims() + 1 != rank) ++ return errors::InvalidArgument( ++ "sparse matrix must have the same rank as permutation; got: ", rank, ++ " != ", perm_shape.dims(), " + 1."); ++ if (perm_shape.dim_size(rank - 2) != *num_rows) ++ return errors::InvalidArgument( ++ "permutation must have the same number of elements in each batch " ++ "as the number of rows in sparse matrix; got: ", ++ perm_shape.dim_size(rank - 2), " != ", *num_rows); + + *batch_size = sparse_matrix.batch_size(); + if (*batch_size > 1) { +- OP_REQUIRES( +- ctx, perm_shape.dim_size(0) == *batch_size, +- errors::InvalidArgument("permutation must have the same batch size " +- "as sparse matrix; got: ", +- perm_shape.dim_size(0), " != ", *batch_size)); ++ if (perm_shape.dim_size(0) != *batch_size) ++ return errors::InvalidArgument( ++ "permutation must have the same batch size " ++ "as sparse matrix; got: ", ++ perm_shape.dim_size(0), " != ", *batch_size); + } ++ ++ return Status::OK(); + } + }; + diff --git a/CVE-2021-29532.patch b/CVE-2021-29532.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c4d376485f6fd0769cb45dbcf75e5ff77012d32 --- /dev/null +++ b/CVE-2021-29532.patch @@ -0,0 +1,69 @@ +From 44b7f486c0143f68b56c34e2d01e146ee445134a Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 21 Apr 2021 16:19:54 -0700 +Subject: [PATCH] Fix out of bounds read in `ragged_cross_op.cc`. + +PiperOrigin-RevId: 369757702 +Change-Id: Ie6e5d2c21513a8d56bf41fcf35960caf76e890f9 +--- + tensorflow/core/kernels/ragged_cross_op.cc | 30 ++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/tensorflow/core/kernels/ragged_cross_op.cc b/tensorflow/core/kernels/ragged_cross_op.cc +index ea65c0ee2b5b2..5dfe93f416659 100644 +--- a/tensorflow/core/kernels/ragged_cross_op.cc ++++ b/tensorflow/core/kernels/ragged_cross_op.cc +@@ -21,6 +21,7 @@ limitations under the License. + #include "tensorflow/core/framework/register_types.h" + #include "tensorflow/core/framework/tensor.h" + #include "tensorflow/core/framework/tensor_shape.h" ++#include "tensorflow/core/platform/errors.h" + #include "tensorflow/core/platform/fingerprint.h" + #include "tensorflow/core/util/util.h" + #include "tensorflow/core/util/work_sharder.h" +@@ -466,16 +467,45 @@ class RaggedCrossOp : public OpKernel { + int next_dense = 0; + for (char c : input_order_) { + if (c == 'R') { ++ if (next_ragged >= ragged_values_list.size()) ++ return errors::InvalidArgument( ++ "input_order \"", input_order_, ++ "\" specifies reading a ragged tensor value at index ", ++ next_ragged, " from a list of ", ragged_values_list.size(), ++ " values."); ++ if (next_ragged >= ragged_splits_list.size()) ++ return errors::InvalidArgument( ++ "input_order \"", input_order_, ++ "\" specifies reading a ragged tensor split at index ", ++ next_ragged, " from a list of ", ragged_splits_list.size(), ++ " splits."); + TF_RETURN_IF_ERROR(BuildRaggedFeatureReader( + ragged_values_list[next_ragged], ragged_splits_list[next_ragged], + features)); + next_ragged++; + } else if (c == 'S') { ++ if (next_sparse >= sparse_values_list.size()) ++ return errors::InvalidArgument( ++ "input_order \"", input_order_, ++ "\" specifies reading a sparse tensor value at index ", ++ next_sparse, " from a list of ", sparse_values_list.size(), ++ " values."); ++ if (next_sparse >= sparse_indices_list.size()) ++ return errors::InvalidArgument( ++ "input_order \"", input_order_, ++ "\" specifies reading a sparse tensor index at index ", ++ next_sparse, " from a list of ", sparse_indices_list.size(), ++ " indices."); + TF_RETURN_IF_ERROR(BuildSparseFeatureReader( + sparse_indices_list[next_sparse], sparse_values_list[next_sparse], + batch_size, features)); + next_sparse++; + } else if (c == 'D') { ++ if (next_dense >= dense_list.size()) ++ return errors::InvalidArgument( ++ "input_order \"", input_order_, ++ "\" specifies reading a dense tensor at index ", next_dense, ++ " from a list of ", dense_list.size(), " tensors."); + TF_RETURN_IF_ERROR( + BuildDenseFeatureReader(dense_list[next_dense++], features)); + } else { diff --git a/CVE-2021-29536.patch b/CVE-2021-29536.patch new file mode 100644 index 0000000000000000000000000000000000000000..7a8ebb2697877010fb170123391f1df4d20fade0 --- /dev/null +++ b/CVE-2021-29536.patch @@ -0,0 +1,57 @@ +From a324ac84e573fba362a5e53d4e74d5de6729933e Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 21 Apr 2021 18:11:15 -0700 +Subject: [PATCH] Validate arguments to `QuantizedReshape`. + +Ensure that validations from `Reshape` also terminate `QuantizedReshape` on failure. + +PiperOrigin-RevId: 369775421 +Change-Id: If8c5342267aceea65b7cb83a4b183304886f1ce8 +--- + .../core/kernels/quantized_reshape_op.cc | 25 +++++++++++++++++-- + 1 file changed, 23 insertions(+), 2 deletions(-) + +diff --git a/tensorflow/core/kernels/quantized_reshape_op.cc b/tensorflow/core/kernels/quantized_reshape_op.cc +index bd76c94edeea7..682f4aaa1f79e 100644 +--- a/tensorflow/core/kernels/quantized_reshape_op.cc ++++ b/tensorflow/core/kernels/quantized_reshape_op.cc +@@ -17,6 +17,7 @@ limitations under the License. + + #include "tensorflow/core/framework/op_kernel.h" + #include "tensorflow/core/framework/register_types.h" ++#include "tensorflow/core/framework/tensor_shape.h" + #include "tensorflow/core/framework/tensor_types.h" + #include "tensorflow/core/framework/types.h" + #include "tensorflow/core/kernels/reshape_op.h" +@@ -30,9 +31,29 @@ class QuantizedReshapeOp : public ReshapeOp { + void Compute(OpKernelContext* ctx) override { + // This call processes inputs 1 and 2 to write output 0. + ReshapeOp::Compute(ctx); ++ if (!ctx->status().ok()) { ++ return; ++ } ++ ++ const auto& input_min_float_tensor = ctx->input(2); ++ const auto& input_min_float_shape = input_min_float_tensor.shape(); ++ OP_REQUIRES(ctx, ++ TensorShapeUtils::IsScalar(input_min_float_shape) || ++ (TensorShapeUtils::IsVector(input_min_float_shape) && ++ (input_min_float_shape.dim_size(0) == 1)), ++ errors::InvalidArgument( ++ "input_min must be a scalar or a vector of 1 element")); ++ const float input_min_float = input_min_float_tensor.flat()(0); ++ const auto& input_max_float_tensor = ctx->input(3); ++ const auto& input_max_float_shape = input_max_float_tensor.shape(); ++ OP_REQUIRES(ctx, ++ TensorShapeUtils::IsScalar(input_max_float_shape) || ++ (TensorShapeUtils::IsVector(input_max_float_shape) && ++ (input_max_float_shape.dim_size(0) == 1)), ++ errors::InvalidArgument( ++ "input_max must be a scalar or a vector of 1 element")); ++ const float input_max_float = input_max_float_tensor.flat()(0); + +- const float input_min_float = ctx->input(2).flat()(0); +- const float input_max_float = ctx->input(3).flat()(0); + Tensor* output_min = nullptr; + OP_REQUIRES_OK(ctx, ctx->allocate_output(1, TensorShape({}), &output_min)); + output_min->flat()(0) = input_min_float; diff --git a/CVE-2021-29539.patch b/CVE-2021-29539.patch new file mode 100644 index 0000000000000000000000000000000000000000..232a727b1c7f48978fe6bb4498729466cd49ef1e --- /dev/null +++ b/CVE-2021-29539.patch @@ -0,0 +1,34 @@ +From 4f663d4b8f0bec1b48da6fa091a7d29609980fa4 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Mon, 8 Feb 2021 12:29:30 -0800 +Subject: [PATCH] Allowlist certain data types to avoid a seg fault. + +PiperOrigin-RevId: 356326671 +Change-Id: I23b65b52e93798cb5a6744632d31b0f88c6b6b31 +--- + tensorflow/core/kernels/immutable_constant_op.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/immutable_constant_op.cc b/tensorflow/core/kernels/immutable_constant_op.cc +index 1cfbdb8277891..19aa865c1fbe4 100644 +--- a/tensorflow/core/kernels/immutable_constant_op.cc ++++ b/tensorflow/core/kernels/immutable_constant_op.cc +@@ -17,6 +17,8 @@ limitations under the License. + + #include + ++#include "tensorflow/core/framework/types.pb.h" ++ + namespace tensorflow { + + namespace { +@@ -86,6 +88,9 @@ ImmutableConstantOp::ImmutableConstantOp(OpKernelConstruction* context) + OP_REQUIRES_OK(context, + context->GetAttr(kMemoryRegionNameAttr, ®ion_name_)); + OP_REQUIRES_OK(context, context->GetAttr(kDTypeAttr, &dtype_)); ++ OP_REQUIRES(context, dtype_ != DT_RESOURCE && dtype_ != DT_VARIANT, ++ errors::InvalidArgument( ++ "Resource and variant dtypes are invalid for this op.")); + OP_REQUIRES_OK(context, context->GetAttr(kShapeAttr, &shape_)); + } + diff --git a/CVE-2021-29541_CVE-2021-29542.patch b/CVE-2021-29541_CVE-2021-29542.patch new file mode 100644 index 0000000000000000000000000000000000000000..b19d31db78daf451960cab5bf51fd6b7773760c0 --- /dev/null +++ b/CVE-2021-29541_CVE-2021-29542.patch @@ -0,0 +1,133 @@ +From ba424dd8f16f7110eea526a8086f1a155f14f22b Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 22 Apr 2021 13:29:54 -0700 +Subject: [PATCH] Enhance validation of ngram op and handle case of 0 tokens. + +PiperOrigin-RevId: 369940178 +Change-Id: Ia82f42c09d14efe76e7dc013505b832a42282f0b +--- + tensorflow/core/kernels/string_ngrams_op.cc | 52 +++++++++++++++---- + .../core/kernels/string_ngrams_op_test.cc | 34 ++++++++++++ + 2 files changed, 75 insertions(+), 11 deletions(-) + +diff --git a/tensorflow/core/kernels/string_ngrams_op.cc b/tensorflow/core/kernels/string_ngrams_op.cc +index 8aed2b3831a2f..7008a1d766af2 100644 +--- a/tensorflow/core/kernels/string_ngrams_op.cc ++++ b/tensorflow/core/kernels/string_ngrams_op.cc +@@ -61,16 +61,28 @@ class StringNGramsOp : public tensorflow::OpKernel { + OP_REQUIRES_OK(context, context->input("data_splits", &splits)); + const auto& splits_vec = splits->flat(); + +- // Validate that the splits are valid indices into data ++ // Validate that the splits are valid indices into data, only if there are ++ // splits specified. + const int input_data_size = data->flat().size(); + const int splits_vec_size = splits_vec.size(); +- for (int i = 0; i < splits_vec_size; ++i) { +- bool valid_splits = splits_vec(i) >= 0; +- valid_splits = valid_splits && (splits_vec(i) <= input_data_size); +- OP_REQUIRES( +- context, valid_splits, +- errors::InvalidArgument("Invalid split value ", splits_vec(i), +- ", must be in [0,", input_data_size, "]")); ++ if (splits_vec_size > 0) { ++ int prev_split = splits_vec(0); ++ OP_REQUIRES(context, prev_split == 0, ++ errors::InvalidArgument("First split value must be 0, got ", ++ prev_split)); ++ for (int i = 1; i < splits_vec_size; ++i) { ++ bool valid_splits = splits_vec(i) >= prev_split; ++ valid_splits = valid_splits && (splits_vec(i) <= input_data_size); ++ OP_REQUIRES(context, valid_splits, ++ errors::InvalidArgument( ++ "Invalid split value ", splits_vec(i), ", must be in [", ++ prev_split, ", ", input_data_size, "]")); ++ prev_split = splits_vec(i); ++ } ++ OP_REQUIRES(context, prev_split == input_data_size, ++ errors::InvalidArgument( ++ "Last split value must be data size. Expected ", ++ input_data_size, ", got ", prev_split)); + } + + int num_batch_items = splits_vec.size() - 1; +@@ -174,13 +186,31 @@ class StringNGramsOp : public tensorflow::OpKernel { + ngram->append(left_pad_); + ngram->append(separator_); + } ++ // Only output first num_tokens - 1 pairs of data and separator + for (int n = 0; n < num_tokens - 1; ++n) { + ngram->append(data[data_start_index + n]); + ngram->append(separator_); + } +- ngram->append(data[data_start_index + num_tokens - 1]); +- for (int n = 0; n < right_padding; ++n) { +- ngram->append(separator_); ++ // Handle case when there are no tokens or no right padding as these can ++ // result in consecutive separators. ++ if (num_tokens > 0) { ++ // If we have tokens, then output last and then pair each separator with ++ // the right padding that follows, to ensure ngram ends either with the ++ // token or with the right pad. ++ ngram->append(data[data_start_index + num_tokens - 1]); ++ for (int n = 0; n < right_padding; ++n) { ++ ngram->append(separator_); ++ ngram->append(right_pad_); ++ } ++ } else { ++ // If we don't have tokens, then the last item inserted into the ngram ++ // has been the separator from the left padding loop above. Hence, ++ // output right pad and separator and make sure to finish with a ++ // padding, not a separator. ++ for (int n = 0; n < right_padding - 1; ++n) { ++ ngram->append(right_pad_); ++ ngram->append(separator_); ++ } + ngram->append(right_pad_); + } + +diff --git a/tensorflow/core/kernels/string_ngrams_op_test.cc b/tensorflow/core/kernels/string_ngrams_op_test.cc +index b89de9ad16dab..0d52283bd8fb9 100644 +--- a/tensorflow/core/kernels/string_ngrams_op_test.cc ++++ b/tensorflow/core/kernels/string_ngrams_op_test.cc +@@ -542,6 +542,40 @@ TEST_F(NgramKernelTest, TestEmptyInput) { + assert_int64_equal(expected_splits, *GetOutput(1)); + } + ++TEST_F(NgramKernelTest, TestNoTokens) { ++ MakeOp("|", {3}, "L", "R", -1, false); ++ // Batch items are: ++ // 0: ++ // 1: "a" ++ AddInputFromArray(TensorShape({1}), {"a"}); ++ AddInputFromArray(TensorShape({3}), {0, 0, 1}); ++ TF_ASSERT_OK(RunOpKernel()); ++ ++ std::vector expected_values( ++ {"L|L|R", "L|R|R", // no input in first split ++ "L|L|a", "L|a|R", "a|R|R"}); // second split ++ std::vector expected_splits({0, 2, 5}); ++ ++ assert_string_equal(expected_values, *GetOutput(0)); ++ assert_int64_equal(expected_splits, *GetOutput(1)); ++} ++ ++TEST_F(NgramKernelTest, TestNoTokensNoPad) { ++ MakeOp("|", {3}, "", "", 0, false); ++ // Batch items are: ++ // 0: ++ // 1: "a" ++ AddInputFromArray(TensorShape({1}), {"a"}); ++ AddInputFromArray(TensorShape({3}), {0, 0, 1}); ++ TF_ASSERT_OK(RunOpKernel()); ++ ++ std::vector expected_values({}); ++ std::vector expected_splits({0, 0, 0}); ++ ++ assert_string_equal(expected_values, *GetOutput(0)); ++ assert_int64_equal(expected_splits, *GetOutput(1)); ++} ++ + TEST_F(NgramKernelTest, ShapeFn) { + ShapeInferenceTestOp op("StringNGrams"); + INFER_OK(op, "?;?", "[?];[?]"); diff --git a/CVE-2021-29543.patch b/CVE-2021-29543.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f4b6dc916be4a36fef93133d2cd1105e494d9f2 --- /dev/null +++ b/CVE-2021-29543.patch @@ -0,0 +1,24 @@ +From ea3b43e98c32c97b35d52b4c66f9107452ca8fb2 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Thu, 22 Apr 2021 15:11:05 -0700 +Subject: [PATCH] Fix `tf.raw_ops.CTCGreedyDecoder` CHECK failure. + +PiperOrigin-RevId: 369960465 +Change-Id: If0b8b3264d5a47a24ac0970ed7b81ce6b4921fae +--- + tensorflow/core/kernels/ctc_decoder_ops.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/ctc_decoder_ops.cc b/tensorflow/core/kernels/ctc_decoder_ops.cc +index d62aef2d03b98..22681f97437f0 100644 +--- a/tensorflow/core/kernels/ctc_decoder_ops.cc ++++ b/tensorflow/core/kernels/ctc_decoder_ops.cc +@@ -232,6 +232,8 @@ class CTCGreedyDecoderOp : public OpKernel { + int prev_indices = -1; + for (int t = 0; t < seq_len_t(b); ++t) { + int max_class_indices; ++ OP_REQUIRES(ctx, input_list_t[t].dimension(1) > 0, ++ errors::InvalidArgument("Invalid input dimensions.")); + log_prob_t(b, 0) += + -RowMax(input_list_t[t], b, &max_class_indices); + if (max_class_indices != blank_index && diff --git a/CVE-2021-29545.patch b/CVE-2021-29545.patch new file mode 100644 index 0000000000000000000000000000000000000000..34848241eaee9da2a06c25b1b3d915ebc81cc36a --- /dev/null +++ b/CVE-2021-29545.patch @@ -0,0 +1,35 @@ +From 1e922ccdf6bf46a3a52641f99fd47d54c1decd13 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 23 Apr 2021 10:41:12 -0700 +Subject: [PATCH] Fix crash in `SparseTensorToCSRSparseMatrixCPUFunctor` + +PiperOrigin-RevId: 370110290 +Change-Id: I4451e92661a55c2180f80d38b67a9b50bf5edec5 +--- + tensorflow/core/kernels/sparse/kernels.cc | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tensorflow/core/kernels/sparse/kernels.cc b/tensorflow/core/kernels/sparse/kernels.cc +index 0eea9f1feed5c..dff9aeb83ccfe 100644 +--- a/tensorflow/core/kernels/sparse/kernels.cc ++++ b/tensorflow/core/kernels/sparse/kernels.cc +@@ -22,6 +22,7 @@ limitations under the License. + #include "tensorflow/core/framework/tensor_types.h" + #include "tensorflow/core/lib/core/errors.h" + #include "tensorflow/core/lib/core/status.h" ++#include "tensorflow/core/platform/errors.h" + + namespace tensorflow { + namespace functor { +@@ -63,6 +64,11 @@ Status SparseTensorToCSRSparseMatrixCPUFunctor::operator()( + + for (int64 i = 0; i < total_nnz; ++i) { + // For now, the rows pointers store the corresponding row counts. ++ int64 ix = indices(i, 0) + 1; ++ if (ix >= csr_row_ptr.size()) { ++ return errors::InvalidArgument("Got an index ", ix, ++ " that is outside of csr_row_ptr"); ++ } + csr_row_ptr(indices(i, 0) + 1) += 1; + csr_col_ind(i) = indices(i, 1); + } diff --git a/CVE-2021-29546.patch b/CVE-2021-29546.patch new file mode 100644 index 0000000000000000000000000000000000000000..11671fb6411346f3afa9f671388e46cce963f530 --- /dev/null +++ b/CVE-2021-29546.patch @@ -0,0 +1,24 @@ +From 67784700869470d65d5f2ef20aeb5e97c31673cb Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 23 Apr 2021 11:11:39 -0700 +Subject: [PATCH] Prevent division by 0 in `QuantizedBiasAdd`. + +PiperOrigin-RevId: 370117454 +Change-Id: I3804e2ac8dcc6d3afcc92e27853e2325a017ca4d +--- + tensorflow/core/kernels/quantized_bias_add_op.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/quantized_bias_add_op.cc b/tensorflow/core/kernels/quantized_bias_add_op.cc +index 5457d290c2559..db0e21a498011 100644 +--- a/tensorflow/core/kernels/quantized_bias_add_op.cc ++++ b/tensorflow/core/kernels/quantized_bias_add_op.cc +@@ -56,6 +56,8 @@ class QuantizedBiasAddOp : public OpKernel { + "Must provide as many biases as the last dimension " + "of the input tensor: ", + bias.shape().DebugString(), " vs. ", input.shape().DebugString())); ++ OP_REQUIRES(context, bias.NumElements() > 0, ++ errors::InvalidArgument("Must provide at least 1 bias")); + + Tensor* output = nullptr; + OP_REQUIRES_OK(context, diff --git a/CVE-2021-29547.patch b/CVE-2021-29547.patch new file mode 100644 index 0000000000000000000000000000000000000000..a0a11a31a6114d885e12d4fd1d83d52fd903a43c --- /dev/null +++ b/CVE-2021-29547.patch @@ -0,0 +1,111 @@ +From d6ed5bcfe1dcab9e85a4d39931bd18d99018e75b Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 23 Apr 2021 11:40:06 -0700 +Subject: [PATCH] Add missing validation in + `QuantizedBatchNormWithGlobalNormalization` + +PiperOrigin-RevId: 370123451 +Change-Id: Id234d6dab1ec21230bb8e503dba30f899af87f33 +--- + .../core/kernels/quantized_batch_norm_op.cc | 77 ++++++++++++++++--- + 1 file changed, 67 insertions(+), 10 deletions(-) + +diff --git a/tensorflow/core/kernels/quantized_batch_norm_op.cc b/tensorflow/core/kernels/quantized_batch_norm_op.cc +index b03da7ad17fab..6dfe07f97a400 100644 +--- a/tensorflow/core/kernels/quantized_batch_norm_op.cc ++++ b/tensorflow/core/kernels/quantized_batch_norm_op.cc +@@ -173,20 +173,50 @@ class QuantizedBatchNormOp : public OpKernel { + + void Compute(OpKernelContext* context) override { + const Tensor& input = context->input(0); +- const float input_min = context->input(1).flat()(0); +- const float input_max = context->input(2).flat()(0); ++ const auto& input_min_tensor = context->input(1); ++ OP_REQUIRES(context, input_min_tensor.NumElements() == 1, ++ errors::InvalidArgument("input_min must have 1 element")); ++ const float input_min = input_min_tensor.flat()(0); ++ const auto& input_max_tensor = context->input(2); ++ OP_REQUIRES(context, input_max_tensor.NumElements() == 1, ++ errors::InvalidArgument("input_max must have 1 element")); ++ const float input_max = input_max_tensor.flat()(0); + const Tensor& mean = context->input(3); +- const float mean_min = context->input(4).flat()(0); +- const float mean_max = context->input(5).flat()(0); ++ const auto& mean_min_tensor = context->input(4); ++ OP_REQUIRES(context, mean_min_tensor.NumElements() == 1, ++ errors::InvalidArgument("mean_min must have 1 element")); ++ const float mean_min = mean_min_tensor.flat()(0); ++ const auto& mean_max_tensor = context->input(5); ++ OP_REQUIRES(context, mean_max_tensor.NumElements() == 1, ++ errors::InvalidArgument("mean_max must have 1 element")); ++ const float mean_max = mean_max_tensor.flat()(0); + const Tensor& var = context->input(6); +- const float var_min = context->input(7).flat()(0); +- const float var_max = context->input(8).flat()(0); ++ const auto& var_min_tensor = context->input(7); ++ OP_REQUIRES(context, var_min_tensor.NumElements() == 1, ++ errors::InvalidArgument("var_min must have 1 element")); ++ const float var_min = var_min_tensor.flat()(0); ++ const auto& var_max_tensor = context->input(8); ++ OP_REQUIRES(context, var_max_tensor.NumElements() == 1, ++ errors::InvalidArgument("var_max must have 1 element")); ++ const float var_max = var_max_tensor.flat()(0); + const Tensor& beta = context->input(9); +- const float beta_min = context->input(10).flat()(0); +- const float beta_max = context->input(11).flat()(0); ++ const auto& beta_min_tensor = context->input(10); ++ OP_REQUIRES(context, beta_min_tensor.NumElements() == 1, ++ errors::InvalidArgument("beta_min must have 1 element")); ++ const float beta_min = beta_min_tensor.flat()(0); ++ const auto& beta_max_tensor = context->input(11); ++ OP_REQUIRES(context, beta_max_tensor.NumElements() == 1, ++ errors::InvalidArgument("beta_max must have 1 element")); ++ const float beta_max = beta_max_tensor.flat()(0); + const Tensor& gamma = context->input(12); +- const float gamma_min = context->input(13).flat()(0); +- const float gamma_max = context->input(14).flat()(0); ++ const auto& gamma_min_tensor = context->input(13); ++ OP_REQUIRES(context, gamma_min_tensor.NumElements() == 1, ++ errors::InvalidArgument("gamma_min must have 1 element")); ++ const float gamma_min = gamma_min_tensor.flat()(0); ++ const auto& gamma_max_tensor = context->input(14); ++ OP_REQUIRES(context, gamma_max_tensor.NumElements() == 1, ++ errors::InvalidArgument("gamma_max must have 1 element")); ++ const float gamma_max = gamma_max_tensor.flat()(0); + + OP_REQUIRES(context, input.dims() == 4, + errors::InvalidArgument("input must be 4-dimensional", +@@ -203,6 +233,33 @@ class QuantizedBatchNormOp : public OpKernel { + OP_REQUIRES(context, gamma.dims() == 1, + errors::InvalidArgument("gamma must be 1-dimensional", + gamma.shape().DebugString())); ++ OP_REQUIRES(context, mean.NumElements() > 1, ++ errors::InvalidArgument("Must have at least a mean value", ++ gamma.shape().DebugString())); ++ OP_REQUIRES(context, mean.NumElements() > 1, ++ errors::InvalidArgument("Must have at least a mean value")); ++ const auto last_dim = input.shape().dims() - 1; ++ OP_REQUIRES(context, ++ mean.shape().dim_size(0) == input.shape().dim_size(last_dim), ++ errors::InvalidArgument("Must provide as many means as the " ++ "last dimension of the input tensor: ", ++ mean.shape().DebugString(), " vs. ", ++ input.shape().DebugString())); ++ OP_REQUIRES( ++ context, mean.shape().dim_size(0) == var.shape().dim_size(0), ++ errors::InvalidArgument( ++ "Mean and variance tensors must have the same shape: ", ++ mean.shape().DebugString(), " vs. ", var.shape().DebugString())); ++ OP_REQUIRES( ++ context, mean.shape().dim_size(0) == beta.shape().dim_size(0), ++ errors::InvalidArgument( ++ "Mean and beta tensors must have the same shape: ", ++ mean.shape().DebugString(), " vs. ", beta.shape().DebugString())); ++ OP_REQUIRES( ++ context, mean.shape().dim_size(0) == gamma.shape().dim_size(0), ++ errors::InvalidArgument( ++ "Mean and gamma tensors must have the same shape: ", ++ mean.shape().DebugString(), " vs. ", gamma.shape().DebugString())); + + Tensor* output = nullptr; + OP_REQUIRES_OK(context, diff --git a/CVE-2021-29549.patch b/CVE-2021-29549.patch new file mode 100644 index 0000000000000000000000000000000000000000..49cf2de5fc13172a059fd3b309f76e8ad887d933 --- /dev/null +++ b/CVE-2021-29549.patch @@ -0,0 +1,24 @@ +From 744009c9e5cc5d0447f0dc39d055f917e1fd9e16 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 23 Apr 2021 12:00:12 -0700 +Subject: [PATCH] Validate work in `QuantizedAdd`, ensure at least one element. + +PiperOrigin-RevId: 370127996 +Change-Id: I57c6f3e01afdeada84737820a131590137463855 +--- + tensorflow/core/kernels/quantized_add_op.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/quantized_add_op.cc b/tensorflow/core/kernels/quantized_add_op.cc +index 55c69de7d3ea6..b186f00f15c06 100644 +--- a/tensorflow/core/kernels/quantized_add_op.cc ++++ b/tensorflow/core/kernels/quantized_add_op.cc +@@ -538,6 +538,8 @@ class QuantizedAddOp : public OpKernel { + tensor_min = min_x; + tensor_max = max_x; + } ++ OP_REQUIRES(context, vector_num_elements > 0, ++ errors::InvalidArgument("Must have some elements to add")); + VectorTensorAddition( + vector_data, vector_min, vector_max, vector_num_elements, tensor_data, + tensor_min, tensor_max, tensor_num_elements, min_z_value, max_z_value, diff --git a/CVE-2021-29550.patch b/CVE-2021-29550.patch new file mode 100644 index 0000000000000000000000000000000000000000..15199669305c2f71fd30a49b3bc3af957f6a084c --- /dev/null +++ b/CVE-2021-29550.patch @@ -0,0 +1,26 @@ +From 548b5eaf23685d86f722233d8fbc21d0a4aecb96 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Thu, 29 Apr 2021 08:38:16 -0700 +Subject: [PATCH] Fix divide by zero error in `fractional_pool_common.cc`. + +PiperOrigin-RevId: 371126221 +Change-Id: Iea4b2f363aaeb116ab460e3bc592c687484af344 +--- + tensorflow/core/kernels/fractional_avg_pool_op.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/fractional_avg_pool_op.cc b/tensorflow/core/kernels/fractional_avg_pool_op.cc +index dfc2382624e3f..b8a5083e5340f 100644 +--- a/tensorflow/core/kernels/fractional_avg_pool_op.cc ++++ b/tensorflow/core/kernels/fractional_avg_pool_op.cc +@@ -80,6 +80,10 @@ class FractionalAvgPoolOp : public OpKernel { + std::vector output_size(tensor_in_and_out_dims); + for (int i = 0; i < tensor_in_and_out_dims; ++i) { + input_size[i] = tensor_in.dim_size(i); ++ OP_REQUIRES( ++ context, pooling_ratio_[i] <= input_size[i], ++ errors::InvalidArgument( ++ "Pooling ratio cannot be bigger than input tensor dim size.")); + } + // Output size. + for (int i = 0; i < tensor_in_and_out_dims; ++i) { diff --git a/CVE-2021-29552.patch b/CVE-2021-29552.patch new file mode 100644 index 0000000000000000000000000000000000000000..edf7c9207559195a48f950abc69cfe3dcf59de61 --- /dev/null +++ b/CVE-2021-29552.patch @@ -0,0 +1,25 @@ +From 704866eabe03a9aeda044ec91a8d0c83fc1ebdbe Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Tue, 27 Apr 2021 14:41:40 -0700 +Subject: [PATCH] Fix overflow CHECK issue with + `tf.raw_ops.UnsortedSegmentJoin`. + +PiperOrigin-RevId: 370766155 +Change-Id: I33e7c6626224e1060a8a4ab51ad5d861c6d4c63e +--- + tensorflow/core/kernels/unsorted_segment_join_op.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/unsorted_segment_join_op.cc b/tensorflow/core/kernels/unsorted_segment_join_op.cc +index 7464e165e46c8..9acfe7fb1e495 100644 +--- a/tensorflow/core/kernels/unsorted_segment_join_op.cc ++++ b/tensorflow/core/kernels/unsorted_segment_join_op.cc +@@ -90,6 +90,8 @@ class UnsortedSegmentJoinOp : public OpKernel { + const int32 segment_dims = segment_id_shape.dims(); + + const Tensor& num_segments_tensor = context->input(2); ++ OP_REQUIRES(context, num_segments_tensor.NumElements() != 0, ++ errors::InvalidArgument("Number of segments cannot be empty.")); + auto num_segments = num_segments_tensor.scalar()(); + + OP_REQUIRES(context, segment_dims != 0, diff --git a/CVE-2021-29553.patch b/CVE-2021-29553.patch new file mode 100644 index 0000000000000000000000000000000000000000..437e2d98ab6c831c2fe11aa05894783f1a332987 --- /dev/null +++ b/CVE-2021-29553.patch @@ -0,0 +1,34 @@ +From 99085e8ff02c3763a0ec2263e44daec416f6a387 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Mon, 26 Apr 2021 17:32:41 -0700 +Subject: [PATCH] Fix `tf.raw_ops.QuantizeAndDequantizeV3` array index failure. + +PiperOrigin-RevId: 370577691 +Change-Id: Ifeae64212f6bcd139435824fa2748d1329213c4c +--- + tensorflow/core/kernels/quantize_and_dequantize_op.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/quantize_and_dequantize_op.cc b/tensorflow/core/kernels/quantize_and_dequantize_op.cc +index c2a7a90d8713d..f01a70114591b 100644 +--- a/tensorflow/core/kernels/quantize_and_dequantize_op.cc ++++ b/tensorflow/core/kernels/quantize_and_dequantize_op.cc +@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and + limitations under the License. + ==============================================================================*/ + ++#include "tensorflow/core/framework/op_requires.h" + #define EIGEN_USE_THREADS + + #if (defined(GOOGLE_CUDA) && GOOGLE_CUDA) || \ +@@ -234,6 +235,10 @@ class QuantizeAndDequantizeV3Op : public OpKernel { + + void Compute(OpKernelContext* ctx) override { + const Tensor& input = ctx->input(0); ++ OP_REQUIRES(ctx, axis_ < input.dims(), ++ errors::InvalidArgument( ++ "Axis requested is larger than input dimensions. Axis: ", ++ axis_, " Input Dimensions: ", input.dims())); + const int depth = (axis_ == -1) ? 1 : input.dim_size(axis_); + Tensor* output = nullptr; + OP_REQUIRES_OK(ctx, ctx->allocate_output(0, input.shape(), &output)); diff --git a/CVE-2021-29554.patch b/CVE-2021-29554.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1d8c5e28dbbd13a45cfa979b98a356d3ebe80b0 --- /dev/null +++ b/CVE-2021-29554.patch @@ -0,0 +1,25 @@ +From da5ff2daf618591f64b2b62d9d9803951b945e9f Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Wed, 28 Apr 2021 11:24:45 -0700 +Subject: [PATCH] Fix FPE issue with `tf.raw_ops.DenseCountSparseOutput`. + +PiperOrigin-RevId: 370946862 +Change-Id: I3752584ad04aaecb327ff6793a9640ac56acfe7a +--- + tensorflow/core/kernels/count_ops.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/count_ops.cc b/tensorflow/core/kernels/count_ops.cc +index eeb0b853c7aad..40aa1fe458c1e 100644 +--- a/tensorflow/core/kernels/count_ops.cc ++++ b/tensorflow/core/kernels/count_ops.cc +@@ -122,6 +122,9 @@ class DenseCount : public OpKernel { + + int num_batch_elements = 1; + for (int i = 0; i < num_batch_dimensions; ++i) { ++ OP_REQUIRES(context, data.shape().dim_size(i) != 0, ++ errors::InvalidArgument( ++ "Invalid input: Shapes dimension cannot be 0.")); + num_batch_elements *= data.shape().dim_size(i); + } + int num_value_elements = data.shape().num_elements() / num_batch_elements; diff --git a/CVE-2021-29555.patch b/CVE-2021-29555.patch new file mode 100644 index 0000000000000000000000000000000000000000..35dc4c00830aa44cea0f5cb95022eaeb55bc2023 --- /dev/null +++ b/CVE-2021-29555.patch @@ -0,0 +1,25 @@ +From 1a2a87229d1d61e23a39373777c056161eb4084d Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Wed, 28 Apr 2021 11:30:28 -0700 +Subject: [PATCH] Fix FPE issue with `tf.raw_ops.FusedBatchNorm`. + +PiperOrigin-RevId: 370948185 +Change-Id: If0c8e0320062ed6363e94ff5fe38e6a301f69ac2 +--- + tensorflow/core/kernels/fused_batch_norm_op.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/fused_batch_norm_op.cc b/tensorflow/core/kernels/fused_batch_norm_op.cc +index 9b917348e2afa..e564b19857c38 100644 +--- a/tensorflow/core/kernels/fused_batch_norm_op.cc ++++ b/tensorflow/core/kernels/fused_batch_norm_op.cc +@@ -293,6 +293,9 @@ struct FusedBatchNorm { + const CPUDevice& d = context->eigen_device(); + + const int depth = x.dimension(3); ++ OP_REQUIRES( ++ context, depth != 0, ++ errors::Internal("The 4th element in the input shape cannot be 0.")); + const int size = x.size(); + const int rest_size = size / depth; + Eigen::DSizes rest_by_depth(rest_size, depth); diff --git a/CVE-2021-29556.patch b/CVE-2021-29556.patch new file mode 100644 index 0000000000000000000000000000000000000000..8e69d458dff51f9eb2b66b3460d0edae3ee20b04 --- /dev/null +++ b/CVE-2021-29556.patch @@ -0,0 +1,28 @@ +From 4071d8e2f6c45c1955a811fee757ca2adbe462c1 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Thu, 29 Apr 2021 12:24:18 -0700 +Subject: [PATCH] Fix FPE issue with `tf.raw_ops.Reverse`. + +PiperOrigin-RevId: 371176973 +Change-Id: Ic6d483bfc95313ec2299c2d1c956cfe96c96626c +--- + tensorflow/core/kernels/reverse_op.cc | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tensorflow/core/kernels/reverse_op.cc b/tensorflow/core/kernels/reverse_op.cc +index 5555a141b6c7b..560fac7133667 100644 +--- a/tensorflow/core/kernels/reverse_op.cc ++++ b/tensorflow/core/kernels/reverse_op.cc +@@ -155,6 +155,12 @@ class ReverseOp : public OpKernel { + + void Compute(OpKernelContext* context) override { + const Tensor& input = context->input(0); ++ // If input is provided, check to make sure the first dimension is valid. ++ if (input.dims() > 0) { ++ OP_REQUIRES( ++ context, input.dim_size(0) != 0, ++ errors::InvalidArgument("Invalid input first dimension. Found 0.")); ++ } + const Tensor& dims = context->input(1); + + if (TensorShapeUtils::IsScalar(input.shape())) { diff --git a/CVE-2021-29557.patch b/CVE-2021-29557.patch new file mode 100644 index 0000000000000000000000000000000000000000..2fdc57b51d3d340321fda74e2f90302a7d984d4f --- /dev/null +++ b/CVE-2021-29557.patch @@ -0,0 +1,27 @@ +From 7f283ff806b2031f407db64c4d3edcda8fb9f9f5 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Wed, 28 Apr 2021 15:00:39 -0700 +Subject: [PATCH] Fix FPE issue in external Eigen source code issue with + `tf.raw_ops.SparseMatMul`. + +PiperOrigin-RevId: 370992919 +Change-Id: Icfb276fef5fb40928b27c3e44608d2aca72c9fd7 +--- + tensorflow/core/kernels/sparse_matmul_op.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/sparse_matmul_op.cc b/tensorflow/core/kernels/sparse_matmul_op.cc +index f5747854093c9..a02afafa33e3a 100644 +--- a/tensorflow/core/kernels/sparse_matmul_op.cc ++++ b/tensorflow/core/kernels/sparse_matmul_op.cc +@@ -1039,6 +1039,10 @@ class SparseMatMulOp : public OpKernel { + if (transpose_b) { + // TODO(agarwal): avoid transposing the matrix here and directly handle + // transpose in CreateDenseSlices. ++ OP_REQUIRES(ctx, right->dim_size(0) != 0, ++ errors::InvalidArgument("b has an entry 0 in it's shape.")); ++ OP_REQUIRES(ctx, right->dim_size(1) != 0, ++ errors::InvalidArgument("b has an entry 0 in it's shape.")); + right_tr.reset( + new Tensor(right->dtype(), + TensorShape({right->dim_size(1), right->dim_size(0)}))); diff --git a/CVE-2021-29558.patch b/CVE-2021-29558.patch new file mode 100644 index 0000000000000000000000000000000000000000..86f60311f14fa01d302be25ab7571fc23fc8706f --- /dev/null +++ b/CVE-2021-29558.patch @@ -0,0 +1,26 @@ +From 8ba6fa29cd8bf9cef9b718dc31c78c73081f5b31 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Thu, 29 Apr 2021 17:58:08 -0700 +Subject: [PATCH] Fix heap-buffer-overflow issue with `tf.raw_ops.SparseSplit`. + +PiperOrigin-RevId: 371242872 +Change-Id: I482bb3d12602c7c3cc9446f97fb9f584bb98e9a4 +--- + tensorflow/core/util/sparse/sparse_tensor.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/util/sparse/sparse_tensor.h b/tensorflow/core/util/sparse/sparse_tensor.h +index 062226d7699bc..341290dbbc698 100644 +--- a/tensorflow/core/util/sparse/sparse_tensor.h ++++ b/tensorflow/core/util/sparse/sparse_tensor.h +@@ -527,6 +527,10 @@ inline Status SparseTensor::Split(const SparseTensor& input_tensor, + for (int i = 0; i < input_tensor.indices().dim_size(0); ++i) { + const int dim = input_tensor.indices().matrix()(i, split_dim); + int slice_index = GetSliceIndex(dim, split_size, residual); ++ if (slice_index >= num_values.size()) { ++ return errors::InvalidArgument("Slice index ", slice_index, ++ " is larger than num_split."); ++ } + num_values[slice_index]++; + } + diff --git a/CVE-2021-29559.patch b/CVE-2021-29559.patch new file mode 100644 index 0000000000000000000000000000000000000000..25c2e496d3976c3777ede66b46e01f0de0a1b3c5 --- /dev/null +++ b/CVE-2021-29559.patch @@ -0,0 +1,48 @@ +From 51300ba1cc2f487aefec6e6631fef03b0e08b298 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Mon, 3 May 2021 09:53:26 -0700 +Subject: [PATCH] Fix heap buffer overflow in tf.raw_ops.UnicodeEncode. + +PiperOrigin-RevId: 371717714 +Change-Id: If33443b28f158e58078f1268f6b92f2728d219e0 +--- + tensorflow/core/kernels/unicode_ops.cc | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/tensorflow/core/kernels/unicode_ops.cc b/tensorflow/core/kernels/unicode_ops.cc +index d3a7ad7b2866f..e6c8f4dfc4228 100644 +--- a/tensorflow/core/kernels/unicode_ops.cc ++++ b/tensorflow/core/kernels/unicode_ops.cc +@@ -533,6 +533,17 @@ class UnicodeEncodeOp : public OpKernel { + const Tensor& input_splits = context->input(1); + const auto input_splits_flat = input_splits.flat(); + ++ // Operation will treat first argument in input_splits as if it were zero ++ // regardless of its actual value since splits should begin with zero and ++ // end with the length of the input values vector. ++ OP_REQUIRES( ++ context, input_splits_flat(0) == 0, ++ errors::InvalidArgument("First value in input_splits must be zero.")); ++ OP_REQUIRES(context, ++ input_splits_flat(input_splits_flat.size() - 1) == ++ input_tensor_flat.size(), ++ errors::InvalidArgument("Last value in input_splits must be " ++ "equal to length of input_tensor.")); + // Since we limit to a 2-D input (flat_values of rank 1 and a single splits + // tensor), our output dimension will be 1 with it's size equal to the + // number of splits (outer dimension or ragged tensor). +@@ -548,6 +559,14 @@ class UnicodeEncodeOp : public OpKernel { + for (int i = 1; i < input_splits_flat.size(); ++i) { + icu::UnicodeString unicode_string; + icu::UnicodeStringAppendable appendable_unicode_string(unicode_string); ++ OP_REQUIRES( ++ context, input_splits_flat(i - 1) <= input_splits_flat(i), ++ errors::InvalidArgument( ++ "Values in input_splits must be equal or in ascending order.")); ++ OP_REQUIRES( ++ context, input_splits_flat(i) <= input_tensor_flat.size(), ++ errors::InvalidArgument("Values in input_splits must be less than or " ++ "equal to input_tensor length.")); + for (; idx < input_splits_flat(i); ++idx) { + int32 code_point = input_tensor_flat(idx); + // Check for invalid code point diff --git a/CVE-2021-29561.patch b/CVE-2021-29561.patch new file mode 100644 index 0000000000000000000000000000000000000000..e5c870cbd56c27a5e6ab53246260a7ab7d6d2c6f --- /dev/null +++ b/CVE-2021-29561.patch @@ -0,0 +1,27 @@ +From 77dd114513d7796e1e2b8aece214a380af26fbf4 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 4 May 2021 15:46:30 -0700 +Subject: [PATCH] Fix a check fail + +PiperOrigin-RevId: 372011072 +Change-Id: I1062cfaed0aa16884e9a16312483794d188db76f +--- + tensorflow/core/kernels/load_and_remap_matrix_op.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/load_and_remap_matrix_op.cc b/tensorflow/core/kernels/load_and_remap_matrix_op.cc +index cb0245a9b6126..5ec28c7035813 100644 +--- a/tensorflow/core/kernels/load_and_remap_matrix_op.cc ++++ b/tensorflow/core/kernels/load_and_remap_matrix_op.cc +@@ -123,6 +123,11 @@ class LoadAndRemapMatrixOp : public OpKernel { + // Processes the checkpoint source and the provided Tensor name. + const Tensor* ckpt_path_t; + OP_REQUIRES_OK(context, context->input("ckpt_path", &ckpt_path_t)); ++ OP_REQUIRES( ++ context, ckpt_path_t->NumElements() == 1, ++ errors::InvalidArgument("The `ckpt_path` tensor must have exactly one " ++ "element, got tensor of shape ", ++ ckpt_path_t->shape().DebugString())); + const string& ckpt_path = ckpt_path_t->scalar()(); + const Tensor* old_tensor_name_t; + OP_REQUIRES_OK(context, diff --git a/CVE-2021-29562.patch b/CVE-2021-29562.patch new file mode 100644 index 0000000000000000000000000000000000000000..e84b2ecc05da2a79372d3cb9444b347903186130 --- /dev/null +++ b/CVE-2021-29562.patch @@ -0,0 +1,33 @@ +From 1c56f53be0b722ca657cbc7df461ed676c8642a2 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 4 May 2021 17:11:46 -0700 +Subject: [PATCH] Fix a check fail in Fast Fourier implementation + +PiperOrigin-RevId: 372026629 +Change-Id: Id05c3362aa575271bc3e06b16316c9037085fc11 +--- + tensorflow/core/kernels/fft_ops.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/fft_ops.cc b/tensorflow/core/kernels/fft_ops.cc +index c3235c1547ff0..29ca0d2f546a0 100644 +--- a/tensorflow/core/kernels/fft_ops.cc ++++ b/tensorflow/core/kernels/fft_ops.cc +@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and + limitations under the License. + ==============================================================================*/ + ++#include "tensorflow/core/platform/errors.h" + #define EIGEN_USE_THREADS + + // See docs in ../ops/fft_ops.cc. +@@ -261,6 +262,9 @@ class FFTCPU : public FFTBase { + i == FFTRank ? fft_shape[i - 1] / 2 + 1 : fft_shape[i - 1]; + full_fft_shape.AddDim(fft_shape[i - 1]); + } ++ OP_REQUIRES(ctx, full_fft_shape.num_elements() > 0, ++ errors::InvalidArgument("Obtained a FFT shape of 0 elements: ", ++ full_fft_shape.DebugString())); + + Tensor temp; + OP_REQUIRES_OK(ctx, ctx->allocate_temp(DataTypeToEnum::v(), diff --git a/CVE-2021-29563.patch b/CVE-2021-29563.patch new file mode 100644 index 0000000000000000000000000000000000000000..22e59265f090344930eb68fb8ce70a6393d2a69e --- /dev/null +++ b/CVE-2021-29563.patch @@ -0,0 +1,25 @@ +From 31bd5026304677faa8a0b77602c6154171b9aec1 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 4 May 2021 17:42:54 -0700 +Subject: [PATCH] Prevent check fail in FFT + +PiperOrigin-RevId: 372031044 +Change-Id: I50994e3e8a5d1342d01bde80256f6bf2730ca299 +--- + tensorflow/core/kernels/fft_ops.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/fft_ops.cc b/tensorflow/core/kernels/fft_ops.cc +index 29ca0d2f546a0..fc29f49d223be 100644 +--- a/tensorflow/core/kernels/fft_ops.cc ++++ b/tensorflow/core/kernels/fft_ops.cc +@@ -222,6 +222,9 @@ class FFTCPU : public FFTBase { + input_slice_sizes[i] = fft_shape[i - 1]; + temp_shape.AddDim(fft_shape[i - 1]); + } ++ OP_REQUIRES(ctx, temp_shape.num_elements() > 0, ++ errors::InvalidArgument("Obtained a FFT shape of 0 elements: ", ++ temp_shape.DebugString())); + + auto output = out->flat_inner_dims(); + const Eigen::DSizes zero_start_indices; diff --git a/CVE-2021-29564.patch b/CVE-2021-29564.patch new file mode 100644 index 0000000000000000000000000000000000000000..4b135e591c7fa0286ccc707c8b25b5c20bc11d99 --- /dev/null +++ b/CVE-2021-29564.patch @@ -0,0 +1,118 @@ +From f4c364a5d6880557f6f5b6eb5cee2c407f0186b3 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 4 May 2021 18:06:03 -0700 +Subject: [PATCH] Fix multiple issues in EditDistance + +PiperOrigin-RevId: 372033948 +Change-Id: Ieb957c29894af05bdfeb1a0402fced808dfcfd7b +--- + tensorflow/core/kernels/edit_distance_op.cc | 47 +++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/tensorflow/core/kernels/edit_distance_op.cc b/tensorflow/core/kernels/edit_distance_op.cc +index 4aecdc9e414d3..386a1af08409f 100644 +--- a/tensorflow/core/kernels/edit_distance_op.cc ++++ b/tensorflow/core/kernels/edit_distance_op.cc +@@ -64,6 +64,12 @@ Status ValidateShapes(OpKernelContext* ctx, const Tensor& hypothesis_indices, + return errors::InvalidArgument( + "truth_shape should be a vector, but got shape: ", + truth_shape.shape().DebugString()); ++ if (hypothesis_values.NumElements() != hypothesis_indices.dim_size(0)) ++ return errors::InvalidArgument( ++ "Expected hypothesis_values.NumElements == " ++ "#rows(hypothesis_indices), their shapes are: ", ++ hypothesis_values.shape().DebugString(), " and ", ++ hypothesis_indices.shape().DebugString()); + if (hypothesis_shape.NumElements() != hypothesis_indices.dim_size(1)) + return errors::InvalidArgument( + "Expected hypothesis_shape.NumElements == " +@@ -75,6 +81,12 @@ Status ValidateShapes(OpKernelContext* ctx, const Tensor& hypothesis_indices, + "Input SparseTensors must have rank at least 2, but truth_shape " + "rank is: ", + truth_shape.NumElements()); ++ if (truth_values.NumElements() != truth_indices.dim_size(0)) ++ return errors::InvalidArgument( ++ "Expected truth_values.NumElements == " ++ "#rows(truth_indices), their shapes are: ", ++ truth_values.shape().DebugString(), " and ", ++ truth_indices.shape().DebugString()); + if (truth_shape.NumElements() != truth_indices.dim_size(1)) + return errors::InvalidArgument( + "Expected truth_shape.NumElements == " +@@ -153,6 +165,11 @@ class EditDistanceOp : public OpKernel { + output_shape.AddDim(std::max(hypothesis_st_shape.dim_size(d), + truth_st_shape.dim_size(d))); + } ++ const auto output_elements = output_shape.num_elements(); ++ OP_REQUIRES( ++ ctx, output_elements > 0, ++ errors::InvalidArgument("Got output shape ", output_shape.DebugString(), ++ " which has 0 elements")); + + Tensor* output = nullptr; + OP_REQUIRES_OK(ctx, ctx->allocate_output("output", output_shape, &output)); +@@ -185,6 +202,12 @@ class EditDistanceOp : public OpKernel { + if (g_truth == g_hypothesis) { + auto loc = std::inner_product(g_truth.begin(), g_truth.end(), + output_strides.begin(), int64{0}); ++ OP_REQUIRES( ++ ctx, loc < output_elements, ++ errors::Internal("Got an inner product ", loc, ++ " which would require in writing to outside of " ++ "the buffer for the output tensor (max elements ", ++ output_elements, ")")); + output_t(loc) = + gtl::LevenshteinDistance(truth_seq, hypothesis_seq, cmp); + if (normalize_) output_t(loc) /= truth_seq.size(); +@@ -194,6 +217,12 @@ class EditDistanceOp : public OpKernel { + } else if (g_truth > g_hypothesis) { // zero-length truth + auto loc = std::inner_product(g_hypothesis.begin(), g_hypothesis.end(), + output_strides.begin(), int64{0}); ++ OP_REQUIRES( ++ ctx, loc < output_elements, ++ errors::Internal("Got an inner product ", loc, ++ " which would require in writing to outside of " ++ "the buffer for the output tensor (max elements ", ++ output_elements, ")")); + output_t(loc) = hypothesis_seq.size(); + if (normalize_ && output_t(loc) != 0.0f) { + output_t(loc) = std::numeric_limits::infinity(); +@@ -202,6 +231,12 @@ class EditDistanceOp : public OpKernel { + } else { // zero-length hypothesis + auto loc = std::inner_product(g_truth.begin(), g_truth.end(), + output_strides.begin(), int64{0}); ++ OP_REQUIRES( ++ ctx, loc < output_elements, ++ errors::Internal("Got an inner product ", loc, ++ " which would require in writing to outside of " ++ "the buffer for the output tensor (max elements ", ++ output_elements, ")")); + output_t(loc) = (normalize_) ? 1.0 : truth_seq.size(); + ++truth_iter; + } +@@ -212,6 +247,12 @@ class EditDistanceOp : public OpKernel { + auto hypothesis_seq = hypothesis_j.values(); + auto loc = std::inner_product(g_hypothesis.begin(), g_hypothesis.end(), + output_strides.begin(), int64{0}); ++ OP_REQUIRES( ++ ctx, loc < output_elements, ++ errors::Internal("Got an inner product ", loc, ++ " which would require in writing to outside of the " ++ "buffer for the output tensor (max elements ", ++ output_elements, ")")); + output_t(loc) = hypothesis_seq.size(); + if (normalize_ && output_t(loc) != 0.0f) { + output_t(loc) = std::numeric_limits::infinity(); +@@ -224,6 +265,12 @@ class EditDistanceOp : public OpKernel { + auto truth_seq = truth_i.values(); + auto loc = std::inner_product(g_truth.begin(), g_truth.end(), + output_strides.begin(), int64{0}); ++ OP_REQUIRES( ++ ctx, loc < output_elements, ++ errors::Internal("Got an inner product ", loc, ++ " which would require in writing to outside of the " ++ "buffer for the output tensor (max elements ", ++ output_elements, ")")); + output_t(loc) = (normalize_) ? 1.0 : truth_seq.size(); + ++truth_iter; + } diff --git a/CVE-2021-29567.patch b/CVE-2021-29567.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3e9dea9ba26930b08058f5bbca5825c8f3c48de --- /dev/null +++ b/CVE-2021-29567.patch @@ -0,0 +1,28 @@ +From 7ae2af34087fb4b5c8915279efd03da3b81028bc Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Tue, 4 May 2021 21:30:50 -0700 +Subject: [PATCH] Fix heap-buffer-overflow issue with + `tf.raw_ops.SparseDenseCwiseMul`. + +PiperOrigin-RevId: 372054410 +Change-Id: Ifcce0491e2e3816838c87e73be30a1e61b65174d +--- + tensorflow/core/kernels/sparse_dense_binary_op_shared.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/sparse_dense_binary_op_shared.cc b/tensorflow/core/kernels/sparse_dense_binary_op_shared.cc +index 3a5e66a0e73ea..dac4a3d3e6bfc 100644 +--- a/tensorflow/core/kernels/sparse_dense_binary_op_shared.cc ++++ b/tensorflow/core/kernels/sparse_dense_binary_op_shared.cc +@@ -78,6 +78,11 @@ class SparseDenseBinaryOpShared : public OpKernel { + "but received shapes: ", + values_t->shape().DebugString(), " and ", + shape_t->shape().DebugString())); ++ OP_REQUIRES( ++ ctx, values_t->dim_size(0) == indices_t->dim_size(0), ++ errors::InvalidArgument( ++ "The first dimension of values and indices should match. (", ++ values_t->dim_size(0), " vs. ", indices_t->dim_size(0), ")")); + + const auto indices_mat = indices_t->matrix(); + const auto shape_vec = shape_t->vec(); diff --git a/CVE-2021-29568.patch b/CVE-2021-29568.patch new file mode 100644 index 0000000000000000000000000000000000000000..e649f5fc8dbea8170eccd6b96cbb972dec9b4f98 --- /dev/null +++ b/CVE-2021-29568.patch @@ -0,0 +1,25 @@ +From 5e52ef5a461570cfb68f3bdbbebfe972cb4e0fd8 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 4 May 2021 19:14:24 -0700 +Subject: [PATCH] Fix breakage in parameterized_truncated_normal_op.cc + +PiperOrigin-RevId: 372041718 +Change-Id: Iff79e77a2bb27032423eefcb84211627b27dfe81 +--- + tensorflow/core/kernels/parameterized_truncated_normal_op.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/parameterized_truncated_normal_op.cc b/tensorflow/core/kernels/parameterized_truncated_normal_op.cc +index a63457551ac29..116df3541d7cf 100644 +--- a/tensorflow/core/kernels/parameterized_truncated_normal_op.cc ++++ b/tensorflow/core/kernels/parameterized_truncated_normal_op.cc +@@ -627,6 +627,9 @@ class ParameterizedTruncatedNormalOp : public OpKernel { + ctx, TensorShapeUtils::IsVector(shape_tensor.shape()), + errors::InvalidArgument("Input shape should be a vector, got shape: ", + shape_tensor.shape().DebugString())); ++ OP_REQUIRES(ctx, shape_tensor.NumElements() > 0, ++ errors::InvalidArgument("Shape tensor must not be empty, got ", ++ shape_tensor.DebugString())); + int32 num_batches = shape_tensor.flat()(0); + + int32 samples_per_batch = 1; diff --git a/CVE-2021-29569.patch b/CVE-2021-29569.patch new file mode 100644 index 0000000000000000000000000000000000000000..94d059e3e6c63e7ad1c12c5028bc7f6ea009175e --- /dev/null +++ b/CVE-2021-29569.patch @@ -0,0 +1,26 @@ +From ef0c008ee84bad91ec6725ddc42091e19a30cf0e Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Wed, 5 May 2021 08:16:13 -0700 +Subject: [PATCH] Fix out of bound read in requantization_range_op.cc + +PiperOrigin-RevId: 372129031 +Change-Id: Ie684ab98a3840c5186ead3eafffc0e0ed0e8030d +--- + tensorflow/core/kernels/requantization_range_op.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/requantization_range_op.cc b/tensorflow/core/kernels/requantization_range_op.cc +index cc6e891a6b352..f6e217499d198 100644 +--- a/tensorflow/core/kernels/requantization_range_op.cc ++++ b/tensorflow/core/kernels/requantization_range_op.cc +@@ -46,6 +46,10 @@ class RequantizationRangeOp : public OpKernel { + + void Compute(OpKernelContext* ctx) override { + const Tensor& input = ctx->input(0); ++ OP_REQUIRES(ctx, ctx->input(1).NumElements() > 0, ++ errors::InvalidArgument("Input min must not be empty.")); ++ OP_REQUIRES(ctx, ctx->input(2).NumElements() > 0, ++ errors::InvalidArgument("Input max must not be empty.")); + const float input_min_float = ctx->input(1).flat()(0); + const float input_max_float = ctx->input(2).flat()(0); + Tensor* output_min = nullptr; diff --git a/CVE-2021-29570.patch b/CVE-2021-29570.patch new file mode 100644 index 0000000000000000000000000000000000000000..0efb7e7bc20eab409459f8a034a5a077c17f9d2e --- /dev/null +++ b/CVE-2021-29570.patch @@ -0,0 +1,25 @@ +From dcd7867de0fea4b72a2b34bd41eb74548dc23886 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 08:38:03 -0700 +Subject: [PATCH] Fix heap buffer overflow + +PiperOrigin-RevId: 372132844 +Change-Id: Idef9895efaf145f2b1c23d31983601ec980cd5e4 +--- + tensorflow/core/kernels/maxpooling_op.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/maxpooling_op.cc b/tensorflow/core/kernels/maxpooling_op.cc +index b60d54533be68..003d2e94b99cd 100644 +--- a/tensorflow/core/kernels/maxpooling_op.cc ++++ b/tensorflow/core/kernels/maxpooling_op.cc +@@ -1014,6 +1014,9 @@ struct LaunchMaxPoolingGradWithArgmax { + const int input_start = start * input_size_per_batch; + const int input_end = limit * input_size_per_batch; + for (int64 index = input_start; index < input_end; index++) { ++ if (index >= argmax.NumElements()) { ++ break; ++ } + int64 grad_out_index = argmax_flat(index); + if (!include_batch_in_index) { + const int64 cur_batch = index / input_size_per_batch; diff --git a/CVE-2021-29572.patch b/CVE-2021-29572.patch new file mode 100644 index 0000000000000000000000000000000000000000..d38dae8044d2f1bdb1e4a64623318ee5ade46198 --- /dev/null +++ b/CVE-2021-29572.patch @@ -0,0 +1,90 @@ +From f7cc8755ac6683131fdfa7a8a121f9d7a9dec6fb Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 11:40:50 -0700 +Subject: [PATCH] Add several missing validations in SDCA + +PiperOrigin-RevId: 372172877 +Change-Id: Id366da962432e18dcbfac847d11e98488bebb70a +--- + tensorflow/core/kernels/sdca_internal.cc | 36 ++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/tensorflow/core/kernels/sdca_internal.cc b/tensorflow/core/kernels/sdca_internal.cc +index cbc754af0e9bb..11a3be8bf46a7 100644 +--- a/tensorflow/core/kernels/sdca_internal.cc ++++ b/tensorflow/core/kernels/sdca_internal.cc +@@ -99,6 +99,10 @@ Status ModelWeights::Initialize(OpKernelContext* const context) { + OpInputList sparse_weights_inputs; + TF_RETURN_IF_ERROR( + context->input_list("sparse_weights", &sparse_weights_inputs)); ++ if (sparse_indices_inputs.size() != sparse_weights_inputs.size()) ++ return errors::InvalidArgument( ++ "sparse_indices and sparse_weights must have the same length, got ", ++ sparse_indices_inputs.size(), " and ", sparse_weights_inputs.size()); + OpInputList dense_weights_inputs; + TF_RETURN_IF_ERROR( + context->input_list("dense_weights", &dense_weights_inputs)); +@@ -106,10 +110,20 @@ Status ModelWeights::Initialize(OpKernelContext* const context) { + OpOutputList sparse_weights_outputs; + TF_RETURN_IF_ERROR(context->output_list("out_delta_sparse_weights", + &sparse_weights_outputs)); ++ if (sparse_weights_outputs.size() != sparse_weights_inputs.size()) ++ return errors::InvalidArgument( ++ "out_delta_sparse_weights and sparse_weights must have the same " ++ "length, got ", ++ sparse_weights_outputs.size(), " and ", sparse_weights_inputs.size()); + + OpOutputList dense_weights_outputs; + TF_RETURN_IF_ERROR( + context->output_list("out_delta_dense_weights", &dense_weights_outputs)); ++ if (dense_weights_outputs.size() != dense_weights_inputs.size()) ++ return errors::InvalidArgument( ++ "out_delta_dense_weights and dense_weights must have the same length, " ++ "got ", ++ dense_weights_outputs.size(), " and ", dense_weights_inputs.size()); + + for (int i = 0; i < sparse_weights_inputs.size(); ++i) { + Tensor* delta_t; +@@ -327,13 +341,28 @@ Status Examples::Initialize(OpKernelContext* const context, + OpInputList sparse_example_indices_inputs; + TF_RETURN_IF_ERROR(context->input_list("sparse_example_indices", + &sparse_example_indices_inputs)); ++ if (sparse_example_indices_inputs.size() != num_sparse_features) ++ return errors::InvalidArgument( ++ "Expected ", num_sparse_features, ++ " tensors in sparse_example_indices but got ", ++ sparse_example_indices_inputs.size()); + OpInputList sparse_feature_indices_inputs; + TF_RETURN_IF_ERROR(context->input_list("sparse_feature_indices", + &sparse_feature_indices_inputs)); ++ if (sparse_feature_indices_inputs.size() != num_sparse_features) ++ return errors::InvalidArgument( ++ "Expected ", num_sparse_features, ++ " tensors in sparse_feature_indices but got ", ++ sparse_feature_indices_inputs.size()); + OpInputList sparse_feature_values_inputs; + if (num_sparse_features_with_values > 0) { + TF_RETURN_IF_ERROR(context->input_list("sparse_feature_values", + &sparse_feature_values_inputs)); ++ if (sparse_feature_values_inputs.size() != num_sparse_features_with_values) ++ return errors::InvalidArgument( ++ "Expected ", num_sparse_features_with_values, ++ " tensors in sparse_feature_values but got ", ++ sparse_feature_values_inputs.size()); + } + + const Tensor* example_weights_t; +@@ -400,6 +429,13 @@ Status Examples::CreateSparseFeatureRepresentation( + sparse_example_indices_inputs[i].template flat(); + auto feature_indices = + sparse_feature_indices_inputs[i].template flat(); ++ if (example_indices.size() != feature_indices.size()) { ++ mutex_lock l(mu); ++ result = errors::InvalidArgument( ++ "Found mismatched example_indices and feature_indices [", ++ example_indices, "] vs [", feature_indices, "]"); ++ return; ++ } + + // Parse features for each example. Features for a particular example + // are at the offsets (start_id, end_id] diff --git a/CVE-2021-29573.patch b/CVE-2021-29573.patch new file mode 100644 index 0000000000000000000000000000000000000000..e5d6b2324ed136630d8b8eaf7d0ec4b3c445fe32 --- /dev/null +++ b/CVE-2021-29573.patch @@ -0,0 +1,24 @@ +From 376c352a37ce5a68b721406dc7e77ac4b6cf483d Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 14:34:54 -0700 +Subject: [PATCH] Don't do any work if output tensor is null (prevent div by 0) + +PiperOrigin-RevId: 372208700 +Change-Id: Iea6b6293e887ade8538facfdb50fb931e17f511e +--- + tensorflow/core/kernels/maxpooling_op.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/maxpooling_op.cc b/tensorflow/core/kernels/maxpooling_op.cc +index 003d2e94b99cd..ceb6694ed665d 100644 +--- a/tensorflow/core/kernels/maxpooling_op.cc ++++ b/tensorflow/core/kernels/maxpooling_op.cc +@@ -1088,6 +1088,8 @@ class MaxPoolingGradWithArgmaxOp : public OpKernel { + OP_REQUIRES_OK(context, context->forward_input_or_allocate_output( + {0}, 0, out_shape, &grad_out)); + ++ if (out_shape.num_elements() == 0) return; // nothing to be done ++ + LaunchMaxPoolingGradWithArgmax::launch( + context, params, grad_in, argmax, grad_out, include_batch_in_index_); + } diff --git a/CVE-2021-29574.patch b/CVE-2021-29574.patch new file mode 100644 index 0000000000000000000000000000000000000000..bceb829764f0e8a60bd85578815dee5e2f8e3724 --- /dev/null +++ b/CVE-2021-29574.patch @@ -0,0 +1,35 @@ +From a3d9f9be9ac2296615644061b40cefcee341dcc4 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 15:20:14 -0700 +Subject: [PATCH] Add missing validation to pooling_ops_3d + +PiperOrigin-RevId: 372218727 +Change-Id: I6b9ed4266aa7286c02f1f230d7bea922c1be547e +--- + tensorflow/core/kernels/pooling_ops_3d.cc | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/tensorflow/core/kernels/pooling_ops_3d.cc b/tensorflow/core/kernels/pooling_ops_3d.cc +index 1114e6931ecf9..7d133b66a1ebd 100644 +--- a/tensorflow/core/kernels/pooling_ops_3d.cc ++++ b/tensorflow/core/kernels/pooling_ops_3d.cc +@@ -698,6 +698,19 @@ class MaxPooling3dGradGradOp : public OpKernel { + OP_REQUIRES_OK(context, context->forward_input_or_allocate_output( + {2}, 0, tensor_out.shape(), &output)); + ++ // Given access patterns in LaunchMaxPooling3dGradGradOp, these tensors must ++ // have elements. ++ OP_REQUIRES(context, tensor_in.NumElements() > 0, ++ errors::InvalidArgument("received empty tensor tensor_in: ", ++ tensor_in.DebugString())); ++ OP_REQUIRES(context, tensor_out.NumElements() > 0, ++ errors::InvalidArgument("received empty tensor tensor_out: ", ++ tensor_out.DebugString())); ++ OP_REQUIRES( ++ context, out_grad_backprop.NumElements() > 0, ++ errors::InvalidArgument("received empty tensor out_grad_backprop: ", ++ out_grad_backprop.DebugString())); ++ + LaunchMaxPooling3dGradGradOp::launch( + context, params, tensor_in, tensor_out, out_grad_backprop, output); + } diff --git a/CVE-2021-29575.patch b/CVE-2021-29575.patch new file mode 100644 index 0000000000000000000000000000000000000000..84141094f049ed13079d32d10ffa25ecafd4759f --- /dev/null +++ b/CVE-2021-29575.patch @@ -0,0 +1,26 @@ +From ecf768cbe50cedc0a45ce1ee223146a3d3d26d23 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 12:07:57 -0700 +Subject: [PATCH] Add missing validations to reverse_sequence_op + +PiperOrigin-RevId: 372178683 +Change-Id: Iac97ebab5b342f1262c77a7d9bcb4267b305ce5b +--- + tensorflow/core/kernels/reverse_sequence_op.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/reverse_sequence_op.cc b/tensorflow/core/kernels/reverse_sequence_op.cc +index b5b62bc76ca52..1282deb26e8cd 100644 +--- a/tensorflow/core/kernels/reverse_sequence_op.cc ++++ b/tensorflow/core/kernels/reverse_sequence_op.cc +@@ -115,6 +115,10 @@ class ReverseSequenceOp : public OpKernel { + : OpKernel(context) { + OP_REQUIRES_OK(context, context->GetAttr("batch_dim", &batch_dim_)); + OP_REQUIRES_OK(context, context->GetAttr("seq_dim", &seq_dim_)); ++ OP_REQUIRES(context, batch_dim_ >= 0, ++ errors::InvalidArgument("Invalid batch_dim ", batch_dim_)); ++ OP_REQUIRES(context, seq_dim_ >= 0, ++ errors::InvalidArgument("Invalid seq_dim ", seq_dim_)); + } + + void Compute(OpKernelContext* context) override { diff --git a/CVE-2021-29576.patch b/CVE-2021-29576.patch new file mode 100644 index 0000000000000000000000000000000000000000..dfbea3d4998962768fe541f3ec7b4425ad570033 --- /dev/null +++ b/CVE-2021-29576.patch @@ -0,0 +1,41 @@ +From 63c6a29d0f2d692b247f7bf81f8732d6442fad09 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 18:07:02 -0700 +Subject: [PATCH] Add missing validation, prevent heap OOB + +PiperOrigin-RevId: 372246723 +Change-Id: I1a454a643810e77d7d14821b342098c56a09fbbf +--- + tensorflow/core/kernels/pooling_ops_3d.cc | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/tensorflow/core/kernels/pooling_ops_3d.cc b/tensorflow/core/kernels/pooling_ops_3d.cc +index 7d133b66a1ebd..9da2d62b0a21d 100644 +--- a/tensorflow/core/kernels/pooling_ops_3d.cc ++++ b/tensorflow/core/kernels/pooling_ops_3d.cc +@@ -693,6 +693,7 @@ class MaxPooling3dGradGradOp : public OpKernel { + + Pool3dParameters params{context, ksize_, stride_, + padding_, data_format_, tensor_in.shape()}; ++ if (!context->status().ok()) return; // params is invalid + + Tensor* output = nullptr; + OP_REQUIRES_OK(context, context->forward_input_or_allocate_output( +@@ -710,6 +711,17 @@ class MaxPooling3dGradGradOp : public OpKernel { + context, out_grad_backprop.NumElements() > 0, + errors::InvalidArgument("received empty tensor out_grad_backprop: ", + out_grad_backprop.DebugString())); ++ OP_REQUIRES(context, ++ tensor_in.NumElements() == out_grad_backprop.NumElements(), ++ errors::InvalidArgument("tensor_in and out_grad_backprop must " ++ "have same number of elements, got <", ++ tensor_in.DebugString(), "> and <", ++ out_grad_backprop.DebugString(), ">")); ++ OP_REQUIRES( ++ context, tensor_out.NumElements() == output->NumElements(), ++ errors::InvalidArgument( ++ "tensor_out and output must have same number of elements, got <", ++ tensor_out.DebugString(), "> and <", output->DebugString(), ">")); + + LaunchMaxPooling3dGradGradOp::launch( + context, params, tensor_in, tensor_out, out_grad_backprop, output); diff --git a/CVE-2021-29577.patch b/CVE-2021-29577.patch new file mode 100644 index 0000000000000000000000000000000000000000..3e25368d3d6a2c714b3f6527c5d964e4fab14e89 --- /dev/null +++ b/CVE-2021-29577.patch @@ -0,0 +1,35 @@ +From 6fc9141f42f6a72180ecd24021c3e6b36165fe0d Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 6 May 2021 09:51:26 -0700 +Subject: [PATCH] Fix assertion failure in pooling_ops_3d + +PiperOrigin-RevId: 372364504 +Change-Id: Iecde4fe26b47a8fa935d6e2611b5585ed5777781 +--- + tensorflow/core/kernels/pooling_ops_3d.cc | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/tensorflow/core/kernels/pooling_ops_3d.cc b/tensorflow/core/kernels/pooling_ops_3d.cc +index 9da2d62b0a21d..56a55bc2ec87b 100644 +--- a/tensorflow/core/kernels/pooling_ops_3d.cc ++++ b/tensorflow/core/kernels/pooling_ops_3d.cc +@@ -383,6 +383,19 @@ struct LaunchAvgPooling3dGradOp { + const std::array& output_shape, + const std::array& padding, + TensorFormat data_format, Tensor* output) { ++ OP_REQUIRES( ++ context, tensor_in_shape.dim_size(0) == out_backprop.dim_size(0), ++ errors::InvalidArgument( ++ "Expected first dimension of tensor_in_shape and " ++ "out_backprop to match, got ", ++ tensor_in_shape.dim_size(0), " and ", out_backprop.dim_size(0))); ++ OP_REQUIRES( ++ context, tensor_in_shape.dim_size(4) == out_backprop.dim_size(4), ++ errors::InvalidArgument( ++ "Expected last dimension of tensor_in_shape and " ++ "out_backprop to match, got ", ++ tensor_in_shape.dim_size(4), " and ", out_backprop.dim_size(4))); ++ + output->flat().setZero(); + std::array input_size = {{tensor_in_shape.dim_size(3), + tensor_in_shape.dim_size(2), diff --git a/CVE-2021-29578.patch b/CVE-2021-29578.patch new file mode 100644 index 0000000000000000000000000000000000000000..e77501b2b6034ceb99d4ebd91088045fa5e6e004 --- /dev/null +++ b/CVE-2021-29578.patch @@ -0,0 +1,35 @@ +From 12c727cee857fa19be717f336943d95fca4ffe4f Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 6 May 2021 14:02:47 -0700 +Subject: [PATCH] Validate inputs of `FractionalAvgPoolGrad`. + +PiperOrigin-RevId: 372420640 +Change-Id: Icc583928e6cdc3062e12498e4d2337a8fe3da016 +--- + tensorflow/core/kernels/fractional_avg_pool_op.cc | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/tensorflow/core/kernels/fractional_avg_pool_op.cc b/tensorflow/core/kernels/fractional_avg_pool_op.cc +index b8a5083e5340f..0452638a06679 100644 +--- a/tensorflow/core/kernels/fractional_avg_pool_op.cc ++++ b/tensorflow/core/kernels/fractional_avg_pool_op.cc +@@ -250,6 +250,19 @@ class FractionalAvgPoolGradOp : public OpKernel { + const int64 out_cols = out_backprop.dim_size(2); + const int64 out_depth = out_backprop.dim_size(3); + ++ OP_REQUIRES(context, row_seq_tensor.NumElements() > out_rows, ++ errors::InvalidArgument("Given out_backprop shape ", ++ out_backprop.shape().DebugString(), ++ ", row_seq_tensor must have at least ", ++ out_rows + 1, " elements, but got ", ++ row_seq_tensor.NumElements())); ++ OP_REQUIRES(context, col_seq_tensor.NumElements() > out_cols, ++ errors::InvalidArgument("Given out_backprop shape ", ++ out_backprop.shape().DebugString(), ++ ", col_seq_tensor must have at least ", ++ out_cols + 1, " elements, but got ", ++ col_seq_tensor.NumElements())); ++ + auto row_seq_tensor_flat = row_seq_tensor.flat(); + auto col_seq_tensor_flat = col_seq_tensor.flat(); + auto orig_input_tensor_shape_flat = orig_input_tensor_shape.flat(); diff --git a/CVE-2021-29579.patch b/CVE-2021-29579.patch new file mode 100644 index 0000000000000000000000000000000000000000..3612b4f04ab0dab8bcdf14b65cee5f7b50dfee64 --- /dev/null +++ b/CVE-2021-29579.patch @@ -0,0 +1,26 @@ +From a74768f8e4efbda4def9f16ee7e13cf3922ac5f7 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 6 May 2021 14:24:09 -0700 +Subject: [PATCH] Prevent heap OOB error in `MaxPoolGrad` + +PiperOrigin-RevId: 372424854 +Change-Id: Idac0f23867ad8b0601cafbaaa52d5e64269e63a7 +--- + tensorflow/core/kernels/maxpooling_op.cc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tensorflow/core/kernels/maxpooling_op.cc b/tensorflow/core/kernels/maxpooling_op.cc +index ceb6694ed665d..01f303eb26980 100644 +--- a/tensorflow/core/kernels/maxpooling_op.cc ++++ b/tensorflow/core/kernels/maxpooling_op.cc +@@ -199,7 +199,9 @@ static void SpatialMaxPoolWithArgMaxHelper( + // CHECK(input_backprop_index >= in_start && input_backprop_index < + // in_end) + FastBoundsCheck(input_backprop_index - in_start, in_end - in_start); +- input_backprop_flat(input_backprop_index) += out_backprop_flat(index); ++ if (index < out_backprop.NumElements()) { ++ input_backprop_flat(input_backprop_index) += out_backprop_flat(index); ++ } + } + } + }; diff --git a/CVE-2021-29580.patch b/CVE-2021-29580.patch new file mode 100644 index 0000000000000000000000000000000000000000..b6db650c586001e7100226793beec9a7760dcd52 --- /dev/null +++ b/CVE-2021-29580.patch @@ -0,0 +1,36 @@ +From 32fdcbff9d06d010d908fcc4bd4b36eb3ce15925 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 5 May 2021 22:39:29 -0700 +Subject: [PATCH] Validate arguments of `FractionalMaxPoolGrad` + +PiperOrigin-RevId: 372274982 +Change-Id: If46b0c442efa4eaef635ce6a476717060420122c +--- + tensorflow/core/kernels/fractional_max_pool_op.cc | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/tensorflow/core/kernels/fractional_max_pool_op.cc b/tensorflow/core/kernels/fractional_max_pool_op.cc +index 619a3507ce415..1a2a783d135c5 100644 +--- a/tensorflow/core/kernels/fractional_max_pool_op.cc ++++ b/tensorflow/core/kernels/fractional_max_pool_op.cc +@@ -235,6 +235,20 @@ class FractionalMaxPoolGradOp : public OpKernel { + + // Just to make it similar to FractionalMaxPoolOp. + constexpr int tensor_in_and_out_dims = 4; ++ OP_REQUIRES( ++ context, tensor_in.dims() == tensor_in_and_out_dims, ++ errors::InvalidArgument("orig_input should be a tensor of rank 4, got ", ++ tensor_in.DebugString())); ++ OP_REQUIRES(context, tensor_in.NumElements() > 0, ++ errors::InvalidArgument("orig_input must not be empty, got ", ++ tensor_in.DebugString())); ++ OP_REQUIRES(context, tensor_out.dims() == tensor_in_and_out_dims, ++ errors::InvalidArgument( ++ "orig_output should be a tensor of rank 4, got ", ++ tensor_out.DebugString())); ++ OP_REQUIRES(context, tensor_out.NumElements() > 0, ++ errors::InvalidArgument("orig_output must not be empty, got ", ++ tensor_out.DebugString())); + std::vector input_size(tensor_in_and_out_dims); + std::vector output_size(tensor_in_and_out_dims); + for (int i = 0; i < tensor_in_and_out_dims; ++i) { diff --git a/CVE-2021-29581.patch b/CVE-2021-29581.patch new file mode 100644 index 0000000000000000000000000000000000000000..07fa28ba644ec93aabac8ed3df7ba4a7c28017b2 --- /dev/null +++ b/CVE-2021-29581.patch @@ -0,0 +1,25 @@ +From b1b323042264740c398140da32e93fb9c2c9f33e Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 6 May 2021 14:51:41 -0700 +Subject: [PATCH] Fix SEGV in CTC ops + +PiperOrigin-RevId: 372430279 +Change-Id: I7ec2ad9d6f4d0980c33de45d27c6b17df5c6e26f +--- + tensorflow/core/kernels/ctc_decoder_ops.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/ctc_decoder_ops.cc b/tensorflow/core/kernels/ctc_decoder_ops.cc +index 22681f97437f0..9efdac60e369c 100644 +--- a/tensorflow/core/kernels/ctc_decoder_ops.cc ++++ b/tensorflow/core/kernels/ctc_decoder_ops.cc +@@ -70,6 +70,9 @@ class CTCDecodeHelper { + if (inputs_shape.dims() != 3) { + return errors::InvalidArgument("inputs is not a 3-Tensor"); + } ++ if (inputs_shape.num_elements() == 0) { ++ return errors::InvalidArgument("inputs must not be empty"); ++ } + + const int64 max_time = inputs_shape.dim_size(0); + const int64 batch_size = inputs_shape.dim_size(1); diff --git a/CVE-2021-29582.patch b/CVE-2021-29582.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f461cee94d4ff441c83ebf5a065513d26c5167a --- /dev/null +++ b/CVE-2021-29582.patch @@ -0,0 +1,36 @@ +From 5899741d0421391ca878da47907b1452f06aaf1b Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 6 May 2021 15:31:05 -0700 +Subject: [PATCH] Fix heap OOB read in dequantize op. + +Also fixes SEGV in same op + +PiperOrigin-RevId: 372437896 +Change-Id: I135e94d360c2a1ce374c10f7e0fed1af603dbc02 +--- + tensorflow/core/kernels/dequantize_op.cc | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/tensorflow/core/kernels/dequantize_op.cc b/tensorflow/core/kernels/dequantize_op.cc +index 5393a677db242..7a90e0c340b09 100644 +--- a/tensorflow/core/kernels/dequantize_op.cc ++++ b/tensorflow/core/kernels/dequantize_op.cc +@@ -98,6 +98,18 @@ class DequantizeOp : public OpKernel { + if (axis_ > -1) { + num_slices = input.dim_size(axis_); + } ++ OP_REQUIRES(ctx, input_min_tensor.NumElements() == num_slices, ++ errors::InvalidArgument( ++ "input_min_tensor must have as many elements as input on " ++ "the dequantization axis (", ++ axis_, "), got ", input_min_tensor.NumElements(), ++ ", expected ", num_slices)); ++ OP_REQUIRES(ctx, input_max_tensor.NumElements() == num_slices, ++ errors::InvalidArgument( ++ "input_max_tensor must have as many elements as input on " ++ "the dequantization axis (", ++ axis_, "), got ", input_max_tensor.NumElements(), ++ ", expected ", num_slices)); + + Tensor* output = nullptr; + OP_REQUIRES_OK(ctx, ctx->allocate_output(0, input.shape(), &output)); diff --git a/CVE-2021-29585.patch b/CVE-2021-29585.patch new file mode 100644 index 0000000000000000000000000000000000000000..bc865e8543fc96484f7b83b9a79cc06fae6351b7 --- /dev/null +++ b/CVE-2021-29585.patch @@ -0,0 +1,27 @@ +From 49847ae69a4e1a97ae7f2db5e217c77721e37948 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 15:37:08 -0700 +Subject: [PATCH] Fix division by zero in TFLite padding. + +PiperOrigin-RevId: 370777494 +Change-Id: Ic1331e4a1603b9e4c8aa183012a6c8237410aa0f +--- + tensorflow/lite/kernels/padding.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/lite/kernels/padding.h b/tensorflow/lite/kernels/padding.h +index 85950eaf34bb9..d9cca3ea13515 100644 +--- a/tensorflow/lite/kernels/padding.h ++++ b/tensorflow/lite/kernels/padding.h +@@ -44,6 +44,11 @@ inline int ComputePaddingWithOffset(int stride, int dilation_rate, int in_size, + inline int ComputeOutSize(TfLitePadding padding, int image_size, + int filter_size, int stride, int dilation_rate = 1) { + int effective_filter_size = (filter_size - 1) * dilation_rate + 1; ++ ++ // TODO(b/186448822): This uses 0 since the function has no other way to ++ // report error case ++ if (stride == 0) return 0; ++ + switch (padding) { + case kTfLitePaddingSame: + return (image_size + stride - 1) / stride; diff --git a/CVE-2021-29586.patch b/CVE-2021-29586.patch new file mode 100644 index 0000000000000000000000000000000000000000..e6cd86dbcbc758a67b30c425d945e77a07e07a26 --- /dev/null +++ b/CVE-2021-29586.patch @@ -0,0 +1,51 @@ +From 5f7975d09eac0f10ed8a17dbb6f5964977725adc Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 17:45:43 -0700 +Subject: [PATCH] Prevent another div by 0 in optimized pooling implementations + TFLite + +PiperOrigin-RevId: 370800091 +Change-Id: I2119352f57fb5ca4f2051e0e2d749403304a979b +--- + tensorflow/lite/kernels/pooling.cc | 4 ++++ + tensorflow/lite/kernels/pooling_test.cc | 13 +++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/tensorflow/lite/kernels/pooling.cc b/tensorflow/lite/kernels/pooling.cc +index 1ae3d207b135e..474bd3825f4ff 100644 +--- a/tensorflow/lite/kernels/pooling.cc ++++ b/tensorflow/lite/kernels/pooling.cc +@@ -87,6 +87,10 @@ TfLiteStatus GenericPrepare(TfLiteContext* context, TfLiteNode* node) { + auto padding = params->padding; + int out_width, out_height; + ++ // Prevent division by 0 in optimized pooling implementations ++ TF_LITE_ENSURE(context, params->stride_height > 0); ++ TF_LITE_ENSURE(context, params->stride_width > 0); ++ + data->padding = ComputePaddingHeightWidth( + params->stride_height, params->stride_width, 1, 1, height, width, + params->filter_height, params->filter_width, padding, &out_height, +diff --git a/tensorflow/lite/kernels/pooling_test.cc b/tensorflow/lite/kernels/pooling_test.cc +index e614fedccfd50..108195388141d 100644 +--- a/tensorflow/lite/kernels/pooling_test.cc ++++ b/tensorflow/lite/kernels/pooling_test.cc +@@ -1151,5 +1151,18 @@ TEST(FloatPoolingOpTest, L2PoolPaddingValidSlide1) { + EXPECT_THAT(m.GetOutput(), ElementsAreArray({3.5, 6.0, 6.5})); + } + ++#ifdef GTEST_HAS_DEATH_TEST ++TEST(FloatPoolingOpTest, MaxPoolWithZeroStride) { ++ EXPECT_DEATH( ++ FloatPoolingOpModel m(BuiltinOperator_MAX_POOL_2D, ++ /*input=*/{TensorType_FLOAT32, {1, 2, 4, 1}}, ++ /*filter_width=*/2, /*filter_height=*/2, ++ /*output=*/{TensorType_FLOAT32, {}}, ++ /*padding=*/Padding_VALID, ++ /*stride_w=*/0, /*stride_h=*/0), ++ "Cannot allocate tensors"); ++} ++#endif ++ + } // namespace + } // namespace tflite diff --git a/CVE-2021-29587.patch b/CVE-2021-29587.patch new file mode 100644 index 0000000000000000000000000000000000000000..82fad316175d7a195ce8016f4d55340e10570a22 --- /dev/null +++ b/CVE-2021-29587.patch @@ -0,0 +1,23 @@ +From 0d45ea1ca641b21b73bcf9c00e0179cda284e7e7 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 17:45:57 -0700 +Subject: [PATCH] Prevent one more div by 0 in TFLite + +PiperOrigin-RevId: 370800114 +Change-Id: I6b956aeb8c458cc6f514408d2e89ffacfe249e57 +--- + tensorflow/lite/kernels/space_to_depth.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/space_to_depth.cc b/tensorflow/lite/kernels/space_to_depth.cc +index 4db7440b57e60..35a0fe1c26e20 100644 +--- a/tensorflow/lite/kernels/space_to_depth.cc ++++ b/tensorflow/lite/kernels/space_to_depth.cc +@@ -61,6 +61,7 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TF_LITE_ENSURE_TYPES_EQ(context, input->type, output->type); + + const int block_size = params->block_size; ++ TF_LITE_ENSURE(context, block_size > 0); + const int input_height = input->dims->data[1]; + const int input_width = input->dims->data[2]; + int output_height = input_height / block_size; diff --git a/CVE-2021-29588.patch b/CVE-2021-29588.patch new file mode 100644 index 0000000000000000000000000000000000000000..698e3bd4501deeb0ff48b726cfb3721023155fa7 --- /dev/null +++ b/CVE-2021-29588.patch @@ -0,0 +1,26 @@ +From 801c1c6be5324219689c98e1bd3e0ca365ee834d Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 17:46:25 -0700 +Subject: [PATCH] Fix another division by 0 in TFLite + +PiperOrigin-RevId: 370800181 +Change-Id: I924809166a6131f5075e6d45c455106538d755f9 +--- + tensorflow/lite/kernels/transpose_conv.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/lite/kernels/transpose_conv.cc b/tensorflow/lite/kernels/transpose_conv.cc +index 497edac5762dc..cf9d53fb3b6ee 100644 +--- a/tensorflow/lite/kernels/transpose_conv.cc ++++ b/tensorflow/lite/kernels/transpose_conv.cc +@@ -591,6 +591,10 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const auto* params = + reinterpret_cast(node->builtin_data); + ++ // Prevent divisions by 0 ++ TF_LITE_ENSURE(context, params->stride_height > 0); ++ TF_LITE_ENSURE(context, params->stride_width > 0); ++ + // Resize any deferred dynamic tensors + if (IsDynamicTensor(output)) { + TF_LITE_ENSURE_OK(context, ResizeTensor(context, output_shape, output)); diff --git a/CVE-2021-29590.patch b/CVE-2021-29590.patch new file mode 100644 index 0000000000000000000000000000000000000000..eeea683f220829b649f3028fdf9953809270d3fa --- /dev/null +++ b/CVE-2021-29590.patch @@ -0,0 +1,82 @@ +From 953f28dca13c92839ba389c055587cfe6c723578 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 17:46:38 -0700 +Subject: [PATCH] Prevent a null pointer exception in TFLite + +PiperOrigin-RevId: 370800206 +Change-Id: Idd437ebce4ff224120d8eefc1c14c062173b71d6 +--- + tensorflow/lite/kernels/maximum_minimum.cc | 60 +++++++++++----------- + 1 file changed, 31 insertions(+), 29 deletions(-) + +diff --git a/tensorflow/lite/kernels/maximum_minimum.cc b/tensorflow/lite/kernels/maximum_minimum.cc +index 777e51442f120..176e020a5a8e5 100644 +--- a/tensorflow/lite/kernels/maximum_minimum.cc ++++ b/tensorflow/lite/kernels/maximum_minimum.cc +@@ -157,35 +157,37 @@ template + TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + OpContext op_context(context, node); + +- switch (op_context.output->type) { +- case kTfLiteFloat32: +- TFLiteOperation(context, node, op_context); +- break; +- case kTfLiteUInt8: +- TFLiteOperation(context, node, +- op_context); +- break; +- case kTfLiteInt8: +- TFLiteOperation(context, node, op_context); +- break; +- case kTfLiteInt32: +- TFLiteOperation(context, node, +- op_context); +- break; +- case kTfLiteInt64: +- TFLiteOperation(context, node, +- op_context); +- break; +- case kTfLiteInt16: +- TFLiteOperation(context, node, +- op_context); +- break; +- default: +- context->ReportError(context, +- "Type %d is currently not supported by Maximum.", +- op_context.output->type); +- return kTfLiteError; +- } ++ // If inputs have no element, shortcircuit. ++ if (NumElements(op_context.input1) == 0 || ++ NumElements(op_context.input2) == 0) { ++ return kTfLiteOk; ++ } ++ ++ switch (op_context.output->type) { ++ case kTfLiteFloat32: ++ TFLiteOperation(context, node, op_context); ++ break; ++ case kTfLiteUInt8: ++ TFLiteOperation(context, node, op_context); ++ break; ++ case kTfLiteInt8: ++ TFLiteOperation(context, node, op_context); ++ break; ++ case kTfLiteInt32: ++ TFLiteOperation(context, node, op_context); ++ break; ++ case kTfLiteInt64: ++ TFLiteOperation(context, node, op_context); ++ break; ++ case kTfLiteInt16: ++ TFLiteOperation(context, node, op_context); ++ break; ++ default: ++ context->ReportError(context, ++ "Type %d is currently not supported by Maximum.", ++ op_context.output->type); ++ return kTfLiteError; ++ } + return kTfLiteOk; + } + diff --git a/CVE-2021-29591.patch b/CVE-2021-29591.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c050fa85085be5bb2739bee9cd3065a84dc6391 --- /dev/null +++ b/CVE-2021-29591.patch @@ -0,0 +1,24 @@ +From 9c1dc920d8ffb4893d6c9d27d1f039607b326743 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 17:47:46 -0700 +Subject: [PATCH] Prevent infinite loop/stack overflow in TFLite `while` op. + +PiperOrigin-RevId: 370800333 +Change-Id: I6a2e4ff849da339545c449db2af7e11ce6ff02c3 +--- + tensorflow/lite/kernels/while.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/lite/kernels/while.cc b/tensorflow/lite/kernels/while.cc +index e05959fe2a682..74ab81c2a9599 100644 +--- a/tensorflow/lite/kernels/while.cc ++++ b/tensorflow/lite/kernels/while.cc +@@ -138,6 +138,8 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + auto* subgraphs = this_subgraph->GetSubgraphs(); + TF_LITE_ENSURE(context, op_data->cond_subgraph_index < subgraphs->size()); + TF_LITE_ENSURE(context, op_data->body_subgraph_index < subgraphs->size()); ++ TF_LITE_ENSURE(context, ++ op_data->cond_subgraph_index != op_data->body_subgraph_index); + + Subgraph* cond_subgraph = (*subgraphs)[op_data->cond_subgraph_index].get(); + Subgraph* body_subgraph = (*subgraphs)[op_data->body_subgraph_index].get(); diff --git a/CVE-2021-29592.patch b/CVE-2021-29592.patch new file mode 100644 index 0000000000000000000000000000000000000000..86b4ceaa9ee4ff34451fa23801faa70f177b1f05 --- /dev/null +++ b/CVE-2021-29592.patch @@ -0,0 +1,36 @@ +From f8378920345f4f4604202d4ab15ef64b2aceaa16 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Apr 2021 17:47:59 -0700 +Subject: [PATCH] Prevent a null pointer dereference in TFLite. + +PiperOrigin-RevId: 370800353 +Change-Id: Ic9c9712ce5c6e384c954dcd640a5bd9ff05c9a05 +--- + tensorflow/lite/core/subgraph.cc | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/tensorflow/lite/core/subgraph.cc b/tensorflow/lite/core/subgraph.cc +index 7f9dd2ce3363d..0273018b3bf03 100644 +--- a/tensorflow/lite/core/subgraph.cc ++++ b/tensorflow/lite/core/subgraph.cc +@@ -1060,10 +1060,17 @@ TfLiteStatus Subgraph::Invoke() { + TF_LITE_ENSURE_STATUS(EnsureTensorDataIsReadable(tensor_index)); + } + if (tensor->data.raw == nullptr && tensor->bytes > 0) { +- if (registration.builtin_code == kTfLiteBuiltinReshape && i == 1) { ++ if (registration.builtin_code == kTfLiteBuiltinReshape && i == 1 && ++ tensor->dims->size != 1) { + // In general, having a tensor here with no buffer will be an error. +- // However, for the reshape operator, the second input tensor is only +- // used for the shape, not for the data. Thus, null buffer is ok. ++ // However, for the reshape operator, the second input tensor is ++ // sometimes only used for the shape, not for the data. Thus, null ++ // buffer is ok in this situation. ++ // The situation where null buffer is not ok for reshape operator is ++ // only when there are 2 inputs given to the node and the one ++ // corresponding to the shape (i == 1) is a vector that contains all ++ // dimensions. See `GetOutputShape()` function in ++ // `tensorflow/lite/kernels/reshape.cc` + continue; + } else { + // In all other cases, we need to return an error as otherwise we will diff --git a/CVE-2021-29593.patch b/CVE-2021-29593.patch new file mode 100644 index 0000000000000000000000000000000000000000..c53f6c56d893b786fab46dd0d941e6980e17933e --- /dev/null +++ b/CVE-2021-29593.patch @@ -0,0 +1,23 @@ +From 2c74674348a4708ced58ad6eb1b23354df8ee044 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 13:57:37 -0700 +Subject: [PATCH] Prevent division by 0 + +PiperOrigin-RevId: 370979352 +Change-Id: Ic79191c316d986fc6072ecaebfec9d5f2b924d00 +--- + tensorflow/lite/kernels/batch_to_space_nd.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/batch_to_space_nd.cc b/tensorflow/lite/kernels/batch_to_space_nd.cc +index 9d6492e0fcbf0..044ac1b3a5ee5 100644 +--- a/tensorflow/lite/kernels/batch_to_space_nd.cc ++++ b/tensorflow/lite/kernels/batch_to_space_nd.cc +@@ -78,6 +78,7 @@ TfLiteStatus ResizeOutputTensor(TfLiteContext* context, + int output_batch_size = input_size->data[0]; + for (int dim = 0; dim < spatial_dims_num; ++dim) { + // Number of batch must be multiple of (block_shape[dim]). ++ TF_LITE_ENSURE(context, block_shape[dim] != 0); + TF_LITE_ENSURE_EQ(context, output_batch_size % block_shape[dim], 0); + output_batch_size = output_batch_size / block_shape[dim]; + output_size->data[dim + 1] = input_size->data[dim + 1] * block_shape[dim] - diff --git a/CVE-2021-29596.patch b/CVE-2021-29596.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e424ae208966607af127db02c8c45c6229e5ab5 --- /dev/null +++ b/CVE-2021-29596.patch @@ -0,0 +1,26 @@ +From f61c57bd425878be108ec787f4d96390579fb83e Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 12:57:00 -0700 +Subject: [PATCH] Prevent division by 0 + +PiperOrigin-RevId: 370966645 +Change-Id: I831bfd96c7eb77b02d7ebb744335f59f6e5728cb +--- + tensorflow/lite/kernels/embedding_lookup.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/lite/kernels/embedding_lookup.cc b/tensorflow/lite/kernels/embedding_lookup.cc +index d865f69eb9bd3..092868d5a6a74 100644 +--- a/tensorflow/lite/kernels/embedding_lookup.cc ++++ b/tensorflow/lite/kernels/embedding_lookup.cc +@@ -71,6 +71,10 @@ TfLiteStatus EvalSimple(TfLiteContext* context, TfLiteNode* node, + const TfLiteTensor* lookup, const TfLiteTensor* value, + TfLiteTensor* output) { + const int row_size = SizeOfDimension(value, 0); ++ if (row_size == 0) { ++ // Propagate empty tensor if input is empty ++ return kTfLiteOk; ++ } + const int row_bytes = value->bytes / row_size; + + char* output_raw = GetTensorData(output); diff --git a/CVE-2021-29597.patch b/CVE-2021-29597.patch new file mode 100644 index 0000000000000000000000000000000000000000..47a82932be485cc1836ed2c25a979dfa84690917 --- /dev/null +++ b/CVE-2021-29597.patch @@ -0,0 +1,23 @@ +From 6d36ba65577006affb272335b7c1abd829010708 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 14:22:30 -0700 +Subject: [PATCH] Prevent division by 0 + +PiperOrigin-RevId: 370984990 +Change-Id: Ib324955bbeb1cbd97c82fd5d61a00a2697c9a2de +--- + tensorflow/lite/kernels/space_to_batch_nd.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/space_to_batch_nd.cc b/tensorflow/lite/kernels/space_to_batch_nd.cc +index 0d537e2d1892f..af7b9d9e914a1 100644 +--- a/tensorflow/lite/kernels/space_to_batch_nd.cc ++++ b/tensorflow/lite/kernels/space_to_batch_nd.cc +@@ -79,6 +79,7 @@ TfLiteStatus ResizeOutputTensor(TfLiteContext* context, + for (int dim = 0; dim < spatial_dims_num; ++dim) { + int final_dim_size = (input_size->data[dim + 1] + paddings_data[dim * 2] + + paddings_data[dim * 2 + 1]); ++ TF_LITE_ENSURE(context, block_shape[dim] != 0); + TF_LITE_ENSURE_EQ(context, final_dim_size % block_shape[dim], 0); + output_size->data[dim + 1] = final_dim_size / block_shape[dim]; + output_batch_size *= block_shape[dim]; diff --git a/CVE-2021-29598.patch b/CVE-2021-29598.patch new file mode 100644 index 0000000000000000000000000000000000000000..4f53de424088f8dacf2fdf2718602e523a130f1f --- /dev/null +++ b/CVE-2021-29598.patch @@ -0,0 +1,23 @@ +From 6841e522a3e7d48706a02e8819836e809f738682 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 15:13:03 -0700 +Subject: [PATCH] Prevent division by 0 + +PiperOrigin-RevId: 370995582 +Change-Id: I670ffaf52d1ff8823ec31ea5f438f9125b402223 +--- + tensorflow/lite/kernels/svdf.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/svdf.cc b/tensorflow/lite/kernels/svdf.cc +index 8f5c9a86bff5c..73024fd1e587a 100644 +--- a/tensorflow/lite/kernels/svdf.cc ++++ b/tensorflow/lite/kernels/svdf.cc +@@ -99,6 +99,7 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + const int rank = params->rank; + const int batch_size = input->dims->data[0]; + const int num_filters = weights_feature->dims->data[0]; ++ TF_LITE_ENSURE(context, rank != 0); + TF_LITE_ENSURE_EQ(context, num_filters % rank, 0); + const int num_units = num_filters / rank; + const int memory_size = weights_time->dims->data[1]; diff --git a/CVE-2021-29599.patch b/CVE-2021-29599.patch new file mode 100644 index 0000000000000000000000000000000000000000..68319e5b4ac3e5fd89ec2da2602027c25ebe4b9c --- /dev/null +++ b/CVE-2021-29599.patch @@ -0,0 +1,23 @@ +From b22786e7e9b7bdb6a56936ff29cc7e9968d7bc1d Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 15:31:26 -0700 +Subject: [PATCH] Prevent division by 0 + +PiperOrigin-RevId: 370998952 +Change-Id: I6b1d49079624ee1447d2d9b53a8976fb356cc8f5 +--- + tensorflow/lite/kernels/split.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/split.cc b/tensorflow/lite/kernels/split.cc +index be7425cc0b5e2..cf778b0b95124 100644 +--- a/tensorflow/lite/kernels/split.cc ++++ b/tensorflow/lite/kernels/split.cc +@@ -60,6 +60,7 @@ TfLiteStatus ResizeOutputTensors(TfLiteContext* context, TfLiteNode* node, + TF_LITE_ENSURE(context, axis_value < NumDimensions(input)); + + const int input_size = SizeOfDimension(input, axis_value); ++ TF_LITE_ENSURE(context, num_splits != 0); + TF_LITE_ENSURE_MSG(context, input_size % num_splits == 0, + "Not an even split"); + const int slice_size = input_size / num_splits; diff --git a/CVE-2021-29600.patch b/CVE-2021-29600.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ce1104639b74ad575b6a544d5a6a085691bf172 --- /dev/null +++ b/CVE-2021-29600.patch @@ -0,0 +1,29 @@ +From 3ebedd7e345453d68e279cfc3e4072648e5e12e5 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 12:58:07 -0700 +Subject: [PATCH] Prevent division by 0 in OneHot implementation + +If input indices is degenerate, the implementation would do a divide by zero. See https://github.com/tensorflow/tensorflow/blob/745d57df6d5e9bc568666a2a48ed8dd629c27241/tensorflow/lite/kernels/one_hot.cc#L68-L72 + +PiperOrigin-RevId: 370966870 +Change-Id: Ie018337811c8016b5a1d3a277d00d5f2e19a2058 +--- + tensorflow/lite/kernels/one_hot.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/lite/kernels/one_hot.cc b/tensorflow/lite/kernels/one_hot.cc +index f7b4e8e7e19d5..75bfb48d6b19c 100644 +--- a/tensorflow/lite/kernels/one_hot.cc ++++ b/tensorflow/lite/kernels/one_hot.cc +@@ -69,6 +69,11 @@ void OneHotComputeImpl(const OneHotContext& op_context) { + for (int i = 0; i < op_context.axis; ++i) { + prefix_dim_size *= op_context.indices->dims->data[i]; + } ++ if (prefix_dim_size == 0) { ++ // If indices tensor is degenerate, return a degenerate tensor, just like ++ // TensorFlow does. ++ return; ++ } + const int suffix_dim_size = NumElements(op_context.indices) / prefix_dim_size; + const int depth = *op_context.depth->data.i32; + diff --git a/CVE-2021-29601.patch b/CVE-2021-29601.patch new file mode 100644 index 0000000000000000000000000000000000000000..de189c410259fce4598ce3dfd6f5909979b0f5b6 --- /dev/null +++ b/CVE-2021-29601.patch @@ -0,0 +1,35 @@ +From 4253f96a58486ffe84b61c0415bb234a4632ee73 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 16:50:55 -0700 +Subject: [PATCH] Fix integer overflow in TFLite concat + +PiperOrigin-RevId: 371013841 +Change-Id: I6a4782ce7ca753e23ff31e7fb6aeb7f9d412cd29 +--- + tensorflow/lite/kernels/concatenation.cc | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tensorflow/lite/kernels/concatenation.cc b/tensorflow/lite/kernels/concatenation.cc +index 61596a4ff0661..75bcd9403c0ae 100644 +--- a/tensorflow/lite/kernels/concatenation.cc ++++ b/tensorflow/lite/kernels/concatenation.cc +@@ -16,6 +16,8 @@ limitations under the License. + + #include + ++#include ++ + #include "tensorflow/lite/c/builtin_op_data.h" + #include "tensorflow/lite/c/common.h" + #include "tensorflow/lite/kernels/internal/compatibility.h" +@@ -69,6 +71,10 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TF_LITE_ENSURE_EQ(context, t->type, input_type); + for (int d = 0; d < t0->dims->size; ++d) { + if (d == axis) { ++ // Avoid integer overflow in sum_axis below ++ TF_LITE_ENSURE(context, t->dims->data[axis] >= 0); ++ TF_LITE_ENSURE(context, t->dims->data[axis] <= ++ std::numeric_limits::max() - sum_axis); + sum_axis += t->dims->data[axis]; + } else { + TF_LITE_ENSURE_EQ(context, t->dims->data[d], t0->dims->data[d]); diff --git a/CVE-2021-29603.patch b/CVE-2021-29603.patch new file mode 100644 index 0000000000000000000000000000000000000000..286374d971908665fbf7ad9a404e7e2b60fcb2e8 --- /dev/null +++ b/CVE-2021-29603.patch @@ -0,0 +1,27 @@ +From c59c37e7b2d563967da813fa50fe20b21f4da683 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 17:50:10 -0700 +Subject: [PATCH] Prevent array write out-of-bounds. + +If user passes an invalid axis, then we copy one too many dimensions to the output in the loop below these checks. Even if we didn't do that, there will be further issues with an invalid axis, so we check for that right now. + +PiperOrigin-RevId: 371023299 +Change-Id: I9eca37ffc2b29e8e48710f500701270ef0790224 +--- + tensorflow/lite/kernels/arg_min_max.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/lite/kernels/arg_min_max.cc b/tensorflow/lite/kernels/arg_min_max.cc +index a0ba8cb9f8bbe..291fd61681f2a 100644 +--- a/tensorflow/lite/kernels/arg_min_max.cc ++++ b/tensorflow/lite/kernels/arg_min_max.cc +@@ -48,6 +48,9 @@ TfLiteStatus ResizeOutput(TfLiteContext* context, const TfLiteTensor* input, + axis_value += NumDimensions(input); + } + ++ TF_LITE_ENSURE(context, axis_value >= 0); ++ TF_LITE_ENSURE(context, axis_value < NumDimensions(input)); ++ + // Copy the input dimensions to output except the axis dimension. + TfLiteIntArray* output_dims = TfLiteIntArrayCreate(NumDimensions(input) - 1); + int j = 0; diff --git a/CVE-2021-29605.patch b/CVE-2021-29605.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a63575a72349063fccc47ef028d4aa087ae7c28 --- /dev/null +++ b/CVE-2021-29605.patch @@ -0,0 +1,42 @@ +From 7c8cc4ec69cd348e44ad6a2699057ca88faad3e5 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Apr 2021 19:43:09 -0700 +Subject: [PATCH] Fix a dangerous integer overflow and a malloc of negative + size. + +PiperOrigin-RevId: 371254154 +Change-Id: I250a98a3df26328770167025670235a963a72da0 +--- + tensorflow/lite/c/common.c | 6 ++++-- + tensorflow/lite/kernels/embedding_lookup_sparse.cc | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/tensorflow/lite/c/common.c b/tensorflow/lite/c/common.c +index aaa98a98ebe69..00dd0260cbcc9 100644 +--- a/tensorflow/lite/c/common.c ++++ b/tensorflow/lite/c/common.c +@@ -45,8 +45,10 @@ int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size, + #ifndef TF_LITE_STATIC_MEMORY + + TfLiteIntArray* TfLiteIntArrayCreate(int size) { +- TfLiteIntArray* ret = +- (TfLiteIntArray*)malloc(TfLiteIntArrayGetSizeInBytes(size)); ++ int alloc_size = TfLiteIntArrayGetSizeInBytes(size); ++ if (alloc_size <= 0) return NULL; ++ TfLiteIntArray* ret = (TfLiteIntArray*)malloc(alloc_size); ++ if (!ret) return ret; + ret->size = size; + return ret; + } +diff --git a/tensorflow/lite/kernels/embedding_lookup_sparse.cc b/tensorflow/lite/kernels/embedding_lookup_sparse.cc +index e9ad7e50cf133..4ad1054340c9c 100644 +--- a/tensorflow/lite/kernels/embedding_lookup_sparse.cc ++++ b/tensorflow/lite/kernels/embedding_lookup_sparse.cc +@@ -173,6 +173,7 @@ TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + + // Resize output tensor. + TfLiteIntArray* output_shape = TfLiteIntArrayCreate(output_rank); ++ TF_LITE_ENSURE(context, output_shape != nullptr); + int k = 0; + int embedding_size = 1; + int lookup_size = 1; diff --git a/CVE-2021-29606.patch b/CVE-2021-29606.patch new file mode 100644 index 0000000000000000000000000000000000000000..5014d0d1b35128b3a00f9d6deb048ecf9b1884cb --- /dev/null +++ b/CVE-2021-29606.patch @@ -0,0 +1,24 @@ +From ae2daeb45abfe2c6dda539cf8d0d6f653d3ef412 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Wed, 28 Apr 2021 18:12:15 -0700 +Subject: [PATCH] Prevent array OOB read/write + +PiperOrigin-RevId: 371026165 +Change-Id: I26ac6372c87246e03c7eb8c94e84c84d86054b36 +--- + tensorflow/lite/kernels/split_v.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/lite/kernels/split_v.cc b/tensorflow/lite/kernels/split_v.cc +index 054e00572f5a6..ed8a4851c1e97 100644 +--- a/tensorflow/lite/kernels/split_v.cc ++++ b/tensorflow/lite/kernels/split_v.cc +@@ -96,6 +96,8 @@ TfLiteStatus ResizeOutputTensors(TfLiteContext* context, TfLiteNode* node, + } + } + ++ TF_LITE_ENSURE(context, axis_value >= 0); ++ TF_LITE_ENSURE(context, axis_value < NumDimensions(input)); + const int input_size = SizeOfDimension(input, axis_value); + + if (minus_one_index != -1) { diff --git a/CVE-2021-29607-1.patch b/CVE-2021-29607-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..bce68606bd8f588131e6a0e7d59b66b295131189 --- /dev/null +++ b/CVE-2021-29607-1.patch @@ -0,0 +1,27 @@ +From ba6822bd7b7324ba201a28b2f278c29a98edbef2 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Wed, 28 Apr 2021 16:06:54 -0700 +Subject: [PATCH] Fix OOB issue with `tf.raw_ops.SparseSparseMinimum`. + +PiperOrigin-RevId: 371005787 +Change-Id: Ib686ccc077836e8b980b8b5a03936d36a8ecaf71 +--- + tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc b/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc +index 43dc9ae70cd62..9fe42e05d879e 100644 +--- a/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc ++++ b/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc +@@ -180,6 +180,11 @@ class SparseSparseBinaryOpShared : public OpKernel { + " for dimension ", i)); + } + ++ OP_REQUIRES( ++ ctx, a_indices_t->dim_size(1) == b_indices_t->dim_size(1), ++ errors::InvalidArgument( ++ "Indices' dimensions do not match: got ", a_indices_t->dim_size(1), ++ " and ", b_indices_t->dim_size(1), " for the second dimension.")); + const int num_dims = a_indices_t->dim_size(1); + const auto a_indices_mat = a_indices_t->matrix(); + const auto b_indices_mat = b_indices_t->matrix(); diff --git a/CVE-2021-29607-2.patch b/CVE-2021-29607-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..31ba1a1fefac43be7fbb39cf4e054b371028e87e --- /dev/null +++ b/CVE-2021-29607-2.patch @@ -0,0 +1,51 @@ +From f6fde895ef9c77d848061c0517f19d0ec2682f3a Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 11 May 2021 18:32:03 -0700 +Subject: [PATCH] Validate that a and b are proper sparse tensors + +PiperOrigin-RevId: 373274848 +Change-Id: I3a665ac3a29dee9fb69bdf408a939330cb93ea75 +--- + .../kernels/sparse_sparse_binary_op_shared.cc | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc b/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc +index 9fe42e05d879e..eb993a5965043 100644 +--- a/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc ++++ b/tensorflow/core/kernels/sparse_sparse_binary_op_shared.cc +@@ -150,6 +150,7 @@ class SparseSparseBinaryOpShared : public OpKernel { + + const int64 a_nnz = a_indices_t->dim_size(0); + const int64 b_nnz = b_indices_t->dim_size(0); ++ + const auto a_values = a_values_t->vec(); + const auto b_values = b_values_t->vec(); + +@@ -166,6 +167,14 @@ class SparseSparseBinaryOpShared : public OpKernel { + "Input shapes should be a vector but received shapes ", + a_shape_t->shape().DebugString(), " and ", + b_shape_t->shape().DebugString())); ++ const int num_dims = a_indices_t->dim_size(1); ++ OP_REQUIRES( ++ ctx, a_shape_t->NumElements() == num_dims, ++ errors::InvalidArgument("Second dimension of a_indices and length of " ++ "a_shape must match, got ", ++ num_dims, " and ", a_shape_t->NumElements())); ++ OP_REQUIRES(ctx, num_dims > 0, ++ errors::InvalidArgument("Tensors must not be empty")); + OP_REQUIRES(ctx, a_shape_t->IsSameSize(*b_shape_t), + errors::InvalidArgument( + "Operands do not have the same ranks; got shapes: ", +@@ -180,12 +189,6 @@ class SparseSparseBinaryOpShared : public OpKernel { + " for dimension ", i)); + } + +- OP_REQUIRES( +- ctx, a_indices_t->dim_size(1) == b_indices_t->dim_size(1), +- errors::InvalidArgument( +- "Indices' dimensions do not match: got ", a_indices_t->dim_size(1), +- " and ", b_indices_t->dim_size(1), " for the second dimension.")); +- const int num_dims = a_indices_t->dim_size(1); + const auto a_indices_mat = a_indices_t->matrix(); + const auto b_indices_mat = b_indices_t->matrix(); + std::vector a_augmented_values, b_augmented_values; diff --git a/CVE-2021-29608-1.patch b/CVE-2021-29608-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..d3aa918a975307600320ed43a6cfb582741e8f38 --- /dev/null +++ b/CVE-2021-29608-1.patch @@ -0,0 +1,72 @@ +From b761c9b652af2107cfbc33efd19be0ce41daa33e Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Thu, 15 Apr 2021 13:28:49 -0700 +Subject: [PATCH] Fix `tf.raw_ops.RaggedTensorToTensor` failing CHECK. + +PiperOrigin-RevId: 368706628 +Change-Id: I5c9ea4833f38835ee183ca50d63251dc89c9f3bc +--- + .../kernels/ragged_tensor_to_tensor_op.cc | 20 ++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc b/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc +index 433d910f6090c..434c853b63daa 100644 +--- a/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc ++++ b/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc +@@ -208,7 +208,7 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + } + + void CalculateOutputIndexRowSplit( +- const RowPartitionTensor& row_split, ++ OpKernelContext* context, const RowPartitionTensor& row_split, + const vector& parent_output_index, + INDEX_TYPE output_index_multiplier, INDEX_TYPE output_size, + vector* result) { +@@ -233,7 +233,8 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + } + } + if (row_split_size > 0) { +- DCHECK_EQ(result->size(), row_split(row_split_size - 1)); ++ OP_REQUIRES(context, result->size() == row_split(row_split_size - 1), ++ errors::InvalidArgument("Invalid row split size.")); + } + } + +@@ -259,7 +260,7 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + // result[7] = -1 because parent_output_index[value_rowids[6]] == -1 + // result[8] = parent_output_index[value_rowids[7]] + void CalculateOutputIndexValueRowID( +- const RowPartitionTensor& value_rowids, ++ OpKernelContext* context, const RowPartitionTensor& value_rowids, + const vector& parent_output_index, + INDEX_TYPE output_index_multiplier, INDEX_TYPE output_size, + vector* result) { +@@ -293,7 +294,8 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + } + result->push_back(current_output_index); + } +- DCHECK_EQ(result->size(), value_rowids.size()); ++ OP_REQUIRES(context, result->size() == value_rowids.size(), ++ errors::InvalidArgument("Invalid row ids.")); + } + + Status CalculateOutputIndex(OpKernelContext* context, int dimension, +@@ -307,13 +309,13 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + switch (partition_type) { + case RowPartitionType::VALUE_ROWIDS: + CalculateOutputIndexValueRowID( +- row_partition_tensor, parent_output_index, output_index_multiplier, +- output_size, result); ++ context, row_partition_tensor, parent_output_index, ++ output_index_multiplier, output_size, result); + return tensorflow::Status::OK(); + case RowPartitionType::ROW_SPLITS: +- CalculateOutputIndexRowSplit(row_partition_tensor, parent_output_index, +- output_index_multiplier, output_size, +- result); ++ CalculateOutputIndexRowSplit( ++ context, row_partition_tensor, parent_output_index, ++ output_index_multiplier, output_size, result); + return tensorflow::Status::OK(); + default: + return errors::InvalidArgument( diff --git a/CVE-2021-29608-2.patch b/CVE-2021-29608-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..85137c402455777766fceeb5b5e655cbb2f0dd35 --- /dev/null +++ b/CVE-2021-29608-2.patch @@ -0,0 +1,28 @@ +From f94ef358bb3e91d517446454edff6535bcfe8e4a Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Tue, 13 Apr 2021 14:54:18 -0700 +Subject: [PATCH] Fix `tf.raw_ops.RaggedTensorToTensor` failing CHECK in + `tensor.cc`. + +PiperOrigin-RevId: 368300502 +Change-Id: I91255d23c4bfd3aa3c029aac773937c09daf3c64 +--- + tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc b/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc +index 28898c65ca797..433d910f6090c 100644 +--- a/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc ++++ b/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc +@@ -345,6 +345,11 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + + void Compute(OpKernelContext* context) override { + INDEX_TYPE first_dimension; ++ const Tensor first_partition_tensor = ++ context->input(kFirstPartitionInputIndex); ++ OP_REQUIRES(context, first_partition_tensor.NumElements() > 0, ++ errors::InvalidArgument("Invalid first partition input. Tensor " ++ "requires at least one element.")); + OP_REQUIRES_OK(context, GetFirstDimensionSize(context, &first_dimension)); + vector output_size; + OP_REQUIRES_OK(context, diff --git a/CVE-2021-29609.patch b/CVE-2021-29609.patch new file mode 100644 index 0000000000000000000000000000000000000000..c34eedc7490340d808d0a78550bf8cdbb6078ea0 --- /dev/null +++ b/CVE-2021-29609.patch @@ -0,0 +1,34 @@ +From 6fd02f44810754ae7481838b6a67c5df7f909ca3 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Mon, 26 Apr 2021 16:40:49 -0700 +Subject: [PATCH] Fix `tf.raw_ops.SparseAdd ` invalid memory access failure. + +PiperOrigin-RevId: 370568774 +Change-Id: I5f73b31c865f2948a1c8dfb7ebd22b3cfb6405bf +--- + tensorflow/core/kernels/sparse_add_op.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/sparse_add_op.cc b/tensorflow/core/kernels/sparse_add_op.cc +index 0cf40a709a39a..346206365af8d 100644 +--- a/tensorflow/core/kernels/sparse_add_op.cc ++++ b/tensorflow/core/kernels/sparse_add_op.cc +@@ -14,6 +14,7 @@ limitations under the License. + ==============================================================================*/ + + #include "tensorflow/core/framework/op_kernel.h" ++#include "tensorflow/core/framework/op_requires.h" + #include "tensorflow/core/framework/register_types.h" + #include "tensorflow/core/framework/tensor.h" + #include "tensorflow/core/framework/tensor_util.h" +@@ -101,6 +102,10 @@ class SparseAddOp : public OpKernel { + std::vector out_values; + const int num_dims = a_shape->dim_size(0); + ++ OP_REQUIRES(ctx, num_dims > 0, ++ errors::InvalidArgument("Invalid input_a shape. Received: ", ++ a_shape->DebugString())); ++ + // The input and output sparse tensors are assumed to be ordered along + // increasing dimension number. + int64 i = 0, j = 0; diff --git a/CVE-2021-29613-1.patch b/CVE-2021-29613-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..af59d5fbf57d1f5886a24fba0b6328685d2c5b8f --- /dev/null +++ b/CVE-2021-29613-1.patch @@ -0,0 +1,25 @@ +From 14607c0707040d775e06b6817325640cb4b5864c Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Wed, 5 May 2021 21:09:21 -0700 +Subject: [PATCH] Fix nullptr deref in `tf.raw_ops.CTCLoss`. + +PiperOrigin-RevId: 372266334 +Change-Id: Ic52c3e9f13a38f54482d670907eda1688450862b +--- + tensorflow/core/kernels/ctc_loss_op.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/ctc_loss_op.cc b/tensorflow/core/kernels/ctc_loss_op.cc +index b0e298a0f329f..ca505e1db9314 100644 +--- a/tensorflow/core/kernels/ctc_loss_op.cc ++++ b/tensorflow/core/kernels/ctc_loss_op.cc +@@ -109,6 +109,9 @@ class CTCLossOp : public OpKernel { + + const TensorShape& inputs_shape = inputs->shape(); + const int64 max_time = inputs_shape.dim_size(0); ++ OP_REQUIRES(ctx, max_time != 0, ++ errors::InvalidArgument( ++ "Max time or first dimension of input cannot be 0.")); + const int64 batch_size = inputs_shape.dim_size(1); + const int64 num_classes_raw = inputs_shape.dim_size(2); + OP_REQUIRES( diff --git a/CVE-2021-29613-2.patch b/CVE-2021-29613-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..726db69722ca372dc1edb37f7982a976e2daf7eb --- /dev/null +++ b/CVE-2021-29613-2.patch @@ -0,0 +1,26 @@ +From 4504a081af71514bb1828048363e6540f797005b Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Wed, 5 May 2021 17:33:47 -0700 +Subject: [PATCH] Fix OOB read issue with `tf.raw_ops.CTCLoss`. + +PiperOrigin-RevId: 372242187 +Change-Id: I347228ed8c04e1d2eb9d2479ae52f51d1b512c6e +--- + tensorflow/core/kernels/ctc_loss_op.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/ctc_loss_op.cc b/tensorflow/core/kernels/ctc_loss_op.cc +index 6358e82fdda85..b0e298a0f329f 100644 +--- a/tensorflow/core/kernels/ctc_loss_op.cc ++++ b/tensorflow/core/kernels/ctc_loss_op.cc +@@ -100,6 +100,10 @@ class CTCLossOp : public OpKernel { + errors::InvalidArgument("sequence_length is not a vector")); + OP_REQUIRES(ctx, TensorShapeUtils::IsMatrix(labels_indices->shape()), + errors::InvalidArgument("labels_indices is not a matrix")); ++ OP_REQUIRES(ctx, labels_indices->dim_size(1) > 1, ++ errors::InvalidArgument( ++ "labels_indices second dimension must be >= 1. Received ", ++ labels_indices->dim_size(1))); + OP_REQUIRES(ctx, TensorShapeUtils::IsVector(labels_values->shape()), + errors::InvalidArgument("labels_values is not a vector")); + diff --git a/CVE-2021-29615.patch b/CVE-2021-29615.patch new file mode 100644 index 0000000000000000000000000000000000000000..3cc05fced5725fbc4589e92d6325b253005e8cf4 --- /dev/null +++ b/CVE-2021-29615.patch @@ -0,0 +1,95 @@ +From e07e1c3d26492c06f078c7e5bf2d138043e199c1 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Fri, 23 Apr 2021 10:33:00 -0700 +Subject: [PATCH] Prevent memory overflow in ParseAttrValue from nested + tensors. + +PiperOrigin-RevId: 370108442 +Change-Id: I84d64a5e8895a6aeffbf4749841b4c54d51b5889 +--- + tensorflow/core/framework/attr_value_util.cc | 58 +++++++++++++++++++- + 1 file changed, 57 insertions(+), 1 deletion(-) + +diff --git a/tensorflow/core/framework/attr_value_util.cc b/tensorflow/core/framework/attr_value_util.cc +index 712e205c587c8..76fe36e7f1e2a 100644 +--- a/tensorflow/core/framework/attr_value_util.cc ++++ b/tensorflow/core/framework/attr_value_util.cc +@@ -38,6 +38,9 @@ namespace { + // Do not construct large tensors to compute their hash or compare for equality. + constexpr int kMaxAttrValueTensorByteSize = 32 * 1024 * 1024; // 32mb + ++// Limit nesting of tensors to 100 deep to prevent memory overflow. ++constexpr int kMaxTensorNestDepth = 100; ++ + // Return the size of the tensor represented by this TensorProto. If shape is + // not fully defined return -1. + int64 TensorByteSize(const TensorProto& t) { +@@ -224,6 +227,54 @@ string SummarizeFunc(const NameAttrList& func) { + return strings::StrCat(func.name(), "[", absl::StrJoin(entries, ", "), "]"); + } + ++bool ParseAttrValueHelper_TensorNestsUnderLimit(int limit, string to_parse) { ++ int nests = 0; ++ int maxed_out = to_parse.length(); ++ int open_curly = to_parse.find('{'); ++ int open_bracket = to_parse.find('<'); ++ int close_curly = to_parse.find('}'); ++ int close_bracket = to_parse.find('>'); ++ if (open_curly == -1) { ++ open_curly = maxed_out; ++ } ++ if (open_bracket == -1) { ++ open_bracket = maxed_out; ++ } ++ int min = std::min(open_curly, open_bracket); ++ do { ++ if (open_curly == maxed_out && open_bracket == maxed_out) { ++ return true; ++ } ++ if (min == open_curly) { ++ nests += 1; ++ open_curly = to_parse.find('{', open_curly + 1); ++ if (open_curly == -1) { ++ open_curly = maxed_out; ++ } ++ } else if (min == open_bracket) { ++ nests += 1; ++ open_bracket = to_parse.find('<', open_bracket + 1); ++ if (open_bracket == -1) { ++ open_bracket = maxed_out; ++ } ++ } else if (min == close_curly) { ++ nests -= 1; ++ close_curly = to_parse.find('}', close_curly + 1); ++ if (close_curly == -1) { ++ close_curly = maxed_out; ++ } ++ } else if (min == close_bracket) { ++ nests -= 1; ++ close_bracket = to_parse.find('>', close_bracket + 1); ++ if (close_bracket == -1) { ++ close_bracket = maxed_out; ++ } ++ } ++ min = std::min({open_curly, open_bracket, close_curly, close_bracket}); ++ } while (nests < 100); ++ return false; ++} ++ + } // namespace + + string SummarizeAttrValue(const AttrValue& attr_value) { +@@ -448,7 +499,12 @@ bool ParseAttrValue(StringPiece type, StringPiece text, AttrValue* out) { + } else { + to_parse = strings::StrCat(field_name, ": ", text); + } +- ++ if (field_name == "tensor") { ++ if (!ParseAttrValueHelper_TensorNestsUnderLimit(kMaxTensorNestDepth, ++ to_parse)) { ++ return false; ++ } ++ } + return ProtoParseFromString(to_parse, out); + } + diff --git a/CVE-2021-29616.patch b/CVE-2021-29616.patch new file mode 100644 index 0000000000000000000000000000000000000000..90d3253d01201f8e2ea3325bda273e92b5192760 --- /dev/null +++ b/CVE-2021-29616.patch @@ -0,0 +1,60 @@ +From e6340f0665d53716ef3197ada88936c2a5f7a2d3 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 19 Apr 2021 09:57:01 -0700 +Subject: [PATCH] Handle a special grappler case resulting in crash. + +It might happen that a malformed input could be used to trick Grappler into trying to optimize a node with no inputs. This, in turn, would produce a null pointer dereference and a segfault. + +PiperOrigin-RevId: 369242852 +Change-Id: I2e5cbe7aec243d34a6d60220ac8ac9b16f136f6b +--- + .../core/grappler/optimizers/arithmetic_optimizer.cc | 11 +++++++++++ + .../core/grappler/optimizers/dependency_optimizer.cc | 6 ++++++ + 2 files changed, 17 insertions(+) + +diff --git a/tensorflow/core/grappler/optimizers/arithmetic_optimizer.cc b/tensorflow/core/grappler/optimizers/arithmetic_optimizer.cc +index 484983a7a549c..774fdf3484788 100644 +--- a/tensorflow/core/grappler/optimizers/arithmetic_optimizer.cc ++++ b/tensorflow/core/grappler/optimizers/arithmetic_optimizer.cc +@@ -2047,6 +2047,12 @@ class ReorderCastLikeAndValuePreserving : public ArithmeticOptimizerStage { + + Status TrySimplify(NodeDef* consumer, string* simplified_node_name) override { + NodeDef* producer; ++ ++ if (consumer->input_size() < 1) { ++ return errors::FailedPrecondition("Node ", simplified_node_name, ++ " lacks inputs"); ++ } ++ + TF_RETURN_IF_ERROR(GetInputNode(consumer->input(0), &producer)); + const bool producer_is_cast = IsCastLike(*producer); + const bool can_optimize = +@@ -2538,6 +2544,11 @@ class ReplaceMulWithSquare : public ArithmeticOptimizerStage { + ~ReplaceMulWithSquare() override = default; + + bool IsSupported(const NodeDef* node) const override { ++ if (!node || node->input_size() < 2) { ++ // Invalid node ++ return false; ++ } ++ + return IsAnyMul(*node) && node->input(0) == node->input(1); + } + +diff --git a/tensorflow/core/grappler/optimizers/dependency_optimizer.cc b/tensorflow/core/grappler/optimizers/dependency_optimizer.cc +index 332d2d4e6d966..1be7f2692e0f7 100644 +--- a/tensorflow/core/grappler/optimizers/dependency_optimizer.cc ++++ b/tensorflow/core/grappler/optimizers/dependency_optimizer.cc +@@ -68,6 +68,12 @@ bool DependencyOptimizer::SafeToRemoveIdentity(const NodeDef& node) const { + // The output values of this node may be needed. + return false; + } ++ ++ if (node.input_size() < 1) { ++ // Node lacks input, is invalid ++ return false; ++ } ++ + const NodeDef* input = node_map_->GetNode(NodeName(node.input(0))); + CHECK(input != nullptr) << "node = " << node.name() + << " input = " << node.input(0); diff --git a/CVE-2021-29617.patch b/CVE-2021-29617.patch new file mode 100644 index 0000000000000000000000000000000000000000..1ea7b758d02c7fafeb057dcb179646ea741db8ca --- /dev/null +++ b/CVE-2021-29617.patch @@ -0,0 +1,59 @@ +From 7edb8c9b83ad583616406af61e0de61393996a3e Mon Sep 17 00:00:00 2001 +From: Yong Tang +Date: Sat, 6 Feb 2021 20:24:54 +0000 +Subject: [PATCH] Fix crash of tf.strings.substr when pos and len have + different shapes + +This PR tries to address the issue raised in 46900 where +tf.strings.substr will crash when pos and len have different shapes. +According to the documentation of tf.strings.substr, ValueError +should be raised instead when pos and len does not have the same shape. + +This PR add shape check in kernel to allows grace error throw (instead of crash). + +This PR fixes 46900. + +Signed-off-by: Yong Tang +--- + tensorflow/core/kernels/substr_op.cc | 6 ++++++ + tensorflow/python/kernel_tests/substr_op_test.py | 10 ++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/tensorflow/core/kernels/substr_op.cc b/tensorflow/core/kernels/substr_op.cc +index e382381e12232..0c94ba35b249a 100644 +--- a/tensorflow/core/kernels/substr_op.cc ++++ b/tensorflow/core/kernels/substr_op.cc +@@ -51,6 +51,12 @@ class SubstrOp : public OpKernel { + const Tensor& len_tensor = context->input(2); + const TensorShape& input_shape = input_tensor.shape(); + const TensorShape& pos_shape = pos_tensor.shape(); ++ const TensorShape& len_shape = len_tensor.shape(); ++ OP_REQUIRES( ++ context, (pos_shape == len_shape), ++ errors::InvalidArgument("pos and len should have the same shape, got: ", ++ pos_shape.DebugString(), " vs. ", ++ len_shape.DebugString())); + + bool is_scalar = TensorShapeUtils::IsScalar(pos_shape); + +diff --git a/tensorflow/python/kernel_tests/substr_op_test.py b/tensorflow/python/kernel_tests/substr_op_test.py +index 9302152e82bfa..ad7b6050c2901 100644 +--- a/tensorflow/python/kernel_tests/substr_op_test.py ++++ b/tensorflow/python/kernel_tests/substr_op_test.py +@@ -492,6 +492,16 @@ def testInvalidUnit(self): + with self.assertRaises(ValueError): + string_ops.substr(b"test", 3, 1, unit="UTF8") + ++ def testInvalidPos(self): ++ # Test case for GitHub issue 46900. ++ with self.assertRaises((ValueError, errors_impl.InvalidArgumentError)): ++ x = string_ops.substr(b"abc", len=1, pos=[1, -1]) ++ self.evaluate(x) ++ ++ with self.assertRaises((ValueError, errors_impl.InvalidArgumentError)): ++ x = string_ops.substr(b"abc", len=1, pos=[1, 2]) ++ self.evaluate(x) ++ + + if __name__ == "__main__": + test.main() diff --git a/CVE-2021-29619.patch b/CVE-2021-29619.patch new file mode 100644 index 0000000000000000000000000000000000000000..62cca66805b36e559133bac2418c8392d7fe5c63 --- /dev/null +++ b/CVE-2021-29619.patch @@ -0,0 +1,41 @@ +From 82e6203221865de4008445b13c69b6826d2b28d9 Mon Sep 17 00:00:00 2001 +From: Amit Patankar +Date: Tue, 2 Mar 2021 17:02:03 -0800 +Subject: [PATCH] Fix segfaults in `tf.raw_ops.SparseCountSparseOutput`. + +PiperOrigin-RevId: 360547563 +Change-Id: I781c7af4b54a63d867c6e18d43a44d64a5c4e7c9 +--- + tensorflow/core/kernels/count_ops.cc | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/tensorflow/core/kernels/count_ops.cc b/tensorflow/core/kernels/count_ops.cc +index 087deef0812f0..d6ab68c2c70bd 100644 +--- a/tensorflow/core/kernels/count_ops.cc ++++ b/tensorflow/core/kernels/count_ops.cc +@@ -192,6 +192,10 @@ class SparseCount : public OpKernel { + "; values shape: ", values.shape().DebugString())); + } + ++ OP_REQUIRES(context, shape.NumElements() != 0, ++ errors::InvalidArgument( ++ "The shape argument requires at least one element.")); ++ + bool is_1d = shape.NumElements() == 1; + int num_batches = is_1d ? 1 : shape.flat()(0); + int num_values = values.NumElements(); +@@ -212,6 +216,14 @@ class SparseCount : public OpKernel { + + for (int idx = 0; idx < num_values; ++idx) { + int batch = is_1d ? 0 : indices_values(idx, 0); ++ if (batch >= num_batches) { ++ OP_REQUIRES(context, batch < num_batches, ++ errors::InvalidArgument( ++ "Indices value along the first dimension must be ", ++ "lower than the first index of the shape.", "Got ", ++ batch, " as batch and ", num_batches, ++ " as the first dimension of the shape.")); ++ } + const auto& value = values_values(idx); + if (value >= 0 && (maxlength_ <= 0 || value < maxlength_)) { + if (binary_output_) { diff --git a/CVE-2021-37637.patch b/CVE-2021-37637.patch new file mode 100644 index 0000000000000000000000000000000000000000..92bd45bd1ad55c2e097b9d77d6611416de0db800 --- /dev/null +++ b/CVE-2021-37637.patch @@ -0,0 +1,60 @@ +From 5dc7f6981fdaf74c8c5be41f393df705841fb7c5 Mon Sep 17 00:00:00 2001 +From: "A. Unique TensorFlower" +Date: Fri, 14 May 2021 22:07:07 -0700 +Subject: [PATCH] Fix accessing possible nullptr in + tensorflow::data::CompressElement and UncompressElement which are used in + tf.data.service. + +PiperOrigin-RevId: 373920841 +Change-Id: Ia88d78aee09fa19bb53a0f163fd19620d0c68743 +--- + tensorflow/core/data/compression_utils.cc | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/tensorflow/core/data/compression_utils.cc b/tensorflow/core/data/compression_utils.cc +index bbff3a96667d1..40238a05a2614 100644 +--- a/tensorflow/core/data/compression_utils.cc ++++ b/tensorflow/core/data/compression_utils.cc +@@ -29,9 +29,10 @@ Status CompressElement(const std::vector& element, + int64 total_size = 0; + for (auto& component : element) { + if (DataTypeCanUseMemcpy(component.dtype())) { +- // Some datatypes can be memcopied, allowing us to save two copies +- // (AsProtoTensorContent and SerializeToArray). +- total_size += DMAHelper::buffer(&component)->size(); ++ const TensorBuffer* buffer = DMAHelper::buffer(&component); ++ if (buffer) { ++ total_size += buffer->size(); ++ } + } else { + non_memcpy_components.emplace_back(); + component.AsProtoTensorContent(&non_memcpy_components.back()); +@@ -53,8 +54,10 @@ Status CompressElement(const std::vector& element, + component.shape().AsProto(metadata->mutable_tensor_shape()); + if (DataTypeCanUseMemcpy(component.dtype())) { + const TensorBuffer* buffer = DMAHelper::buffer(&component); +- memcpy(position, buffer->data(), buffer->size()); +- metadata->set_tensor_size_bytes(buffer->size()); ++ if (buffer) { ++ memcpy(position, buffer->data(), buffer->size()); ++ metadata->set_tensor_size_bytes(buffer->size()); ++ } + } else { + TensorProto& proto = non_memcpy_components[non_memcpy_component_index++]; + proto.SerializeToArray(position, proto.ByteSizeLong()); +@@ -94,8 +97,13 @@ Status UncompressElement(const CompressedElement& compressed, + if (DataTypeCanUseMemcpy(metadata.dtype())) { + out->emplace_back(metadata.dtype(), metadata.tensor_shape()); + TensorBuffer* buffer = DMAHelper::buffer(&out->back()); +- iov[i].iov_base = buffer->data(); +- iov[i].iov_len = buffer->size(); ++ if (buffer) { ++ iov[i].iov_base = buffer->data(); ++ iov[i].iov_len = buffer->size(); ++ } else { ++ iov[i].iov_base = nullptr; ++ iov[i].iov_len = 0; ++ } + } else { + // Allocate an empty Tensor. We will fill it out later after + // uncompressing into the tensor_proto_str. diff --git a/CVE-2021-37638.patch b/CVE-2021-37638.patch new file mode 100644 index 0000000000000000000000000000000000000000..fac972fd442beab5d9de12cd1cee969f4e89c82c --- /dev/null +++ b/CVE-2021-37638.patch @@ -0,0 +1,25 @@ +From 301ae88b331d37a2a16159b65b255f4f9eb39314 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Mon, 12 Jul 2021 09:59:54 -0700 +Subject: [PATCH] Fix null ptr deref in tf.raw_ops.RaggedTensorToTensor + +PiperOrigin-RevId: 384257511 +Change-Id: I0484ad285039d132d6c41b284a7fcdd2b774a38e +--- + tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc b/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc +index b79a07e67ba91..1749a6e24784d 100644 +--- a/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc ++++ b/tensorflow/core/kernels/ragged_tensor_to_tensor_op.cc +@@ -348,6 +348,9 @@ class RaggedTensorToTensorBaseOp : public OpKernel { + Status GetFirstDimensionSize(OpKernelContext* context, INDEX_TYPE* result) { + const Tensor first_partition_tensor = + context->input(kFirstPartitionInputIndex); ++ if (row_partition_types_.empty()) { ++ return errors::InvalidArgument("No row_partition_types given."); ++ } + const RowPartitionType first_partition_type = row_partition_types_[0]; + switch (first_partition_type) { + case RowPartitionType::FIRST_DIM_SIZE: diff --git a/CVE-2021-37639.patch b/CVE-2021-37639.patch new file mode 100644 index 0000000000000000000000000000000000000000..b1e3e72cf8cb7434b80871e75848f930dbb132d3 --- /dev/null +++ b/CVE-2021-37639.patch @@ -0,0 +1,35 @@ +From 9e82dce6e6bd1f36a57e08fa85af213e2b2f2622 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 2 Aug 2021 14:21:41 -0700 +Subject: [PATCH] Fix NPE in restoring code. + +PiperOrigin-RevId: 388303253 +Change-Id: Ia8c68568cb854bca538909a182b31a618d68ce55 +--- + tensorflow/core/kernels/save_restore_tensor.cc | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/tensorflow/core/kernels/save_restore_tensor.cc b/tensorflow/core/kernels/save_restore_tensor.cc +index 953c1dfb6290b..dcbed428a5a5a 100644 +--- a/tensorflow/core/kernels/save_restore_tensor.cc ++++ b/tensorflow/core/kernels/save_restore_tensor.cc +@@ -151,11 +151,18 @@ void RestoreTensor(OpKernelContext* context, + context, size == 1, + errors::InvalidArgument( + "Input 0 (file_pattern) must be a string scalar; got a tensor of ", +- size, "elements")); ++ size, " elements")); + } + const string& file_pattern = file_pattern_t.flat()(0); + + const Tensor& tensor_name_t = context->input(1); ++ { ++ const int64_t size = tensor_name_t.NumElements(); ++ OP_REQUIRES(context, size > restore_index, ++ errors::InvalidArgument( ++ "Input 1 (file_pattern) must be a have at least ", ++ restore_index + 1, " elements")); ++ } + const string& tensor_name = tensor_name_t.flat()(restore_index); + + // If we cannot find a cached reader we will allocate our own. diff --git a/CVE-2021-37641.patch b/CVE-2021-37641.patch new file mode 100644 index 0000000000000000000000000000000000000000..002359381fec5f9e411bc57775de6579f708bbbb --- /dev/null +++ b/CVE-2021-37641.patch @@ -0,0 +1,38 @@ +From a2b743f6017d7b97af1fe49087ae15f0ac634373 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 2 Aug 2021 19:05:27 -0700 +Subject: [PATCH] Fix heap OOB in `tf.raw_ops.RaggedGather` + +PiperOrigin-RevId: 388355464 +Change-Id: If14d96231d1cd7aad7c4d1c22c1bab1576b75717 +--- + tensorflow/core/kernels/ragged_gather_op.cc | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/tensorflow/core/kernels/ragged_gather_op.cc b/tensorflow/core/kernels/ragged_gather_op.cc +index 3bf82cba050e3..d6d51c770bbb7 100644 +--- a/tensorflow/core/kernels/ragged_gather_op.cc ++++ b/tensorflow/core/kernels/ragged_gather_op.cc +@@ -58,15 +58,21 @@ class RaggedGatherOpBase : public OpKernel { + + void Compute(OpKernelContext* context) override { + // Get the input Tensors. ++ + OpInputList params_nested_splits_in; + OP_REQUIRES_OK(context, context->input_list("params_nested_splits", + ¶ms_nested_splits_in)); ++ OP_REQUIRES( ++ context, params_nested_splits_in.size() > 0, ++ errors::InvalidArgument("params_nested_splits must be non empty")); ++ + const Tensor& params_dense_values_in = + context->input(params_nested_splits_in.size()); + const Tensor& indices_in = + context->input(params_nested_splits_in.size() + 1); + +- DCHECK_GT(params_nested_splits_in.size(), 0); // Enforced by REGISTER_OP. ++ OP_REQUIRES(context, params_nested_splits_in[0].dims() > 0, ++ errors::InvalidArgument("Split tensors must not be scalars")); + SPLITS_TYPE num_params = params_nested_splits_in[0].dim_size(0) - 1; + OP_REQUIRES_OK(context, ValidateIndices(indices_in, num_params)); + diff --git a/CVE-2021-37644.patch b/CVE-2021-37644.patch new file mode 100644 index 0000000000000000000000000000000000000000..f60ab3c9d0a9df4c2f12a511e10f53eb3160bc93 --- /dev/null +++ b/CVE-2021-37644.patch @@ -0,0 +1,26 @@ +From 8a6e874437670045e6c7dc6154c7412b4a2135e2 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Fri, 9 Jul 2021 17:32:55 -0700 +Subject: [PATCH] Validate num_elements input in tf.raw_ops.TensorListReserve + +PiperOrigin-RevId: 383954564 +Change-Id: I454bd78eff85bc4f16ddb7e608596971cca47f8f +--- + tensorflow/core/kernels/list_kernels.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/list_kernels.cc b/tensorflow/core/kernels/list_kernels.cc +index 9a2f373f5ce0c..488e02337f707 100644 +--- a/tensorflow/core/kernels/list_kernels.cc ++++ b/tensorflow/core/kernels/list_kernels.cc +@@ -302,6 +302,10 @@ class TensorListReserve : public OpKernel { + PartialTensorShape element_shape; + OP_REQUIRES_OK(c, TensorShapeFromTensor(c->input(0), &element_shape)); + int32 num_elements = c->input(1).scalar()(); ++ OP_REQUIRES(c, num_elements >= 0, ++ errors::InvalidArgument("The num_elements to reserve must be a " ++ "non negative number, but got ", ++ num_elements)); + TensorList output; + output.element_shape = element_shape; + output.element_dtype = element_dtype_; diff --git a/CVE-2021-37646.patch b/CVE-2021-37646.patch new file mode 100644 index 0000000000000000000000000000000000000000..283cc6d6676a4c3849423d60fe6cfd3ec1f5ea6c --- /dev/null +++ b/CVE-2021-37646.patch @@ -0,0 +1,29 @@ +From c283e542a3f422420cfdb332414543b62fc4e4a5 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Tue, 27 Jul 2021 10:55:35 -0700 +Subject: [PATCH] Disallow negative ngram_widths values in + tf.raw_ops.StringNGrams + +PiperOrigin-RevId: 387148179 +Change-Id: I641395a09a208be72ef9b3ceb128cf8a83a0775b +--- + tensorflow/core/kernels/string_ngrams_op.cc | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tensorflow/core/kernels/string_ngrams_op.cc b/tensorflow/core/kernels/string_ngrams_op.cc +index 7008a1d766af2..97af9abc4454a 100644 +--- a/tensorflow/core/kernels/string_ngrams_op.cc ++++ b/tensorflow/core/kernels/string_ngrams_op.cc +@@ -53,6 +53,12 @@ class StringNGramsOp : public tensorflow::OpKernel { + } + + void Compute(tensorflow::OpKernelContext* context) override { ++ for (int ngram_width : ngram_widths_) { ++ OP_REQUIRES( ++ context, ngram_width > 0, ++ errors::InvalidArgument("ngram_widths must contain positive values")); ++ } ++ + const tensorflow::Tensor* data; + OP_REQUIRES_OK(context, context->input("data", &data)); + const auto& input_data = data->flat().data(); diff --git a/CVE-2021-37647.patch b/CVE-2021-37647.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c5260408e1d48097f78ee9a9bccbd88279e1571 --- /dev/null +++ b/CVE-2021-37647.patch @@ -0,0 +1,69 @@ +From 02cc160e29d20631de3859c6653184e3f876b9d7 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 3 Aug 2021 15:51:47 -0700 +Subject: [PATCH] Prevent nullptr deref in SparseTensorSliceDataset + +The arguments must determine a valid sparse tensor. This means that when indices are empty then the values must be empty too (and the reverse). + +Also added test, by modifying existing test with empty sparse tensor to now run with an invalid sparse tensor input. + +PiperOrigin-RevId: 388562757 +Change-Id: Id8b54cd7c2316025b4f9a77292c8fb5344d17609 +--- + .../data/sparse_tensor_slice_dataset_op.cc | 11 ++++++++++ + .../from_sparse_tensor_slices_test.py | 20 +++++++++++++++++++ + 2 files changed, 31 insertions(+) + +diff --git a/tensorflow/core/kernels/data/sparse_tensor_slice_dataset_op.cc b/tensorflow/core/kernels/data/sparse_tensor_slice_dataset_op.cc +index 00b71d41a7ca1..58bb4b0b6d806 100644 +--- a/tensorflow/core/kernels/data/sparse_tensor_slice_dataset_op.cc ++++ b/tensorflow/core/kernels/data/sparse_tensor_slice_dataset_op.cc +@@ -241,6 +241,17 @@ class SparseTensorSliceDatasetOp : public DatasetOpKernel { + errors::InvalidArgument( + "Input indices should be a matrix but received shape ", + indices->shape().DebugString())); ++ ++ const auto num_indices = indices->NumElements(); ++ const auto num_values = values->NumElements(); ++ if (num_indices == 0 || num_values == 0) { ++ OP_REQUIRES(ctx, num_indices == num_values, ++ errors::InvalidArgument( ++ "If indices or values are empty, the other one must also " ++ "be. Got indices of shape ", ++ indices->shape().DebugString(), " and values of shape ", ++ values->shape().DebugString())); ++ } + OP_REQUIRES(ctx, TensorShapeUtils::IsVector(values->shape()), + errors::InvalidArgument( + "Input values should be a vector but received shape ", +diff --git a/tensorflow/python/data/kernel_tests/from_sparse_tensor_slices_test.py b/tensorflow/python/data/kernel_tests/from_sparse_tensor_slices_test.py +index 25ecbf20680b3..8f93530010cae 100644 +--- a/tensorflow/python/data/kernel_tests/from_sparse_tensor_slices_test.py ++++ b/tensorflow/python/data/kernel_tests/from_sparse_tensor_slices_test.py +@@ -118,6 +118,26 @@ def testEmptySparseTensorSlices(self): + with self.assertRaises(errors.OutOfRangeError): + sess.run(get_next) + ++ @combinations.generate(combinations.combine(tf_api_version=1, mode=["graph"])) ++ def testEmptySparseTensorSlicesInvalid(self): ++ """Test a dataset based on invalid `tf.sparse.SparseTensor`.""" ++ st = array_ops.sparse_placeholder(dtypes.float64) ++ iterator = dataset_ops.make_initializable_iterator( ++ dataset_ops.Dataset.from_sparse_tensor_slices(st)) ++ init_op = iterator.initializer ++ ++ with self.cached_session() as sess: ++ # Test with an empty sparse tensor but with non empty values. ++ empty_indices = np.empty((0, 4), dtype=np.int64) ++ non_empty_values = [1, 2, 3, 4] ++ empty_dense_shape = [0, 4, 37, 9] ++ sparse_feed = sparse_tensor.SparseTensorValue(empty_indices, ++ non_empty_values, ++ empty_dense_shape) ++ # Here, we expect the test to fail when running the feed. ++ with self.assertRaises(errors.InvalidArgumentError): ++ sess.run(init_op, feed_dict={st: sparse_feed}) ++ + @combinations.generate(combinations.combine(tf_api_version=2, mode=["eager"])) + def testFromSparseTensorSlicesError(self): + with self.assertRaises(AttributeError): diff --git a/CVE-2021-37648.patch b/CVE-2021-37648.patch new file mode 100644 index 0000000000000000000000000000000000000000..83f9e1142216307f8b04d29db9e482add4eec437 --- /dev/null +++ b/CVE-2021-37648.patch @@ -0,0 +1,31 @@ +From 9728c60e136912a12d99ca56e106b7cce7af5986 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 30 Jul 2021 19:05:41 -0700 +Subject: [PATCH] Ensure validation sticks in `save_restore_v2_ops.cc` + +PiperOrigin-RevId: 387924206 +Change-Id: I6156842eb3230076b5812c0815f3e66bd5241454 +--- + tensorflow/core/kernels/save_restore_v2_ops.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/save_restore_v2_ops.cc b/tensorflow/core/kernels/save_restore_v2_ops.cc +index 44738d0f0cca3..809a26030b850 100644 +--- a/tensorflow/core/kernels/save_restore_v2_ops.cc ++++ b/tensorflow/core/kernels/save_restore_v2_ops.cc +@@ -98,6 +98,7 @@ class SaveV2 : public OpKernel { + const Tensor& shape_and_slices = context->input(2); + ValidateInputs(true /* is save op */, context, prefix, tensor_names, + shape_and_slices); ++ if (!context->status().ok()) return; + + const int kFixedInputs = 3; // Prefix, tensor names, shape_and_slices. + const int num_tensors = static_cast(tensor_names.NumElements()); +@@ -177,6 +178,7 @@ class RestoreV2 : public OpKernel { + " expected dtypes.")); + ValidateInputs(false /* not save op */, context, prefix, tensor_names, + shape_and_slices); ++ if (!context->status().ok()) return; + + const string& prefix_string = prefix.scalar()(); + diff --git a/CVE-2021-37649.patch b/CVE-2021-37649.patch new file mode 100644 index 0000000000000000000000000000000000000000..37d91638fca2ca1ce744c8745ef4f11d0c7b453f --- /dev/null +++ b/CVE-2021-37649.patch @@ -0,0 +1,28 @@ +From 7bdf50bb4f5c54a4997c379092888546c97c3ebd Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Fri, 9 Jul 2021 17:45:15 -0700 +Subject: [PATCH] Ensure non-empty compressed input in + tf.raw_ops.UncompressElement + +PiperOrigin-RevId: 383955815 +Change-Id: I072a84fd02738dd2f51b3f42836ed80067dba4a8 +--- + tensorflow/core/kernels/data/experimental/compression_ops.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/data/experimental/compression_ops.cc b/tensorflow/core/kernels/data/experimental/compression_ops.cc +index efa7018acb629..8cc214671bd74 100644 +--- a/tensorflow/core/kernels/data/experimental/compression_ops.cc ++++ b/tensorflow/core/kernels/data/experimental/compression_ops.cc +@@ -48,6 +48,11 @@ void UncompressElementOp::Compute(OpKernelContext* ctx) { + Tensor tensor = ctx->input(0); + const Variant& variant = tensor.scalar()(); + const CompressedElement* compressed = variant.get(); ++ OP_REQUIRES( ++ ctx, compressed != nullptr, ++ errors::InvalidArgument( ++ "Input does not contain a compressed element. Instead got tensor ", ++ tensor.DebugString())); + + std::vector components; + OP_REQUIRES_OK(ctx, UncompressElement(*compressed, &components)); diff --git a/CVE-2021-37652.patch b/CVE-2021-37652.patch new file mode 100644 index 0000000000000000000000000000000000000000..609800a4bbb1717639640819375b88d8457aade7 --- /dev/null +++ b/CVE-2021-37652.patch @@ -0,0 +1,25 @@ +From 5ecec9c6fbdbc6be03295685190a45e7eee726ab Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 30 Jul 2021 19:13:19 -0700 +Subject: [PATCH] Prevent use after free. + +A very old version of the code used `result` as a simple pointer to a resource. Two years later, the pointer got changed to a `unique_ptr` but author forgot to remove the call to `Unref`. Three years after that, we finally uncover the UAF. + +PiperOrigin-RevId: 387924872 +Change-Id: I70fb6f199164de49fac20c168132a07b84903f9b +--- + tensorflow/core/kernels/boosted_trees/resource_ops.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/core/kernels/boosted_trees/resource_ops.cc b/tensorflow/core/kernels/boosted_trees/resource_ops.cc +index d50885fa3f511..f2c60b9b4511d 100644 +--- a/tensorflow/core/kernels/boosted_trees/resource_ops.cc ++++ b/tensorflow/core/kernels/boosted_trees/resource_ops.cc +@@ -53,6 +53,7 @@ class BoostedTreesCreateEnsembleOp : public OpKernel { + if (!result->InitFromSerialized( + tree_ensemble_serialized_t->scalar()(), stamp_token)) { + result->Unref(); ++ result.release(); // Needed due to the `->Unref` above, to prevent UAF + OP_REQUIRES( + context, false, + errors::InvalidArgument("Unable to parse tree ensemble proto.")); diff --git a/CVE-2021-37656.patch b/CVE-2021-37656.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8c8ecb7b9e98abeab5a4c0ac93a82e208686259 --- /dev/null +++ b/CVE-2021-37656.patch @@ -0,0 +1,50 @@ +From 1071f554dbd09f7e101324d366eec5f4fe5a3ece Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 18:23:29 -0700 +Subject: [PATCH] Add missing validation to `RaggedTensorToSparse`. + +There needs to be a check that the splits allow for valid ragged tensors. + +PiperOrigin-RevId: 387712169 +Change-Id: I2499175324b82b65d159a260c7f83b98ceb5cc7d +--- + .../core/kernels/ragged_tensor_to_sparse_kernel.cc | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/tensorflow/core/kernels/ragged_tensor_to_sparse_kernel.cc b/tensorflow/core/kernels/ragged_tensor_to_sparse_kernel.cc +index a47ff372cf087..639280a26b40d 100644 +--- a/tensorflow/core/kernels/ragged_tensor_to_sparse_kernel.cc ++++ b/tensorflow/core/kernels/ragged_tensor_to_sparse_kernel.cc +@@ -21,6 +21,7 @@ limitations under the License. + #include "tensorflow/core/framework/register_types.h" + #include "tensorflow/core/framework/tensor.h" + #include "tensorflow/core/framework/tensor_shape.h" ++#include "tensorflow/core/platform/errors.h" + + namespace tensorflow { + +@@ -38,7 +39,8 @@ class RaggedTensorToSparseOp : public OpKernel { + OP_REQUIRES_OK( + context, context->input_list("rt_nested_splits", &rt_nested_splits_in)); + const int rt_nested_splits_len = rt_nested_splits_in.size(); +- DCHECK_GT(rt_nested_splits_len, 0); // Enforced by REGISTER_OP. ++ OP_REQUIRES(context, rt_nested_splits_len > 0, ++ errors::InvalidArgument("rt_nested_splits must be non empty")); + std::vector rt_nested_splits; + rt_nested_splits.reserve(rt_nested_splits_len); + for (int i = 0; i < rt_nested_splits_len; ++i) { +@@ -162,6 +164,14 @@ class RaggedTensorToSparseOp : public OpKernel { + if (rt_nested_splits[i](0) != 0) { + return InvalidArgument("First value of ragged splits must be 0."); + } ++ for (int j = 1; j < rt_nested_splits[i].size(); ++j) { ++ if (rt_nested_splits[i](j) < rt_nested_splits[i](j - 1)) { ++ return InvalidArgument( ++ "Ragged splits should be non decreasing, but we got ", ++ rt_nested_splits[i](j - 1), " followed by ", ++ rt_nested_splits[i](j)); ++ } ++ } + if (i > 0) { + SPLITS_TYPE last_split = + rt_nested_splits[i - 1](rt_nested_splits[i - 1].size() - 1); diff --git a/CVE-2021-37659.patch b/CVE-2021-37659.patch new file mode 100644 index 0000000000000000000000000000000000000000..f43c0f6c8b47fa2ee5295645eb8bdf2d7e638630 --- /dev/null +++ b/CVE-2021-37659.patch @@ -0,0 +1,27 @@ +From 93f428fd1768df147171ed674fee1fc5ab8309ec Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 30 Jul 2021 21:42:36 -0700 +Subject: [PATCH] Fix nullptr deref and heap OOB access in binary cwise ops. + +PiperOrigin-RevId: 387936777 +Change-Id: I608b8074cec36a982cca622b7144cb2c43e6e19f +--- + tensorflow/core/kernels/cwise_ops_common.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/cwise_ops_common.h b/tensorflow/core/kernels/cwise_ops_common.h +index 9adc628421d04..4f2c83322ba00 100644 +--- a/tensorflow/core/kernels/cwise_ops_common.h ++++ b/tensorflow/core/kernels/cwise_ops_common.h +@@ -265,6 +265,11 @@ class SimpleBinaryOp : public OpKernel { + void Compute(OpKernelContext* ctx) override { + const Tensor& in0 = ctx->input(0); + const Tensor& in1 = ctx->input(1); ++ OP_REQUIRES( ++ ctx, in0.NumElements() == in1.NumElements(), ++ errors::InvalidArgument("The two arguments to a cwise op must have " ++ "same number of elements, got ", ++ in0.NumElements(), " and ", in1.NumElements())); + auto in0_flat = in0.flat(); + auto in1_flat = in1.flat(); + const Device& eigen_device = ctx->eigen_device(); diff --git a/CVE-2021-37660.patch b/CVE-2021-37660.patch new file mode 100644 index 0000000000000000000000000000000000000000..d1b933553e74ed3cb407bf19cff1a5b622d09ef2 --- /dev/null +++ b/CVE-2021-37660.patch @@ -0,0 +1,24 @@ +From e86605c0a336c088b638da02135ea6f9f6753618 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Mon, 2 Aug 2021 14:21:27 -0700 +Subject: [PATCH] Fix FPE in inpace update ops. + +PiperOrigin-RevId: 388303197 +Change-Id: Ib48309b6213ffe53eba81004b00e889d653e4b83 +--- + tensorflow/core/kernels/inplace_ops.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tensorflow/core/kernels/inplace_ops.cc b/tensorflow/core/kernels/inplace_ops.cc +index 2c0b201af3dd8..81027c7e17ee1 100644 +--- a/tensorflow/core/kernels/inplace_ops.cc ++++ b/tensorflow/core/kernels/inplace_ops.cc +@@ -225,7 +225,7 @@ class InplaceOpBase : public OpKernel { + + Tensor y = x; // This creates an alias intentionally. + // Skip processing if tensors are empty. +- if (x.NumElements() > 0 || v.NumElements() > 0) { ++ if (x.NumElements() > 0 && v.NumElements() > 0) { + OP_REQUIRES_OK(ctx, DoCompute(ctx, i, v, &y)); + } + ctx->set_output(0, y); diff --git a/CVE-2021-37663.patch b/CVE-2021-37663.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e504c57b11de212afb5a62be542261293d929e8 --- /dev/null +++ b/CVE-2021-37663.patch @@ -0,0 +1,69 @@ +From 6da6620efad397c85493b8f8667b821403516708 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Tue, 27 Jul 2021 17:19:57 -0700 +Subject: [PATCH] Secure tf.raw_ops.QuantizeV2 + +Validate size and shape of min_range and max_range +Ensure axis is within input dims limits + +PiperOrigin-RevId: 387232799 +Change-Id: I36975281f7b5758e9e31a8dcc73fe610ef456318 +--- + tensorflow/core/kernels/quantize_op.cc | 43 ++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/tensorflow/core/kernels/quantize_op.cc b/tensorflow/core/kernels/quantize_op.cc +index f64a2188fa954..be73d4f8291f7 100644 +--- a/tensorflow/core/kernels/quantize_op.cc ++++ b/tensorflow/core/kernels/quantize_op.cc +@@ -113,7 +113,50 @@ class QuantizeV2Op : public OpKernel { + + int num_slices = 1; + if (axis_ > -1) { ++ OP_REQUIRES( ++ ctx, input.dims() > axis_, ++ errors::InvalidArgument( ++ "Axis is on a zero-based index, so its value must always be less " ++ "than number of input's dims, but given axis value was ", ++ axis_, " and input's dims was ", input.dims())); + num_slices = input.dim_size(axis_); ++ OP_REQUIRES(ctx, input_min_range.dims() == 1, ++ errors::InvalidArgument( ++ "If axis is specified, min_range must be a 1-D tensor " ++ "whose size matches the axis dimension of the input and " ++ "output tensors, but min_range dims are ", ++ input_min_range.dims())); ++ OP_REQUIRES(ctx, input_min_range.dim_size(0) == num_slices, ++ errors::InvalidArgument( ++ "If axis is specified, min_range must be a 1-D tensor " ++ "whose size matches the axis dimension of the input and " ++ "output tensors, but min_range is a 1-D tensor of size ", ++ input_min_range.dim_size(0), ++ " and input's axis dimension is of size ", num_slices)); ++ OP_REQUIRES(ctx, input_max_range.dims() == 1, ++ errors::InvalidArgument( ++ "If axis is specified, max_range must be a 1-D tensor " ++ "whose size matches the axis dimension of the input and " ++ "output tensors, but max_range dims are ", ++ input_max_range.dims())); ++ OP_REQUIRES(ctx, input_max_range.dim_size(0) == num_slices, ++ errors::InvalidArgument( ++ "If axis is specified, max_range must be a 1-D tensor " ++ "whose size matches the axis dimension of the input and " ++ "output tensors, but max_range is a 1-D tensor of size ", ++ input_max_range.dim_size(0), ++ " and input's axis dimension is of size ", num_slices)); ++ } else { ++ OP_REQUIRES(ctx, input_min_range.NumElements() == 1, ++ errors::InvalidArgument( ++ "If axis is not specified, min_range must contain a " ++ "single float element, but it contains ", ++ input_min_range.NumElements(), " elements")); ++ OP_REQUIRES(ctx, input_max_range.NumElements() == 1, ++ errors::InvalidArgument( ++ "If axis is not specified, max_range must contain a " ++ "single float element, but it contains ", ++ input_max_range.NumElements(), " elements")); + } + + const TensorShape& minmax_shape = ctx->input(1).shape(); diff --git a/CVE-2021-37667.patch b/CVE-2021-37667.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b6cb2e2bdf9bf4f763c72e3d56781fe6dc79316 --- /dev/null +++ b/CVE-2021-37667.patch @@ -0,0 +1,26 @@ +From 2e0ee46f1a47675152d3d865797a18358881d7a6 Mon Sep 17 00:00:00 2001 +From: Laura Pak +Date: Tue, 27 Jul 2021 12:30:33 -0700 +Subject: [PATCH] Ensure non-empty input_splits in tf.raw_ops.UnicodeEncode + +PiperOrigin-RevId: 387170080 +Change-Id: I3b489acc51c5cb4124c535b9df7cc6e62ef21766 +--- + tensorflow/core/kernels/unicode_ops.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/kernels/unicode_ops.cc b/tensorflow/core/kernels/unicode_ops.cc +index 301cdf932ba60..d4153e04e4f94 100644 +--- a/tensorflow/core/kernels/unicode_ops.cc ++++ b/tensorflow/core/kernels/unicode_ops.cc +@@ -533,6 +533,10 @@ class UnicodeEncodeOp : public OpKernel { + const Tensor& input_splits = context->input(1); + const auto input_splits_flat = input_splits.flat(); + ++ OP_REQUIRES( ++ context, input_splits.NumElements() > 0, ++ errors::InvalidArgument("Input_splits should contain elements, but " ++ "given input_values has 0 elements")); + // Operation will treat first argument in input_splits as if it were zero + // regardless of its actual value since splits should begin with zero and + // end with the length of the input values vector. diff --git a/CVE-2021-37670.patch b/CVE-2021-37670.patch new file mode 100644 index 0000000000000000000000000000000000000000..cdaa46637979570a456b97d38a9bb756b080c810 --- /dev/null +++ b/CVE-2021-37670.patch @@ -0,0 +1,37 @@ +From 42459e4273c2e47a3232cc16c4f4fff3b3a35c38 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 22:25:05 -0700 +Subject: [PATCH] Prevent CHECK-fail/heap OOB in UpperBound and LowerBound + +PiperOrigin-RevId: 387738073 +Change-Id: Iee74de95ddad18440d052a75a5a1cb67544f490a +--- + tensorflow/core/kernels/searchsorted_op.cc | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/tensorflow/core/kernels/searchsorted_op.cc b/tensorflow/core/kernels/searchsorted_op.cc +index 01e221dc471c4..5f075a6a540e9 100644 +--- a/tensorflow/core/kernels/searchsorted_op.cc ++++ b/tensorflow/core/kernels/searchsorted_op.cc +@@ -86,6 +86,10 @@ class UpperBoundOp : public OpKernel { + const Tensor& sorted_inputs_t = ctx->input(0); + const Tensor& values_t = ctx->input(1); + ++ // inputs must be at least a matrix ++ OP_REQUIRES( ++ ctx, sorted_inputs_t.shape().dims() >= 2, ++ errors::InvalidArgument("sorted input argument must be a matrix")); + // must have same batch dim_size for both + OP_REQUIRES(ctx, sorted_inputs_t.dim_size(0) == values_t.dim_size(0), + Status(error::INVALID_ARGUMENT, +@@ -127,6 +131,10 @@ class LowerBoundOp : public OpKernel { + const Tensor& sorted_inputs_t = ctx->input(0); + const Tensor& values_t = ctx->input(1); + ++ // inputs must be at least a matrix ++ OP_REQUIRES( ++ ctx, sorted_inputs_t.shape().dims() >= 2, ++ errors::InvalidArgument("sorted input argument must be a matrix")); + // must have same batch dim_size for both + OP_REQUIRES(ctx, sorted_inputs_t.dim_size(0) == values_t.dim_size(0), + Status(error::INVALID_ARGUMENT, diff --git a/CVE-2021-37671.patch b/CVE-2021-37671.patch new file mode 100644 index 0000000000000000000000000000000000000000..5db24f5f391385d9da8bc73be1bf153d65893065 --- /dev/null +++ b/CVE-2021-37671.patch @@ -0,0 +1,61 @@ +From 532f5c5a547126c634fefd43bbad1dc6417678ac Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 22:24:39 -0700 +Subject: [PATCH] Prevent nullptr deref in validation of indexes in map ops. + +PiperOrigin-RevId: 387738023 +Change-Id: I83d18d36a7b82ffd2a40b5124a4e5b4c72238f27 +--- + tensorflow/core/kernels/map_stage_op.cc | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/tensorflow/core/kernels/map_stage_op.cc b/tensorflow/core/kernels/map_stage_op.cc +index 9411792762baa..1a2f5a8fa2247 100644 +--- a/tensorflow/core/kernels/map_stage_op.cc ++++ b/tensorflow/core/kernels/map_stage_op.cc +@@ -210,9 +210,9 @@ class StagingMap : public ResourceBase { + const OptionalTuple& tuple) + TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) { + if (tuple[index].has_value()) { +- return Status(errors::InvalidArgument( ++ return errors::InvalidArgument( + "The tensor for index '", index, "' for key '", key.scalar()(), +- "' was already initialized '", dtypes_.size(), "'.")); ++ "' was already initialized '", dtypes_.size(), "'."); + } + + return Status::OK(); +@@ -220,6 +220,10 @@ class StagingMap : public ResourceBase { + + // Check that the indices are strictly ordered + Status check_index_ordering(const Tensor& indices) { ++ if (indices.NumElements() == 0) { ++ return errors::InvalidArgument("Indices are empty"); ++ } ++ + auto findices = indices.flat(); + + for (std::size_t i = 0; i < findices.dimension(0) - 1; ++i) { +@@ -227,8 +231,7 @@ class StagingMap : public ResourceBase { + continue; + } + +- return Status( +- errors::InvalidArgument("Indices are not strictly ordered")); ++ return errors::InvalidArgument("Indices are not strictly ordered"); + } + + return Status::OK(); +@@ -238,10 +241,10 @@ class StagingMap : public ResourceBase { + Status check_memory_limit(std::size_t bytes) + TF_EXCLUSIVE_LOCKS_REQUIRED(mu_) { + if (has_memory_limit() && bytes > memory_limit_) { +- return Status(errors::ResourceExhausted( ++ return errors::ResourceExhausted( + "Attempted to insert tensors with combined size of '", bytes, + "' bytes into Staging Area with a memory limit of '", memory_limit_, +- "'.")); ++ "'."); + } + + return Status::OK(); diff --git a/CVE-2021-37672.patch b/CVE-2021-37672.patch new file mode 100644 index 0000000000000000000000000000000000000000..727d2ea716c43d7a67816930156da468ef333009 --- /dev/null +++ b/CVE-2021-37672.patch @@ -0,0 +1,27 @@ +From a4e138660270e7599793fa438cd7b2fc2ce215a6 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 22:24:27 -0700 +Subject: [PATCH] Add remaining validation to `sdca_internal.cc` + +PiperOrigin-RevId: 387738010 +Change-Id: I28eedcfd87a53aaf34deb075acea1f8c95470808 +--- + tensorflow/core/kernels/sdca_internal.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tensorflow/core/kernels/sdca_internal.cc b/tensorflow/core/kernels/sdca_internal.cc +index 6c4a63b270c25..164f9382724ca 100644 +--- a/tensorflow/core/kernels/sdca_internal.cc ++++ b/tensorflow/core/kernels/sdca_internal.cc +@@ -380,6 +380,11 @@ Status Examples::Initialize(OpKernelContext* const context, + const Tensor* example_labels_t; + TF_RETURN_IF_ERROR(context->input("example_labels", &example_labels_t)); + auto example_labels = example_labels_t->flat(); ++ if (example_labels.size() != num_examples) { ++ return errors::InvalidArgument("Expected ", num_examples, ++ " example labels but got ", ++ example_labels.size()); ++ } + + OpInputList dense_features_inputs; + TF_RETURN_IF_ERROR( diff --git a/CVE-2021-37673.patch b/CVE-2021-37673.patch new file mode 100644 index 0000000000000000000000000000000000000000..60f31a1b55c3eefb8d43dabe4ed413bfd204c9a8 --- /dev/null +++ b/CVE-2021-37673.patch @@ -0,0 +1,25 @@ +From d7de67733925de196ec8863a33445b73f9562d1d Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 22:23:46 -0700 +Subject: [PATCH] Prevent a CHECK-fail due to empty tensor input in + `map_stage_op.cc` + +PiperOrigin-RevId: 387737906 +Change-Id: Idc52df0c71c7ed6e2dd633b651a581932f277c8a +--- + tensorflow/core/kernels/map_stage_op.cc | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/tensorflow/core/kernels/map_stage_op.cc b/tensorflow/core/kernels/map_stage_op.cc +index b575c2d3862e0..9411792762baa 100644 +--- a/tensorflow/core/kernels/map_stage_op.cc ++++ b/tensorflow/core/kernels/map_stage_op.cc +@@ -527,6 +527,8 @@ class MapStageOp : public OpKernel { + OP_REQUIRES_OK(ctx, ctx->input("key", &key_tensor)); + OP_REQUIRES_OK(ctx, ctx->input("indices", &indices_tensor)); + OP_REQUIRES_OK(ctx, ctx->input_list("values", &values_tensor)); ++ OP_REQUIRES(ctx, key_tensor->NumElements() > 0, ++ errors::InvalidArgument("key must not be empty")); + + // Create copy for insertion into Staging Area + Tensor key(*key_tensor); diff --git a/CVE-2021-37676.patch b/CVE-2021-37676.patch new file mode 100644 index 0000000000000000000000000000000000000000..cfd36fc4f42d5a969831025a948166428f52693a --- /dev/null +++ b/CVE-2021-37676.patch @@ -0,0 +1,32 @@ +From 578e634b4f1c1c684d4b4294f9e5281b2133b3ed Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 22:24:08 -0700 +Subject: [PATCH] Prevent a segfault in shape inference due to bad inputs. + +PiperOrigin-RevId: 387737970 +Change-Id: Ibd1cf3dbdce1dd2ab47fd633d5c5a57f7d8fb6e9 +--- + tensorflow/core/ops/sparse_ops.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/core/ops/sparse_ops.cc b/tensorflow/core/ops/sparse_ops.cc +index 906cef1f5ecaf..b1e40e66af892 100644 +--- a/tensorflow/core/ops/sparse_ops.cc ++++ b/tensorflow/core/ops/sparse_ops.cc +@@ -16,6 +16,7 @@ limitations under the License. + #include "tensorflow/core/framework/common_shape_fns.h" + #include "tensorflow/core/framework/op.h" + #include "tensorflow/core/framework/shape_inference.h" ++#include "tensorflow/core/platform/errors.h" + + namespace tensorflow { + +@@ -619,6 +620,8 @@ REGISTER_OP("SparseFillEmptyRows") + DimensionHandle unused_dim; + TF_RETURN_IF_ERROR(c->Merge(c->Dim(input_indices, 1), + c->Dim(input_shape, 0), &unused_dim)); ++ if (c->Value(c->NumElements(input_shape)) == 0) ++ return errors::InvalidArgument("dense_shape must not be empty"); + ShapeHandle output_indices = + c->Matrix(InferenceContext::kUnknownDim, c->NumElements(input_shape)); + ShapeHandle output_values = c->Vector(InferenceContext::kUnknownDim); diff --git a/CVE-2021-37677.patch b/CVE-2021-37677.patch new file mode 100644 index 0000000000000000000000000000000000000000..68af7c837d0a6ee30c4f53b8d147c5db3227e9f1 --- /dev/null +++ b/CVE-2021-37677.patch @@ -0,0 +1,26 @@ +From da857cfa0fde8f79ad0afdbc94e88b5d4bbec764 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Thu, 29 Jul 2021 18:24:18 -0700 +Subject: [PATCH] Fix a shape inference issue leading to nullptr deref. + +PiperOrigin-RevId: 387712259 +Change-Id: I7e670772b259c068a501a187cd89f18773bb95a1 +--- + tensorflow/core/ops/array_ops.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tensorflow/core/ops/array_ops.cc b/tensorflow/core/ops/array_ops.cc +index 626afd5860370..3bd6f8a103872 100644 +--- a/tensorflow/core/ops/array_ops.cc ++++ b/tensorflow/core/ops/array_ops.cc +@@ -2990,6 +2990,10 @@ REGISTER_OP("Dequantize") + if (!s.ok() && s.code() != error::NOT_FOUND) { + return s; + } ++ if (axis < -1) { ++ return errors::InvalidArgument("axis should be at least -1, got ", ++ axis); ++ } + const int minmax_rank = (axis == -1) ? 0 : 1; + TF_RETURN_IF_ERROR(shape_inference::UnchangedShape(c)); + ShapeHandle minmax; diff --git a/CVE-2021-37680.patch b/CVE-2021-37680.patch new file mode 100644 index 0000000000000000000000000000000000000000..b387ca8b01a5516413fee987bd091d36437a6598 --- /dev/null +++ b/CVE-2021-37680.patch @@ -0,0 +1,23 @@ +From 718721986aa137691ee23f03638867151f74935f Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 16 Jul 2021 06:49:45 -0700 +Subject: [PATCH] Prevent division by 0 in `fully_connected.cc` + +PiperOrigin-RevId: 385137282 +Change-Id: If201e69b6e0048f0be001330b4b977e2b46db2cb +--- + tensorflow/lite/kernels/fully_connected.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/fully_connected.cc b/tensorflow/lite/kernels/fully_connected.cc +index 4ebaa7877fa38..d0010e302618d 100644 +--- a/tensorflow/lite/kernels/fully_connected.cc ++++ b/tensorflow/lite/kernels/fully_connected.cc +@@ -223,6 +223,7 @@ TfLiteStatus PrepareImpl(TfLiteContext* context, TfLiteNode* node) { + } + + TF_LITE_ENSURE_EQ(context, NumDimensions(filter), 2); ++ TF_LITE_ENSURE(context, filter->dims->data[1] != 0); + const int batch_size = input_size / filter->dims->data[1]; + const int num_units = filter->dims->data[0]; + diff --git a/CVE-2021-37682-1.patch b/CVE-2021-37682-1.patch new file mode 100644 index 0000000000000000000000000000000000000000..ffe9879fb53eafa1b7ce2961e743e9ec24955188 --- /dev/null +++ b/CVE-2021-37682-1.patch @@ -0,0 +1,42 @@ +From 8933b8a21280696ab119b63263babdb54c298538 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 16 Jul 2021 10:22:37 -0700 +Subject: [PATCH] Fix a null pointer exception caused by branching on + uninitialized data. + +This is due to not checking that the params for the quantization exists. If there is no quantization, we should not access the `.params` field. + +PiperOrigin-RevId: 385173491 +Change-Id: I8fc476c4b274fdb21ba741caa0fbc6d1b8840663 +--- + tensorflow/lite/kernels/depthwise_conv.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/lite/kernels/depthwise_conv.cc b/tensorflow/lite/kernels/depthwise_conv.cc +index c19e01cf33bca..060b0827dafa7 100644 +--- a/tensorflow/lite/kernels/depthwise_conv.cc ++++ b/tensorflow/lite/kernels/depthwise_conv.cc +@@ -176,6 +176,7 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + if (data_type != kTfLiteFloat32) { + TF_LITE_ENSURE_EQ(context, filter->quantization.type, + kTfLiteAffineQuantization); ++ TF_LITE_ENSURE(context, filter->quantization.type != kTfLiteNoQuantization); + const auto* affine_quantization = + reinterpret_cast( + filter->quantization.params); +@@ -195,6 +196,7 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + } + + if (is_hybrid) { ++ TF_LITE_ENSURE(context, filter->quantization.type != kTfLiteNoQuantization); + const auto* affine_quantization = + reinterpret_cast( + filter->quantization.params); +@@ -495,6 +497,7 @@ TfLiteStatus EvalHybridPerChannel(TfLiteContext* context, TfLiteNode* node, + op_params.weights_offset = 0; + op_params.float_activation_min = output_activation_min; + op_params.float_activation_max = output_activation_max; ++ TF_LITE_ENSURE(context, filter->quantization.type != kTfLiteNoQuantization); + const auto* affine_quantization = + reinterpret_cast(filter->quantization.params); + if (kernel_type == kReference) { diff --git a/CVE-2021-37682-2.patch b/CVE-2021-37682-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..1499353ca48505a6ca775fd5d8e3fc0b4ce59039 --- /dev/null +++ b/CVE-2021-37682-2.patch @@ -0,0 +1,40 @@ +From 537bc7c723439b9194a358f64d871dd326c18887 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Fri, 16 Jul 2021 09:35:48 -0700 +Subject: [PATCH] Fix a null pointer exception caused by branching on + uninitialized data. + +This is due to not checking that the params for the quantization exists. If there is no quantization, we should not access the `.params` field. + +PiperOrigin-RevId: 385163909 +Change-Id: I2beb8d50649b6542db224c163033fbcbaa49314f +--- + tensorflow/lite/kernels/svdf.cc | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/tensorflow/lite/kernels/svdf.cc b/tensorflow/lite/kernels/svdf.cc +index 6c02508e26b1d..41a71c54a8c92 100644 +--- a/tensorflow/lite/kernels/svdf.cc ++++ b/tensorflow/lite/kernels/svdf.cc +@@ -256,14 +256,21 @@ TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + output_temp_size_array)); + + // Calculate effective scales. ++ TF_LITE_ENSURE(context, input->quantization.type != kTfLiteNoQuantization); + auto* input_params = + reinterpret_cast(input->quantization.params); ++ TF_LITE_ENSURE(context, ++ weights_feature->quantization.type != kTfLiteNoQuantization); + auto* weights_feature_params = reinterpret_cast( + weights_feature->quantization.params); ++ TF_LITE_ENSURE(context, state->quantization.type != kTfLiteNoQuantization); + auto* state_params = + reinterpret_cast(state->quantization.params); ++ TF_LITE_ENSURE(context, ++ weights_time->quantization.type != kTfLiteNoQuantization); + auto* weight_time_params = reinterpret_cast( + weights_time->quantization.params); ++ TF_LITE_ENSURE(context, output->quantization.type != kTfLiteNoQuantization); + auto* output_params = reinterpret_cast( + output->quantization.params); + const double effective_scale_1 = input_params->scale->data[0] * diff --git a/CVE-2021-37685.patch b/CVE-2021-37685.patch new file mode 100644 index 0000000000000000000000000000000000000000..3f0f7c7a5037b868b9cfc4952b9c6aa28efdbb6f --- /dev/null +++ b/CVE-2021-37685.patch @@ -0,0 +1,25 @@ +From d94ffe08a65400f898241c0374e9edc6fa8ed257 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Jul 2021 14:42:54 -0700 +Subject: [PATCH] Prevent an OOB read in `expand_dims.cc` + +The for loop that follows this check assumes that `axis` is between `0` and `input_dims.size`. If user supplied `axis` is negative, the if code before this check is supposed to bring it back to positive (similar to how in Python one can do `l[-3]` to mean `l[-3 + len(l)]`). + +PiperOrigin-RevId: 387200206 +Change-Id: I162f4feba12d547c3a4340833ae682016a2ebfab +--- + tensorflow/lite/kernels/expand_dims.cc | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tensorflow/lite/kernels/expand_dims.cc b/tensorflow/lite/kernels/expand_dims.cc +index 231ba6df8ba73..c8d0270551c19 100644 +--- a/tensorflow/lite/kernels/expand_dims.cc ++++ b/tensorflow/lite/kernels/expand_dims.cc +@@ -37,6 +37,7 @@ TfLiteStatus ExpandTensorDim(TfLiteContext* context, const TfLiteTensor& input, + axis = input_dims.size + 1 + axis; + } + TF_LITE_ENSURE(context, axis <= input_dims.size); ++ TF_LITE_ENSURE(context, axis >= 0); + + TfLiteIntArray* output_dims = TfLiteIntArrayCreate(input_dims.size + 1); + for (int i = 0; i < output_dims->size; ++i) { diff --git a/CVE-2021-37687.patch b/CVE-2021-37687.patch new file mode 100644 index 0000000000000000000000000000000000000000..6e7a8c0be27fb207931eb9d5b3f7328109d931cf --- /dev/null +++ b/CVE-2021-37687.patch @@ -0,0 +1,35 @@ +From bb6a0383ed553c286f87ca88c207f6774d5c4a8f Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Jul 2021 15:20:26 -0700 +Subject: [PATCH] Prevent heap OOB read in TFLite's `gather_nd.cc`. + +Passing negative indices is illegal but there was a missing check so that resulted in OOB accesses. + +PiperOrigin-RevId: 387208551 +Change-Id: I6b7a8a62d3e7c13a16d81619e5bc23ae2cdbc7fd +--- + tensorflow/lite/kernels/gather_nd.cc | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/tensorflow/lite/kernels/gather_nd.cc b/tensorflow/lite/kernels/gather_nd.cc +index 3ded771382569..c39917b478505 100644 +--- a/tensorflow/lite/kernels/gather_nd.cc ++++ b/tensorflow/lite/kernels/gather_nd.cc +@@ -123,6 +123,17 @@ TfLiteStatus GatherNdString(const TfLiteTensor* params, + template + TfLiteStatus EvalGatherNd(TfLiteContext* context, const TfLiteTensor* params, + const TfLiteTensor* indices, TfLiteTensor* output) { ++ bool indices_has_only_positive_elements = true; ++ const auto* indices_values = GetTensorData(indices); ++ const size_t num_indices = indices->bytes / sizeof(IndicesT); ++ for (size_t i = 0; i < num_indices; i++) { ++ if (indices_values[i] < 0) { ++ indices_has_only_positive_elements = false; ++ break; ++ } ++ } ++ TF_LITE_ENSURE(context, indices_has_only_positive_elements); ++ + switch (params->type) { + case kTfLiteFloat32: + return GatherNd(params, indices, output); diff --git a/CVE-2021-37688.patch b/CVE-2021-37688.patch new file mode 100644 index 0000000000000000000000000000000000000000..9dd35516effaf07ce0058b7abfa8a17ed7e94e4b --- /dev/null +++ b/CVE-2021-37688.patch @@ -0,0 +1,24 @@ +From 15691e456c7dc9bd6be203b09765b063bf4a380c Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Jul 2021 18:40:39 -0700 +Subject: [PATCH] Prevent dereferencing of null pointers in TFLite's `add.cc`. + +PiperOrigin-RevId: 387244946 +Change-Id: I56094233327fbd8439b92e1dbb1262176e00eeb9 +--- + tensorflow/lite/kernels/internal/optimized/optimized_ops.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tensorflow/lite/kernels/internal/optimized/optimized_ops.h b/tensorflow/lite/kernels/internal/optimized/optimized_ops.h +index 241405a6bbae1..296b3923a257a 100644 +--- a/tensorflow/lite/kernels/internal/optimized/optimized_ops.h ++++ b/tensorflow/lite/kernels/internal/optimized/optimized_ops.h +@@ -265,7 +265,7 @@ inline void BinaryBroadcastFiveFold(const ArithmeticParams& unswitched_params, + // We have broadcast y2*y3*y4 of input2 data y1 times, and now move on. + input2_data_reset = input2_data_ptr; + } +- } else { ++ } else if (input1_data_ptr != nullptr) { + // Special case of y4 == 1, in which the innermost loop is a single + // element and can be combined with the next (y3) as an inner broadcast. + // diff --git a/CVE-2021-37689.patch b/CVE-2021-37689.patch new file mode 100644 index 0000000000000000000000000000000000000000..d755ac231d29cde639244375fd21989d6c564e5d --- /dev/null +++ b/CVE-2021-37689.patch @@ -0,0 +1,25 @@ +From d6b57f461b39fd1aa8c1b870f1b974aac3554955 Mon Sep 17 00:00:00 2001 +From: Mihai Maruseac +Date: Tue, 27 Jul 2021 16:20:45 -0700 +Subject: [PATCH] Prevent nullptr dereference in MLIR TFLite dialect/optimizer. + +PiperOrigin-RevId: 387220762 +Change-Id: Id136ef04bb3d36123b4685d316ae81a9ec924d6b +--- + tensorflow/compiler/mlir/lite/transforms/optimize.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tensorflow/compiler/mlir/lite/transforms/optimize.cc b/tensorflow/compiler/mlir/lite/transforms/optimize.cc +index d457612bf70ee..6a8803d246159 100644 +--- a/tensorflow/compiler/mlir/lite/transforms/optimize.cc ++++ b/tensorflow/compiler/mlir/lite/transforms/optimize.cc +@@ -68,6 +68,9 @@ constexpr char kRelu6[] = "RELU6"; + constexpr char kRelu1[] = "RELU_N1_TO_1"; + + bool L2NormalizeReduceAxis(Value sq_op, DenseElementsAttr axis) { ++ if (axis.getNumElements() == 0) { ++ return false; ++ } + if (sq_op.getType().cast().getRank() - 1 == + *axis.getValues().begin() || + *axis.getValues().begin() == -1) { diff --git a/tensorflow.spec b/tensorflow.spec index 402ae5db22eb8c4828606b30c24b05f662cb1d3e..ef50b465826cd9813d0cf58b3888f26d57740e91 100644 --- a/tensorflow.spec +++ b/tensorflow.spec @@ -1,7 +1,7 @@ %global _empty_manifest_terminate_build 0 Name: tensorflow Version: 2.3.1 -Release: 2 +Release: 3 Summary: An Open Source Machine Learning Framework for Everyone License: Apache License 2.0 URL: https://www.tensorflow.org/ @@ -14,6 +14,109 @@ Patch0002: CVE-2020-26266.patch Patch0003: CVE-2020-26268.patch Patch0004: CVE-2020-26270.patch Patch0005: CVE-2020-26271.patch +Patch0006: CVE-2021-37682-1.patch +Patch0007: CVE-2021-37682-2.patch +Patch0008: CVE-2021-37685.patch +Patch0009: CVE-2021-37687.patch +Patch0010: CVE-2021-37688.patch +Patch0011: CVE-2021-37689.patch +Patch0012: CVE-2021-29512_CVE-2021-29514.patch +Patch0013: CVE-2021-29519.patch +Patch0014: CVE-2021-29520.patch +Patch0015: CVE-2021-29522.patch +Patch0016: CVE-2021-29524.patch +Patch0017: CVE-2021-29527.patch +Patch0018: CVE-2021-29528.patch +Patch0019: CVE-2021-29529.patch +Patch0020: CVE-2021-29530.patch +Patch0021: CVE-2021-29532.patch +Patch0022: CVE-2021-29536.patch +Patch0023: CVE-2021-29539.patch +Patch0024: CVE-2021-29541_CVE-2021-29542.patch +Patch0025: CVE-2021-29543.patch +Patch0026: CVE-2021-29545.patch +Patch0027: CVE-2021-29546.patch +Patch0028: CVE-2021-29547.patch +Patch0029: CVE-2021-29549.patch +Patch0030: CVE-2021-29550.patch +Patch0031: CVE-2021-29552.patch +Patch0032: CVE-2021-29553.patch +Patch0033: CVE-2021-29554.patch +Patch0034: CVE-2021-29555.patch +Patch0035: CVE-2021-29556.patch +Patch0036: CVE-2021-29557.patch +Patch0037: CVE-2021-29558.patch +Patch0038: CVE-2021-29559.patch +Patch0039: CVE-2021-29561.patch +Patch0040: CVE-2021-29562.patch +Patch0041: CVE-2021-29563.patch +Patch0042: CVE-2021-29564.patch +Patch0043: CVE-2021-29567.patch +Patch0044: CVE-2021-29568.patch +Patch0045: CVE-2021-29569.patch +Patch0046: CVE-2021-29570.patch +Patch0047: CVE-2021-29572.patch +Patch0048: CVE-2021-29573.patch +Patch0049: CVE-2021-29574.patch +Patch0050: CVE-2021-29575.patch +Patch0051: CVE-2021-29576.patch +Patch0052: CVE-2021-29577.patch +Patch0053: CVE-2021-29578.patch +Patch0054: CVE-2021-29579.patch +Patch0055: CVE-2021-29580.patch +Patch0056: CVE-2021-29581.patch +Patch0057: CVE-2021-29582.patch +Patch0058: CVE-2021-29585.patch +Patch0059: CVE-2021-29586.patch +Patch0060: CVE-2021-29587.patch +Patch0061: CVE-2021-29588.patch +Patch0062: CVE-2021-29590.patch +Patch0063: CVE-2021-29591.patch +Patch0064: CVE-2021-29592.patch +Patch0065: CVE-2021-29593.patch +Patch0066: CVE-2021-29596.patch +Patch0067: CVE-2021-29597.patch +Patch0068: CVE-2021-29598.patch +Patch0069: CVE-2021-29599.patch +Patch0070: CVE-2021-29600.patch +Patch0071: CVE-2021-29601.patch +Patch0072: CVE-2021-29603.patch +Patch0073: CVE-2021-29605.patch +Patch0074: CVE-2021-29606.patch +Patch0075: CVE-2021-29607-1.patch +Patch0076: CVE-2021-29607-2.patch +Patch0077: CVE-2021-29608-1.patch +Patch0078: CVE-2021-29608-2.patch +Patch0079: CVE-2021-29609.patch +Patch0080: CVE-2021-29613-1.patch +Patch0081: CVE-2021-29613-2.patch +Patch0082: CVE-2021-29615.patch +Patch0083: CVE-2021-29616.patch +Patch0084: CVE-2021-29617.patch +Patch0085: CVE-2021-29619.patch +Patch0086: CVE-2021-37637.patch +Patch0087: CVE-2021-37638.patch +Patch0088: CVE-2021-37639.patch +Patch0089: CVE-2021-37641.patch +Patch0090: CVE-2021-37644.patch +Patch0091: CVE-2021-37646.patch +Patch0092: CVE-2021-37647.patch +Patch0093: CVE-2021-37648.patch +Patch0094: CVE-2021-37649.patch +Patch0095: CVE-2021-37652.patch +Patch0096: CVE-2021-37656.patch +Patch0097: CVE-2021-37659.patch +Patch0098: CVE-2021-37660.patch +Patch0099: CVE-2021-37663.patch +Patch0100: CVE-2021-37667.patch +Patch0101: CVE-2021-37670.patch +Patch0102: CVE-2021-37671.patch +Patch0103: CVE-2021-37672.patch +Patch0104: CVE-2021-37673.patch +Patch0105: CVE-2021-37676.patch +Patch0106: CVE-2021-37677.patch +Patch0107: CVE-2021-37680.patch + Requires: python3-future Requires: python3-numpy @@ -61,6 +164,9 @@ bazel --output_user_root=`pwd`/../output_user_root build //tensorflow/tools/pip_ %{_bindir}/* %changelog +* Thu Aug 26 2021 yaoxin - 2.3.1-3 +- Fix CVE-2021-29512 CVE-2021-29514 CVE-2021-29519 CVE-2021-29520 CVE-2021-29522 CVE-2021-29524 CVE-2021-29527-to-CVE-2021-29530 CVE-2021-29532 CVE-2021-29536 CVE-2021-29539 CVE-2021-29541-to-CVE-2021-29543 CVE-2021-29545-to-CVE-2021-29547 CVE-2021-29549 CVE-2021-29550 CVE-2021-29552-to-CVE-2021-29559 CVE-2021-29561-to-CVE-2021-29564 CVE-2021-29567-to-CVE-2021-29570 CVE-2021-29572-to-CVE-2021-29582 CVE-2021-29585-to-CVE-2021-29588 CVE-2021-29590-to-CVE-2021-29593 CVE-2021-29596-to-CVE-2021-29601 CVE-2021-29603 CVE-2021-29605-to-CVE-2021-29609 CVE-2021-29613 CVE-2021-29615-to-CVE-2021-29617 CVE-2021-29619 CVE-2021-37637-to-CVE-2021-37639 CVE-2021-37641 CVE-2021-37644 CVE-2021-37646-to-CVE-2021-37649 CVE-2021-37652 CVE-2021-37656 CVE-2021-37659 CVE-2021-37660 CVE-2021-37663 CVE-2021-37667 CVE-2021-37670-to-CVE-2021-37673 CVE-2021-37676 CVE-2021-37677 CVE-2021-37680 CVE-2021-37682 CVE-2021-37685 CVE-2021-37687-to-CVE-2021-37689 + * Tue Aug 24 2021 yaoxin - 2.3.1-2 - Fix CVE-2020-26266 CVE-2020-26268 CVE-2020-26270 CVE-2020-26271