Vulnerability: Division by zero in TFLite's implementation of `DepthwiseConv` ### Impact
The implementation of the `DepthwiseConv` TFLite operator is [vulnerable to a division by zero error](https://github.com/tensorflow/tensorflow/blob/1a8e885b864c818198a5b2c0cbbeca5a1e833bc8/tensorflow/lite/kernels/depthwise_conv.cc#L287-L288):

```cc
int num_input_channels = SizeOfDimension(input, 3);
TF_LITE_ENSURE_EQ(context, num_filter_channels % num_input_channels, 0);
```

An attacker can craft a model such that `input`'s fourth dimension would be 0.

### Patches
We have patched the issue in GitHub commit [cbda3c6b2dbbd3fbdc482ff8c0170a78ec2e97d0](https://github.com/tensorflow/tensorflow/commit/cbda3c6b2dbbd3fbdc482ff8c0170a78ec2e97d0).

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.

### For more information 
Please consult [our security guide](https://github.com/tensorflow/tensorflow/blob/master/SECURITY.md) for more information regarding the security model and how to contact us with issues and questions.

### Attribution
This vulnerability has been reported by members of the Aivul Team from Qihoo 360.
Vulnerability ID: GHSA-rf3h-xgv5-2q39
CWE: CWE-369
Severity score: 2.5
Project: https://github.com/tensorflow/tensorflow
Published: 2021-05-21
File: tensorflow/lite/kernels/depthwise_conv.cc
Commit message: Prevent divisions by 0

PiperOrigin-RevId: 371003153
Change-Id: Idef56c95b9fcaeb97f87e18c7a674dbeb5173204
Commit author: Mihai Maruseac

Vulnerable version (before fix):
 TfLiteStatus ComputeDepthMultiplier(TfLiteContext* context,                                     int16* depth_multiplier) {   int num_filter_channels = SizeOfDimension(filter, 3);   int num_input_channels = SizeOfDimension(input, 3);   TF_LITE_ENSURE_EQ(context, num_filter_channels % num_input_channels, 0);    *depth_multiplier = num_filter_channels / num_input_channels;   return kTfLiteOk; } TfLiteStatus EvalHybridPerChannel(TfLiteContext* context, TfLiteNode* node,   float output_activation_min, output_activation_max;   CalculateActivationRange(params->activation, &output_activation_min,                            &output_activation_max);   const int input_size = NumElements(input) / SizeOfDimension(input, 0);   const int batch_size = SizeOfDimension(input, 0);   TfLiteTensor* input_quantized;   TF_LITE_ENSURE_OK(context,                     GetTemporarySafe(context, node, data->input_quantized_index,

Fixed version (after fix):
 TfLiteStatus ComputeDepthMultiplier(TfLiteContext* context,                                     int16* depth_multiplier) {   int num_filter_channels = SizeOfDimension(filter, 3);   int num_input_channels = SizeOfDimension(input, 3);   TF_LITE_ENSURE(context, num_input_channels != 0);   TF_LITE_ENSURE_EQ(context, num_filter_channels % num_input_channels, 0);   *depth_multiplier = num_filter_channels / num_input_channels;   return kTfLiteOk; } TfLiteStatus EvalHybridPerChannel(TfLiteContext* context, TfLiteNode* node,   float output_activation_min, output_activation_max;   CalculateActivationRange(params->activation, &output_activation_min,                            &output_activation_max);   const int batch_size = SizeOfDimension(input, 0);   TF_LITE_ENSURE(context, batch_size != 0);   const int input_size = NumElements(input) / batch_size;   TfLiteTensor* input_quantized;   TF_LITE_ENSURE_OK(context,                     GetTemporarySafe(context, node, data->input_quantized_index,

Patch:
patch: @@ -285,8 +285,8 @@ TfLiteStatus ComputeDepthMultiplier(TfLiteContext* context,
                                     int16* depth_multiplier) {
   int num_filter_channels = SizeOfDimension(filter, 3);
   int num_input_channels = SizeOfDimension(input, 3);
+  TF_LITE_ENSURE(context, num_input_channels != 0);
   TF_LITE_ENSURE_EQ(context, num_filter_channels % num_input_channels, 0);
-
   *depth_multiplier = num_filter_channels / num_input_channels;
   return kTfLiteOk;
 }
@@ -455,8 +455,9 @@ TfLiteStatus EvalHybridPerChannel(TfLiteContext* context, TfLiteNode* node,
   float output_activation_min, output_activation_max;
   CalculateActivationRange(params->activation, &output_activation_min,
                            &output_activation_max);
-  const int input_size = NumElements(input) / SizeOfDimension(input, 0);
   const int batch_size = SizeOfDimension(input, 0);
+  TF_LITE_ENSURE(context, batch_size != 0);
+  const int input_size = NumElements(input) / batch_size;
   TfLiteTensor* input_quantized;
   TF_LITE_ENSURE_OK(context,
                     GetTemporarySafe(context, node, data->input_quantized_index,
path: tensorflow/lite/kernels/depthwise_conv.cc