CVE-2021-41202: Incorrect Conversion between Numeric Types (CWE-681)
value: TensorFlow is an open source platform for machine learning. In affected versions while calculating the size of the output within the `tf.range` kernel, there is a conditional statement of type `int64 = condition ? int64 : double`. Due to C++ implicit conversion rules, both branches of the condition will be cast to `double` and the result would be truncated before the assignment. This result in overflows. The fix will be included in TensorFlow 2.7.0. We will also cherrypick this commit on TensorFlow 2.6.1, TensorFlow 2.5.2, and TensorFlow 2.4.4, as these are also affected and still in supported range.
CWE description: When converting from one data type to another, such as long to integer, data can be omitted or translated in a way that produces unexpected values. If the resulting values are used in a sensitive context, then dangerous behaviors may occur.
CVSS v3 base score: 5.5
Published: 2021-11-05T22:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/kernels/sequence_ops.cc
Commit date: 2021-08-18 08:14:11 -0700
Commit message: Merge pull request #51359 from yongtang:46913-range-overflow

PiperOrigin-RevId: 391529518
Change-Id: Ie3db4ae6d3c0f3dc88404e1dbdc22f7d03cbeb3b

Diff: diff --cc tensorflow/core/kernels/sequence_ops.cc
index 69a5c3f10c65d,c803c89d059d6..ad1b1471c3006
--- a/tensorflow/core/kernels/sequence_ops.cc
+++ b/tensorflow/core/kernels/sequence_ops.cc
@@@ -69,14 -69,18 +69,17 @@@ class RangeOp : public OpKernel 
        OP_REQUIRES(
            context, start >= limit,
            errors::InvalidArgument(
                "Requires start >= limit when delta < 0: ", start, "/", limit));
      }
-     int64_t size = (std::is_integral<T>::value
-                         ? ((std::abs(limit - start) + std::abs(delta) - 1) /
-                            std::abs(delta))
-                         : std::ceil(std::abs((limit - start) / delta)));
+     int64_t size = 0;
+     if (std::is_integral<T>::value) {
+       size = static_cast<int64>(
 -        (std::abs(limit - start) + std::abs(delta) - 1) / std::abs(delta));
++          (std::abs(limit - start) + std::abs(delta) - 1) / std::abs(delta));
+     } else {
 -      size = static_cast<int64>(
 -        std::ceil(std::abs((limit - start) / delta)));
++      size = static_cast<int64>(std::ceil(std::abs((limit - start) / delta)));
+     }
      Tensor* out = nullptr;
      OP_REQUIRES_OK(context,
                     context->allocate_output(0, TensorShape({size}), &out));
      auto flat = out->flat<T>();
      T val = start;

Vulnerable code:      int64_t size = (std::is_integral<T>::value
                         ? ((std::abs(limit - start) + std::abs(delta) - 1) /
                            std::abs(delta))
                         : std::ceil(std::abs((limit - start) / delta)));
Fixed code:      int64_t size = 0;
     if (std::is_integral<T>::value) {
       size = static_cast<int64>(
+          (std::abs(limit - start) + std::abs(delta) - 1) / std::abs(delta));
     } else {
+      size = static_cast<int64>(std::ceil(std::abs((limit - start) / delta)));
     }