CVE-2022-41885: Incorrect Calculation of Buffer Size (CWE-131)
value: TensorFlow is an open source platform for machine learning. When `tf.raw_ops.FusedResizeAndPadConv2D` is given a large tensor shape, it overflows. We have patched the issue in GitHub commit d66e1d568275e6a2947de97dca7a102a211e01ce. The fix will be included in TensorFlow 2.11. We will also cherrypick this commit on TensorFlow 2.10.1, 2.9.3, and TensorFlow 2.8.4, as these are also affected and still in supported range.
CWE description: The product does not correctly calculate the size to be used when allocating a buffer, which could lead to a buffer overflow.
CVSS v3 base score: 7.5
Published: 2022-11-18T22:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/kernels/conv_ops_fused_image_transform.cc, tensorflow/core/ops/nn_ops.cc, tensorflow/python/kernel_tests/nn_ops/conv_ops_test.py
Commit date: 2022-09-29 09:35:15 -0700
Commit message: Fix tensor shape overflow in FusedResizeAndPadConv2D.

Replaced TensorShape constructor by Factory method with status.

PiperOrigin-RevId: 477742686

Diff: diff --git a/tensorflow/core/kernels/conv_ops_fused_image_transform.cc b/tensorflow/core/kernels/conv_ops_fused_image_transform.cc
index ac76cef5bb8c8..dd2db39fbd127 100644
--- a/tensorflow/core/kernels/conv_ops_fused_image_transform.cc
+++ b/tensorflow/core/kernels/conv_ops_fused_image_transform.cc
@@ -665,12 +665,15 @@ class FusedResizeConv2DUsingGemmOp : public OpKernel {
       st.in_width = input.dim_size(2);
       st.channels = input.dim_size(3);
       st.height_scale = 1.0f;
       st.width_scale = 1.0f;
     }
-    TensorShape resized_shape(
-        {input.dim_size(0), st.out_height, st.out_width, input.dim_size(3)});
+    TensorShape resized_shape;
+    OP_REQUIRES_OK(context, TensorShape::BuildTensorShape(
+                                {input.dim_size(0), st.out_height, st.out_width,
+                                 input.dim_size(3)},
+                                &resized_shape));
     int paddings_index;
     int filter_index;
     if (DoResize) {
       paddings_index = 2;
       filter_index = 3;
diff --git a/tensorflow/core/ops/nn_ops.cc b/tensorflow/core/ops/nn_ops.cc
index ce03881e26049..417034477d1fc 100644
--- a/tensorflow/core/ops/nn_ops.cc
+++ b/tensorflow/core/ops/nn_ops.cc
@@ -579,11 +579,11 @@ REGISTER_OP("FusedResizeAndPadConv2D")
     .Attr("resize_align_corners: bool = false")
     .Attr(GetMirrorPadModeAttrString())
     .Attr("strides: list(int)")
     .Attr(GetPaddingAttrString())
     .SetShapeFn([](InferenceContext* c) {
-      return CommonFusedConvCalculations(c, true /* has_resize */);
+      return CommonFusedConvCalculations(c, /*has_resize=*/true);
     });
 
 REGISTER_OP("FusedPadConv2D")
     .Input("input: T")
     .Input("paddings: int32")
@@ -592,11 +592,11 @@ REGISTER_OP("FusedPadConv2D")
     .Attr("T: {half, float, double}")
     .Attr(GetMirrorPadModeAttrString())
     .Attr("strides: list(int)")
     .Attr(GetPaddingAttrString())
     .SetShapeFn([](InferenceContext* c) {
-      return CommonFusedConvCalculations(c, false /* has_resize */);
+      return CommonFusedConvCalculations(c, /*has_resize=*/false);
     });
 
 // --------------------------------------------------------------------------
 
 REGISTER_OP("DepthwiseConv2dNative")
diff --git a/tensorflow/python/kernel_tests/nn_ops/conv_ops_test.py b/tensorflow/python/kernel_tests/nn_ops/conv_ops_test.py
index 463c63f41f724..c41448453e6fb 100644
--- a/tensorflow/python/kernel_tests/nn_ops/conv_ops_test.py
+++ b/tensorflow/python/kernel_tests/nn_ops/conv_ops_test.py
@@ -3427,10 +3427,37 @@ class FusedConv2DTest(test.TestCase):
 
     self.assertAllEqual(
         np.rint(expected_output),
         self.evaluate(add).reshape(-1))
 
+  # Fused resize and pad conv.
+  @test_util.run_in_graph_and_eager_modes()
+  def testResizeAndPadLargeResize(self):
+    with self.assertRaisesRegex((ValueError, errors_impl.InvalidArgumentError),
+                                "Encountered overflow"):
+      mode = "REFLECT"
+      strides = [1, 1, 1, 1]
+      padding = "SAME"
+      resize_align_corners = False
+      tensor = constant_op.constant(
+          147, shape=[3, 3, 1, 4], dtype=dtypes.float32)
+      size = constant_op.constant([1879048192, 1879048192], dtype=dtypes.int32)
+      paddings = constant_op.constant([[0, 0], [0, 0], [0, 0], [0, 0]],
+                                      dtype=dtypes.int32)
+      kernel = constant_op.constant(
+          123, shape=[1, 3, 4, 1], dtype=dtypes.float32)
+      self.evaluate(
+          gen_nn_ops.fused_resize_and_pad_conv2d(
+              input=tensor,
+              size=size,
+              paddings=paddings,
+              filter=kernel,
+              mode=mode,
+              strides=strides,
+              padding=padding,
+              resize_align_corners=resize_align_corners))
+
 
 if __name__ == "__main__":
   for index, (input_size_, filter_size_, output_size_, stride_,
               padding_) in enumerate(GetShrunkInceptionShapes()):
     setattr(Conv2DTest, "testInceptionFwd_" + str(index),

Vulnerable code:     TensorShape resized_shape(
        {input.dim_size(0), st.out_height, st.out_width, input.dim_size(3)});
      return CommonFusedConvCalculations(c, true /* has_resize */);
      return CommonFusedConvCalculations(c, false /* has_resize */);
Fixed code:     TensorShape resized_shape;
    OP_REQUIRES_OK(context, TensorShape::BuildTensorShape(
                                {input.dim_size(0), st.out_height, st.out_width,
                                 input.dim_size(3)},
                                &resized_shape));
      return CommonFusedConvCalculations(c, /*has_resize=*/true);
      return CommonFusedConvCalculations(c, /*has_resize=*/false);
  # Fused resize and pad conv.
  @test_util.run_in_graph_and_eager_modes()
  def testResizeAndPadLargeResize(self):
    with self.assertRaisesRegex((ValueError, errors_impl.InvalidArgumentError),
                                "Encountered overflow"):
      mode = "REFLECT"
      strides = [1, 1, 1, 1]
      padding = "SAME"
      resize_align_corners = False
      tensor = constant_op.constant(
          147, shape=[3, 3, 1, 4], dtype=dtypes.float32)
      size = constant_op.constant([1879048192, 1879048192], dtype=dtypes.int32)
      paddings = constant_op.constant([[0, 0], [0, 0], [0, 0], [0, 0]],
                                      dtype=dtypes.int32)
      kernel = constant_op.constant(
          123, shape=[1, 3, 4, 1], dtype=dtypes.float32)
      self.evaluate(
          gen_nn_ops.fused_resize_and_pad_conv2d(
              input=tensor,
              size=size,
              paddings=paddings,
              filter=kernel,
              mode=mode,
              strides=strides,
              padding=padding,
              resize_align_corners=resize_align_corners))