CVE-2023-25672: NULL Pointer Dereference (CWE-476)
value: TensorFlow is an open source platform for machine learning. The function `tf.raw_ops.LookupTableImportV2` cannot handle scalars in the `values` parameter and gives an NPE. A fix is included in TensorFlow version 2.12.0 and version 2.11.1.

CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 7.5
Published: 2023-03-25T00:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: Python
Files changed: tensorflow/core/ops/lookup_ops.cc, tensorflow/python/kernel_tests/data_structures/lookup_ops_test.py
Commit date: 2023-01-31 15:15:17 -0800
Commit message: Fixes shape inference of LookupTableImportV2 to handle scalar values.

PiperOrigin-RevId: 506126405

Diff: diff --git a/tensorflow/core/ops/lookup_ops.cc b/tensorflow/core/ops/lookup_ops.cc
index 2c279776dca93..4e074e0ef746e 100644
--- a/tensorflow/core/ops/lookup_ops.cc
+++ b/tensorflow/core/ops/lookup_ops.cc
@@ -307,13 +307,14 @@ REGISTER_OP("LookupTableImportV2")
       ShapeHandle handle;
       TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &handle));
 
       ShapeHandle keys;
       TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 1, &keys));
+      ShapeHandle values;
+      TF_RETURN_IF_ERROR(c->WithRankAtLeast(c->input(2), 1, &values));
       DimensionHandle unused;
-      TF_RETURN_IF_ERROR(
-          c->Merge(c->Dim(keys, 0), c->Dim(c->input(2), 0), &unused));
+      TF_RETURN_IF_ERROR(c->Merge(c->Dim(keys, 0), c->Dim(values, 0), &unused));
       return OkStatus();
     });
 
 Status MutableHashTableShape(InferenceContext* c, const ShapeHandle& key,
                              const ShapeHandle& value) {
diff --git a/tensorflow/python/kernel_tests/data_structures/lookup_ops_test.py b/tensorflow/python/kernel_tests/data_structures/lookup_ops_test.py
index f1e14a0279ca1..54a34d7e473dd 100644
--- a/tensorflow/python/kernel_tests/data_structures/lookup_ops_test.py
+++ b/tensorflow/python/kernel_tests/data_structures/lookup_ops_test.py
@@ -39,10 +39,11 @@ from tensorflow.python.framework import sparse_tensor
 from tensorflow.python.framework import tensor_spec
 from tensorflow.python.framework import test_ops
 from tensorflow.python.framework import test_util
 from tensorflow.python.ops import array_ops
 from tensorflow.python.ops import control_flow_ops
+from tensorflow.python.ops import gen_lookup_ops
 from tensorflow.python.ops import lookup_ops
 from tensorflow.python.ops import map_fn
 from tensorflow.python.ops import variables
 from tensorflow.python.ops.ragged import ragged_tensor
 from tensorflow.python.platform import test
@@ -571,10 +572,24 @@ class StaticHashTableTest(BaseLookupTableTest, parameterized.TestCase):
     grad = tape.gradient(loss, beta)
     self.evaluate(variables.global_variables_initializer())
     self.evaluate(lookup_ops.tables_initializer())
     self.assertAllEqual(grad, -10.)
 
+  def testImportShapeInference(self, is_anonymous):
+    v = variables.Variable(1)
+
+    @def_function.function(jit_compile=True)
+    def foo():
+      return gen_lookup_ops.lookup_table_import_v2(
+          table_handle=v.handle, keys=[1.1, 2.2], values=1
+      )
+
+    with self.assertRaisesRegex(
+        ValueError, r"Shape must be at least rank 1 but is rank 0"
+    ):
+      foo()
+
   def testExportShapeInference(self, is_anonymous):
     table = self.getHashTable()(
         lookup_ops.KeyValueTensorInitializer(
             constant_op.constant([2, 5], dtype=dtypes.int64),
             constant_op.constant([-10.0, 1], dtype=dtypes.float32)),

Vulnerable code:       TF_RETURN_IF_ERROR(
          c->Merge(c->Dim(keys, 0), c->Dim(c->input(2), 0), &unused));
Fixed code:       ShapeHandle values;
      TF_RETURN_IF_ERROR(c->WithRankAtLeast(c->input(2), 1, &values));
      TF_RETURN_IF_ERROR(c->Merge(c->Dim(keys, 0), c->Dim(values, 0), &unused));
from tensorflow.python.ops import gen_lookup_ops
  def testImportShapeInference(self, is_anonymous):
    v = variables.Variable(1)

    @def_function.function(jit_compile=True)
    def foo():
      return gen_lookup_ops.lookup_table_import_v2(
          table_handle=v.handle, keys=[1.1, 2.2], values=1
      )

    with self.assertRaisesRegex(
        ValueError, r"Shape must be at least rank 1 but is rank 0"
    ):
      foo()