CVE-2021-29526: Divide By Zero (CWE-369)
value: TensorFlow is an end-to-end open source platform for machine learning. An attacker can trigger a division by 0 in `tf.raw_ops.Conv2D`. This is because the implementation(https://github.com/tensorflow/tensorflow/blob/988087bd83f144af14087fe4fecee2d250d93737/tensorflow/core/kernels/conv_ops.cc#L261-L263) does a division by a quantity that is controlled by the caller. The fix will be included in TensorFlow 2.5.0. We will also cherrypick this commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 2.1.4, as these are also affected and still in supported range.
CWE description: The product divides a value by zero.
CVSS v3 base score: 5.5
Published: 2021-05-14T20:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/kernels/conv_ops.cc
Commit date: 2021-04-19 18:48:47 -0700
Commit message: Fix one more FPE.

PiperOrigin-RevId: 369346568
Change-Id: I840fd575962adc879713a4c9cc59e6da3331caa7

Diff: diff --git a/tensorflow/core/kernels/conv_ops.cc b/tensorflow/core/kernels/conv_ops.cc
index 363e3737a809..9bacebe7d265 100644
--- a/tensorflow/core/kernels/conv_ops.cc
+++ b/tensorflow/core/kernels/conv_ops.cc
@@ -258,18 +258,28 @@ struct LaunchConv2DOp<CPUDevice, T> {
 
     const int64 in_depth = input.dim_size(3);
     const int64 out_depth = output->dim_size(3);
     const int64 patch_depth = filter.dim_size(2);
 
+    if (patch_depth <= 0) {
+      ctx->SetStatus(errors::InvalidArgument(
+          "filter depth must be stricly positive, got ", patch_depth));
+      return;
+    }
     if (in_depth % patch_depth != 0) {
       ctx->SetStatus(errors::InvalidArgument(
           "input depth must be evenly divisible by filter depth: ", in_depth,
           " vs ", patch_depth));
       return;
     }
 
     const int64 num_groups = in_depth / patch_depth;
+    if (num_groups <= 0) {
+      ctx->SetStatus(errors::InvalidArgument(
+          "number of groups must be stricly positive, got ", num_groups));
+      return;
+    }
     if (out_depth % num_groups != 0 || out_depth < num_groups) {
       ctx->SetStatus(errors::InvalidArgument(
           "output depth must be evenly divisible by number of groups: ",
           out_depth, " vs ", num_groups));
       return;
@@ -534,10 +544,13 @@ Status ComputeConv2DDimension(const Conv2DParameters& params,
               errors::InvalidArgument("Input depth too large"));
   TF_REQUIRES(FastBoundsCheck(patch_depth_raw, std::numeric_limits<int>::max()),
               errors::InvalidArgument("Patch depth too large"));
   const int in_depth = static_cast<int>(in_depth_raw);
   const int patch_depth = static_cast<int>(patch_depth_raw);
+  TF_REQUIRES(patch_depth > 0,
+              errors::InvalidArgument(
+                  "filter depth must be stricly positive, got ", patch_depth));
   TF_REQUIRES(in_depth % patch_depth == 0,
               errors::InvalidArgument(
                   "input depth must be evenly divisible by filter depth: ",
                   in_depth, " vs ", patch_depth));
 

Fixed code:     if (patch_depth <= 0) {
      ctx->SetStatus(errors::InvalidArgument(
          "filter depth must be stricly positive, got ", patch_depth));
      return;
    }
    if (num_groups <= 0) {
      ctx->SetStatus(errors::InvalidArgument(
          "number of groups must be stricly positive, got ", num_groups));
      return;
    }
  TF_REQUIRES(patch_depth > 0,
              errors::InvalidArgument(
                  "filter depth must be stricly positive, got ", patch_depth));