CVE-2022-41890: Incorrect Type Conversion or Cast (CWE-704)
value: TensorFlow is an open source platform for machine learning. If `BCast::ToShape` is given input larger than an `int32`, it will crash, despite being supposed to handle up to an `int64`. An example can be seen in `tf.experimental.numpy.outer` by passing in large input to the input `b`. We have patched the issue in GitHub commit 8310bf8dd188ff780e7fc53245058215a05bdbe5. 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 convert an object, resource, or structure from one type to a different type.
CVSS v3 base score: 7.5
Published: 2022-11-18T22:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C
Files changed: tensorflow/core/util/bcast.h, tensorflow/core/util/bcast_test.cc
Commit date: 2022-09-20 16:20:05 -0700
Commit message: Fix crash caused by large broadcasting error.  There was an int32 overflow.

PiperOrigin-RevId: 475677838

Diff: diff --git a/tensorflow/core/util/bcast.h b/tensorflow/core/util/bcast.h
index cbd7a6f8693e3..531c47aec3dab 100644
--- a/tensorflow/core/util/bcast.h
+++ b/tensorflow/core/util/bcast.h
@@ -132,11 +132,11 @@ BCastList<N>::BCastList(const BCastList::Vec (&x)[N],
                         const bool fewer_dims_optimization,
                         const bool return_flattened_batch_indices) {
   typedef BCastList::Vec Vec;
 
   // Safely multiplies dimensions taking into account symbolic shapes.
-  auto mul_dims = [](int64_t dim1, int64_t dim2) -> int64 {
+  auto mul_dims = [](int64_t dim1, int64_t dim2) -> int64_t {
     return dim1 != 0 && dim2 != 0 && (dim1 < 0 || dim2 < 0) ? -1 : dim1 * dim2;
   };
 
   bool all_equal = true;
   size_t largest_rank = 0;
@@ -197,11 +197,11 @@ BCastList<N>::BCastList(const BCastList::Vec (&x)[N],
     prev_is_one[i] = false;
     current_is_one[i] = false;
   }
   Vec output;
   bool output_dim_set = false;
-  int output_dim = -1;
+  int64_t output_dim = -1;
   bool none_is_one = true;
   bool set_one = false;
   for (int j = 0; j < largest_rank; ++j) {
     output_dim = -1;
     output_dim_set = false;
diff --git a/tensorflow/core/util/bcast_test.cc b/tensorflow/core/util/bcast_test.cc
index 60eb7859ec3f1..f33483a5846d6 100644
--- a/tensorflow/core/util/bcast_test.cc
+++ b/tensorflow/core/util/bcast_test.cc
@@ -373,10 +373,17 @@ TEST(BCastTest, Basic_Tensor_Scalar) {
   EXPECT_EQ(BCast({1}, {11, 7, 5, 3, 2}, false),
             "[1,1,1,1,1][11,7,5,3,2][11,7,5,3,2][1,1,1,1,1]"
             "[11,7,5,3,2]"
             "[11,7,5,3,2]"
             "[0,1,2,3,4][]");
+
+  // int32 edge-case:
+  EXPECT_EQ(BCast({1, 2147483648}, {1}),
+            "[2147483648][1][1][2147483648]"
+            "[2147483648]"
+            "[1,2147483648]"
+            "[0][0,1]");
 }
 
 TEST(BCastTest, Basic_Tensor_With_DimSize_1_Scalar) {
   // Effectively it's a tensor and a scalar.
   // [11, 7, 5, 3, 2, 1] [1]

Vulnerable code:   auto mul_dims = [](int64_t dim1, int64_t dim2) -> int64 {
  int output_dim = -1;
Fixed code:   auto mul_dims = [](int64_t dim1, int64_t dim2) -> int64_t {
  int64_t output_dim = -1;

  // int32 edge-case:
  EXPECT_EQ(BCast({1, 2147483648}, {1}),
            "[2147483648][1][1][2147483648]"
            "[2147483648]"
            "[1,2147483648]"
            "[0][0,1]");