CVE-2022-23562: Integer Overflow or Wraparound (CWE-190)
value: Tensorflow is an Open Source Machine Learning Framework. The implementation of `Range` suffers from integer overflows. These can trigger undefined behavior or, in some scenarios, extremely large allocations. The fix will be included in TensorFlow 2.8.0. We will also cherrypick this commit on TensorFlow 2.7.1, TensorFlow 2.6.3, and TensorFlow 2.5.3, as these are also affected and still in supported range.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 8.8
Published: 2022-02-04T23:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/kernels/sequence_ops.cc, tensorflow/core/ops/math_ops.cc
Commit date: 2021-12-16 19:26:39 -0800
Commit message: Merge pull request #52707 from elfringham:init_ops_test_fix

PiperOrigin-RevId: 416941851
Change-Id: Iefa5a9b841b053b36f6b105cd82c9d32d5e47850

Diff: diff --cc tensorflow/core/kernels/sequence_ops.cc
index 7e6f688edf4f7,66b664c3c9d4f..4ea36e9837ae0
--- a/tensorflow/core/kernels/sequence_ops.cc
+++ b/tensorflow/core/kernels/sequence_ops.cc
@@@ -89,28 -69,36 +89,34 @@@ class RangeOp : public OpKernel 
        OP_REQUIRES(
            context, start >= limit,
            errors::InvalidArgument(
                "Requires start >= limit when delta < 0: ", start, "/", limit));
      }
-     int64_t size = 0;
-     if (std::is_integral<T>::value) {
-       size = static_cast<int64_t>(
-           (std::abs(limit - start) + std::abs(delta) - 1) / std::abs(delta));
-     } else {
-       size = static_cast<int64_t>(std::ceil(std::abs((limit - start) / delta)));
-     }
+     auto size_auto = (std::is_integral<T>::value
 -	    ? (Eigen::numext::abs(limit - start) + 
 -		    Eigen::numext::abs(delta) - T(1)) / 
 -		    Eigen::numext::abs(delta)
 -	    : Eigen::numext::ceil(
 -		    Eigen::numext::abs((limit - start) / delta)));
 -    OP_REQUIRES(context, size_auto <= std::numeric_limits<int64_t>::max(),
 -          errors::InvalidArgument("Requires ((limit - start) / delta) <= ",
 -				  std::numeric_limits<int64_t>::max()));
++                          ? (Eigen::numext::abs(limit - start) +
++                             Eigen::numext::abs(delta) - T(1)) /
++                                Eigen::numext::abs(delta)
++                          : Eigen::numext::ceil(
++                                Eigen::numext::abs((limit - start) / delta)));
++    OP_REQUIRES(
++        context, size_auto <= std::numeric_limits<int64_t>::max(),
++        errors::InvalidArgument("Requires ((limit - start) / delta) <= ",
++                                std::numeric_limits<int64_t>::max()));
+ 
+     int64_t size = static_cast<int64_t>(size_auto);
+ 
      TensorShape shape;
      OP_REQUIRES_OK(context, shape.AddDimWithStatus(size));
      Tensor* out = nullptr;
      OP_REQUIRES_OK(context, context->allocate_output(0, shape, &out));
 +    if (size == 0) return;
      auto flat = out->flat<T>();
 -    T val = start;
 -    for (int64_t i = 0; i < size; ++i) {
 -      flat(i) = T(val);
 -      val += delta;
 -    }
 +    functor::RangeFunctor<Device, T>()(context, size, start, delta, flat);
    }
  };
  
 -#define REGISTER_KERNEL(DEV, TYPE)                           \
 +#define REGISTER_KERNEL(DEV, DEV_TYPE, TYPE)                 \
    REGISTER_KERNEL_BUILDER(Name("Range")                      \
                                .Device(DEV)                   \
                                .HostMemory("start")           \
                                .HostMemory("limit")           \
                                .HostMemory("delta")           \
diff --cc tensorflow/core/ops/math_ops.cc
index 3f653287fdb2f,3d7bea60694c5..7bc9f8c9ffd29
--- a/tensorflow/core/ops/math_ops.cc
+++ b/tensorflow/core/ops/math_ops.cc
@@@ -1487,10 -1487,17 +1487,17 @@@ Status RangeSize(const Tensor* start_t
                     ? ((Eigen::numext::abs(limit - start) +
                         Eigen::numext::abs(delta) - T(1)) /
                        Eigen::numext::abs(delta))
                     : (Eigen::numext::ceil(
                           Eigen::numext::abs((limit - start) / delta))));
+ 
+   // Undefined behaviour if size will not fit into int64_t
+   if (size > std::numeric_limits<int64_t>::max()) {
 -    return errors::InvalidArgument(
 -        "Requires ((limit - start) / delta) <= ", std::numeric_limits<int64_t>::max());
++    return errors::InvalidArgument("Requires ((limit - start) / delta) <= ",
++                                   std::numeric_limits<int64_t>::max());
+   }
+ 
    c->set_output(0, c->Vector(static_cast<int64_t>(size)));
    return Status::OK();
  }
  
  }  // namespace

Vulnerable code:      int64_t size = 0;
     if (std::is_integral<T>::value) {
       size = static_cast<int64_t>(
           (std::abs(limit - start) + std::abs(delta) - 1) / std::abs(delta));
     } else {
       size = static_cast<int64_t>(std::ceil(std::abs((limit - start) / delta)));
     }
Fixed code:      auto size_auto = (std::is_integral<T>::value
+                          ? (Eigen::numext::abs(limit - start) +
+                             Eigen::numext::abs(delta) - T(1)) /
+                                Eigen::numext::abs(delta)
+                          : Eigen::numext::ceil(
+                                Eigen::numext::abs((limit - start) / delta)));
+    OP_REQUIRES(
+        context, size_auto <= std::numeric_limits<int64_t>::max(),
+        errors::InvalidArgument("Requires ((limit - start) / delta) <= ",
+                                std::numeric_limits<int64_t>::max()));
 
     int64_t size = static_cast<int64_t>(size_auto);
 
 
   // Undefined behaviour if size will not fit into int64_t
   if (size > std::numeric_limits<int64_t>::max()) {
+    return errors::InvalidArgument("Requires ((limit - start) / delta) <= ",
+                                   std::numeric_limits<int64_t>::max());
   }