CVE-2022-41907: Incorrect Calculation of Buffer Size (CWE-131)
value: TensorFlow is an open source platform for machine learning. When `tf.raw_ops.ResizeNearestNeighborGrad` is given a large `size` input, it overflows. We have patched the issue in GitHub commit 00c821af032ba9e5f5fa3fe14690c8d28a657624. 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: Python
Files changed: tensorflow/core/kernels/image/resize_nearest_neighbor_op.cc, tensorflow/python/ops/image_ops_test.py
Commit date: 2022-10-05 14:27:38 -0700
Commit message: Fix tf.raw_ops.ResizeNearestNeighborGrad vulnerability with large dimensions.

Note: This fix will have to be cherry picked in r2.10, r2.9, and r2.8.
PiperOrigin-RevId: 479141644

Diff: diff --git a/tensorflow/core/kernels/image/resize_nearest_neighbor_op.cc b/tensorflow/core/kernels/image/resize_nearest_neighbor_op.cc
index a54b60f0099a0..0d0e0cbdbe639 100644
--- a/tensorflow/core/kernels/image/resize_nearest_neighbor_op.cc
+++ b/tensorflow/core/kernels/image/resize_nearest_neighbor_op.cc
@@ -255,15 +255,15 @@ class ResizeNearestNeighborOpGrad : public OpKernel {
 
     const int64_t out_height = sizes(0);
     const int64_t out_width = sizes(1);
 
     Tensor* output = nullptr;
-    OP_REQUIRES_OK(
-        context,
-        context->allocate_output(
-            0, TensorShape({batch_size, out_height, out_width, channels}),
-            &output));
+    TensorShape shape;
+    OP_REQUIRES_OK(context,
+                   TensorShape::BuildTensorShape(
+                       {batch_size, out_height, out_width, channels}, &shape));
+    OP_REQUIRES_OK(context, context->allocate_output(0, shape, &output));
 
     // Return if the output is empty.
     if (output->NumElements() == 0) return;
 
     typename TTypes<T, 4>::ConstTensor input_data(input.tensor<T, 4>());
diff --git a/tensorflow/python/ops/image_ops_test.py b/tensorflow/python/ops/image_ops_test.py
index 66dd42d7e6a89..332bf05ecb953 100644
--- a/tensorflow/python/ops/image_ops_test.py
+++ b/tensorflow/python/ops/image_ops_test.py
@@ -4173,10 +4173,29 @@ class ResizeImageWithPadV2Test(test_util.TensorFlowTestCase):
     y_shape = [1, 2, 1]
 
     self._assertReturns(x, x_shape, y, y_shape)
 
 
+class ResizeNearestNeighborGrad(test_util.TensorFlowTestCase):
+
+  def testSizeTooLarge(self):
+    align_corners = True
+    half_pixel_centers = False
+    grads = constant_op.constant(1, shape=[1, 8, 16, 3], dtype=dtypes.float16)
+    size = constant_op.constant([1879048192, 1879048192],
+                                shape=[2],
+                                dtype=dtypes.int32)
+    with self.assertRaisesRegex(errors.InvalidArgumentError,
+                                r"Encountered overflow when multiplying"):
+      self.evaluate(
+          gen_image_ops.ResizeNearestNeighborGrad(
+              grads=grads,
+              size=size,
+              align_corners=align_corners,
+              half_pixel_centers=half_pixel_centers))
+
+
 class ResizeImageWithCropOrPadTest(test_util.TensorFlowTestCase):
 
   def _ResizeImageWithCropOrPad(self, x, target_height, target_width,
                                 use_tensor_inputs):
     if use_tensor_inputs:

Vulnerable code:     OP_REQUIRES_OK(
        context,
        context->allocate_output(
            0, TensorShape({batch_size, out_height, out_width, channels}),
            &output));
Fixed code:     TensorShape shape;
    OP_REQUIRES_OK(context,
                   TensorShape::BuildTensorShape(
                       {batch_size, out_height, out_width, channels}, &shape));
    OP_REQUIRES_OK(context, context->allocate_output(0, shape, &output));
class ResizeNearestNeighborGrad(test_util.TensorFlowTestCase):

  def testSizeTooLarge(self):
    align_corners = True
    half_pixel_centers = False
    grads = constant_op.constant(1, shape=[1, 8, 16, 3], dtype=dtypes.float16)
    size = constant_op.constant([1879048192, 1879048192],
                                shape=[2],
                                dtype=dtypes.int32)
    with self.assertRaisesRegex(errors.InvalidArgumentError,
                                r"Encountered overflow when multiplying"):
      self.evaluate(
          gen_image_ops.ResizeNearestNeighborGrad(
              grads=grads,
              size=size,
              align_corners=align_corners,
              half_pixel_centers=half_pixel_centers))