CVE-2022-41909 (published 2022-11-18T22:15Z)

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.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/tensorflow/tensorflow
commit_details: repo_url: https://github.com/tensorflow/tensorflow
author: Jun Xu
author_date: 2022-09-14 14:54:10-07:00
msg: [Security] Add a check for empty variant tensor input to CompositeTensorVariantToComponents.

So an exception will be raised instead of segfault.

PiperOrigin-RevId: 474397914
repository: repo_url: https://github.com/tensorflow/tensorflow
repo_name: tensorflow/tensorflow
description: An Open Source Machine Learning Framework for Everyone
repo_language: C++
owner: tensorflow
file_changes: filename: composite_tensor_ops.cc
change_type: ModificationType.MODIFY
diff: @@ -15,6 +15,7 @@ limitations under the License.
 
 #include "tensorflow/core/framework/op.h"
 #include "tensorflow/core/framework/op_kernel.h"
+#include "tensorflow/core/framework/op_requires.h"
 #include "tensorflow/core/framework/variant.h"
 #include "tensorflow/core/framework/variant_encode_decode.h"
 #include "tensorflow/core/kernels/composite_tensor_variant.h"
@@ -66,6 +67,11 @@ class CompositeTensorVariantToComponents : public OpKernel {
 
   void Compute(OpKernelContext* context) override {
     Tensor encoded_t = context->input(0);
+    OP_REQUIRES(
+        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>();
 
     // Check that the encoded TypeSpec is compatible with the expected TypeSpec.

programming_language: TypeScript
filename: composite_tensor_ops_test.py
change_type: ModificationType.MODIFY
diff: @@ -18,11 +18,13 @@ from absl.testing import parameterized
 
 from tensorflow.python.eager import backprop
 from tensorflow.python.eager import context
+from tensorflow.python.framework import constant_op
 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 gradients_impl
 from tensorflow.python.ops import math_ops
 from tensorflow.python.ops import parsing_ops
@@ -83,6 +85,18 @@ class ExtensionTypeTest(test_util.TensorFlowTestCase, parameterized.TestCase):
     with self.assertRaisesRegex(ValueError, message):
       composite_tensor_ops.composite_tensor_to_variants(value(), spec)
 
+  def testDecodingEmptyNonScalarTensorError(self):
+    if not context.executing_eagerly():
+      # Creating a variant tensor of an empty list is not allowed in eager mode.
+      return
+
+    with self.assertRaisesRegex(errors.InvalidArgumentError,
+                                'must not be an empty variant tensor'):
+      gen_composite_tensor_ops.CompositeTensorVariantToComponents(
+          encoded=constant_op.constant([], dtype=dtypes.variant),
+          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)

programming_language: Python
repo_url: https://github.com/tensorflow/tensorflow
commit_details: repo_url: https://github.com/tensorflow/tensorflow
author: Jun Xu
author_date: 2022-09-15 10:18:37-07:00
msg: [Security] Raise an exception when input to CompositeTensorVariantToComponents is not a valid CompositeTensorVariant tensor.

So TF won't crash.

PiperOrigin-RevId: 474594628
repository: repo_url: https://github.com/tensorflow/tensorflow
repo_name: tensorflow/tensorflow
description: An Open Source Machine Learning Framework for Everyone
repo_language: C++
owner: tensorflow
file_changes: filename: composite_tensor_ops.cc
change_type: ModificationType.MODIFY
diff: @@ -73,6 +73,10 @@ class CompositeTensorVariantToComponents : public OpKernel {
                                 "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.

programming_language: TypeScript
filename: composite_tensor_ops_test.py
change_type: ModificationType.MODIFY
diff: @@ -25,6 +25,7 @@ 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
@@ -97,6 +98,18 @@ class ExtensionTypeTest(test_util.TensorFlowTestCase, parameterized.TestCase):
           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)

programming_language: Python