CVE-2022-41909: NULL Pointer Dereference (CWE-476)
value: TensorFlow is an open source platform for machine learning. An input `encoded` that is not a valid `CompositeTensorVariant` tensor will trigger a segfault in `tf.raw_ops.CompositeTensorVariantToComponents`. We have patched the issue in GitHub commits bf594d08d377dc6a3354d9fdb494b32d45f91971 and 660ce5a89eb6766834bdc303d2ab3902aef99d3d. 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 dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 7.5
Published: 2022-11-18T22:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: Python
Files changed: tensorflow/core/kernels/composite_tensor_ops.cc, tensorflow/python/kernel_tests/composite_tensor_ops_test.py
Commit date: 2022-09-15 10:21:48 -0700
Commit message: [Security] Raise an exception when input to CompositeTensorVariantToComponents is not a valid CompositeTensorVariant tensor.

So TF won't crash.

PiperOrigin-RevId: 474594628

Diff: diff --git a/tensorflow/core/kernels/composite_tensor_ops.cc b/tensorflow/core/kernels/composite_tensor_ops.cc
index bc4f96e6bb2fe..4e689d27d5acb 100644
--- a/tensorflow/core/kernels/composite_tensor_ops.cc
+++ b/tensorflow/core/kernels/composite_tensor_ops.cc
@@ -71,10 +71,14 @@ class CompositeTensorVariantToComponents : public OpKernel {
         context, encoded_t.flat<Variant>().size() > 0,
         errors::InvalidArgument("Input `encoded` must not be an empty variant "
                                 "tensor, but got ",
                                 encoded_t.DebugString()));
     auto* encoded = encoded_t.flat<Variant>()(0).get<CompositeTensorVariant>();
+    OP_REQUIRES(context, encoded != nullptr,
+                errors::InvalidArgument("The input `encoded` is not a valid "
+                                        "CompositeTensorVariant tensor, got ",
+                                        encoded_t.DebugString()));
 
     // Check that the encoded TypeSpec is compatible with the expected TypeSpec.
     // For now, we just check that the class matches.
     //
     // TODO(b/173744905): Update this to do a generic compatibility check. This
diff --git a/tensorflow/python/kernel_tests/composite_tensor_ops_test.py b/tensorflow/python/kernel_tests/composite_tensor_ops_test.py
index 7a10cae3ebc10..4bce5c624d2ea 100644
--- a/tensorflow/python/kernel_tests/composite_tensor_ops_test.py
+++ b/tensorflow/python/kernel_tests/composite_tensor_ops_test.py
@@ -23,10 +23,11 @@ from tensorflow.python.framework import dtypes
 from tensorflow.python.framework import errors
 from tensorflow.python.framework import sparse_tensor
 from tensorflow.python.framework import test_util
 from tensorflow.python.ops import composite_tensor_ops
 from tensorflow.python.ops import gen_composite_tensor_ops
+from tensorflow.python.ops import gen_list_ops
 from tensorflow.python.ops import gradients_impl
 from tensorflow.python.ops import math_ops
 from tensorflow.python.ops import parsing_ops
 from tensorflow.python.ops import sparse_ops
 from tensorflow.python.ops.ragged import ragged_factory_ops
@@ -95,10 +96,22 @@ class ExtensionTypeTest(test_util.TensorFlowTestCase, parameterized.TestCase):
       gen_composite_tensor_ops.CompositeTensorVariantToComponents(
           encoded=constant_op.constant([], dtype=dtypes.variant),
           metadata='',
           Tcomponents=[dtypes.int32])
 
+  def testDecodingInvalidEncodedInputError(self):
+    with self.assertRaisesRegex(errors.InvalidArgumentError,
+                                'not a valid CompositeTensorVariant tensor'):
+      self.evaluate(
+          gen_composite_tensor_ops.CompositeTensorVariantToComponents(
+              encoded=gen_list_ops.EmptyTensorList(
+                  element_dtype=dtypes.int32,
+                  element_shape=[1, 2],
+                  max_num_elements=2),
+              metadata='',
+              Tcomponents=[dtypes.int32]))
+
   def testRoundTripThroughTensorProto(self):
     value = ragged_factory_ops.constant([[1, 2], [3], [4, 5, 6]])
     encoded = composite_tensor_ops.composite_tensor_to_variants(value)
     proto = parsing_ops.SerializeTensor(tensor=encoded)
     parsed = parsing_ops.ParseTensor(serialized=proto, out_type=dtypes.variant)

Fixed code:     OP_REQUIRES(context, encoded != nullptr,
                errors::InvalidArgument("The input `encoded` is not a valid "
                                        "CompositeTensorVariant tensor, got ",
                                        encoded_t.DebugString()));
from tensorflow.python.ops import gen_list_ops
  def testDecodingInvalidEncodedInputError(self):
    with self.assertRaisesRegex(errors.InvalidArgumentError,
                                'not a valid CompositeTensorVariant tensor'):
      self.evaluate(
          gen_composite_tensor_ops.CompositeTensorVariantToComponents(
              encoded=gen_list_ops.EmptyTensorList(
                  element_dtype=dtypes.int32,
                  element_shape=[1, 2],
                  max_num_elements=2),
              metadata='',
              Tcomponents=[dtypes.int32]))