CVE-2022-35992: Reachable Assertion (CWE-617)
value: TensorFlow is an open source platform for machine learning. When `TensorListFromTensor` receives an `element_shape` of a rank greater than one, it gives a `CHECK` fail that can trigger a denial of service attack. We have patched the issue in GitHub commit 3db59a042a38f4338aa207922fa2f476e000a6ee. The fix will be included in TensorFlow 2.10.0. We will also cherrypick this commit on TensorFlow 2.9.1, TensorFlow 2.8.1, and TensorFlow 2.7.2, as these are also affected and still in supported range. There are no known workarounds for this issue.
CWE description: The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary.
CVSS v3 base score: 7.5
Published: 2022-09-16T23:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: Python
Files changed: tensorflow/core/kernels/list_kernels.h, tensorflow/python/kernel_tests/data_structures/list_ops_test.py
Commit date: 2022-07-21 14:18:40 -0700
Commit message: Check for element_shape in TensorListFromTensor

PiperOrigin-RevId: 462468167

Diff: diff --git a/tensorflow/core/kernels/list_kernels.h b/tensorflow/core/kernels/list_kernels.h
index 96872c5486a33..29f130b87b078 100644
--- a/tensorflow/core/kernels/list_kernels.h
+++ b/tensorflow/core/kernels/list_kernels.h
@@ -767,10 +767,15 @@ class TensorListFromTensor : public OpKernel {
     Tensor* output_tensor;
     AllocatorAttributes attr;
     attr.set_on_host(true);
     OP_REQUIRES_OK(c, c->allocate_output(0, {}, &output_tensor, attr));
     PartialTensorShape element_shape;
+    OP_REQUIRES(
+        c, !TensorShapeUtils::IsMatrixOrHigher(c->input(1).shape()),
+        errors::InvalidArgument(
+            "TensorListFromTensor: element_shape must be at most rank 1 but ",
+            "has the shape of ", c->input(1).shape().DebugString()));
     OP_REQUIRES_OK(c, TensorShapeFromTensor(c->input(1), &element_shape));
     TensorList output_list;
     const Tensor& t = c->input(0);
     output_list.element_dtype = t.dtype();
     OP_REQUIRES(c, TensorShapeUtils::IsVectorOrHigher(t.shape()),
diff --git a/tensorflow/python/kernel_tests/data_structures/list_ops_test.py b/tensorflow/python/kernel_tests/data_structures/list_ops_test.py
index 7e7ad79e78a33..801372dce266c 100644
--- a/tensorflow/python/kernel_tests/data_structures/list_ops_test.py
+++ b/tensorflow/python/kernel_tests/data_structures/list_ops_test.py
@@ -582,10 +582,21 @@ class ListOpsTest(test_util.TensorFlowTestCase, parameterized.TestCase):
     self.assertAllEqual(e, 2.0)
     l, e = list_ops.tensor_list_pop_back(l, element_dtype=dtypes.float32)
     self.assertAllEqual(e, 1.0)
     self.assertAllEqual(list_ops.tensor_list_length(l), 0)
 
+  def testTensorListFromTensorFailsWhenElementShapeIsNotVector(self):
+    t = constant_op.constant([1.0, 2.0])
+    # In Eager mode, InvalidArgumentError is generated by the Compute function.
+    # In graph mode, ValueError is generated by the shape function.
+    with self.assertRaisesRegex(
+        (errors.InvalidArgumentError, ValueError),
+        "must be at most rank 1"):
+      # Wrong element_shape. Should be at most rank 1.
+      l = list_ops.tensor_list_from_tensor(t, element_shape=[[1]])
+      self.evaluate(l)
+
   @test_util.run_gpu_only
   def testFromTensorGPU(self):
     with context.device("gpu:0"):
       self.testTensorListFromTensor()
 

Fixed code:     OP_REQUIRES(
        c, !TensorShapeUtils::IsMatrixOrHigher(c->input(1).shape()),
        errors::InvalidArgument(
            "TensorListFromTensor: element_shape must be at most rank 1 but ",
            "has the shape of ", c->input(1).shape().DebugString()));
  def testTensorListFromTensorFailsWhenElementShapeIsNotVector(self):
    t = constant_op.constant([1.0, 2.0])
    # In Eager mode, InvalidArgumentError is generated by the Compute function.
    # In graph mode, ValueError is generated by the shape function.
    with self.assertRaisesRegex(
        (errors.InvalidArgumentError, ValueError),
        "must be at most rank 1"):
      # Wrong element_shape. Should be at most rank 1.
      l = list_ops.tensor_list_from_tensor(t, element_shape=[[1]])
      self.evaluate(l)