Vulnerability: Undefined behavior in `MaxPool3DGradGrad` ### Impact
The implementation of `tf.raw_ops.MaxPool3DGradGrad` exhibits undefined behavior by dereferencing null pointers backing attacker-supplied empty tensors:

```python
import tensorflow as tf

orig_input = tf.constant([0.0], shape=[1, 1, 1, 1, 1], dtype=tf.float32)
orig_output = tf.constant([0.0], shape=[1, 1, 1, 1, 1], dtype=tf.float32)
grad = tf.constant([], shape=[0, 0, 0, 0, 0], dtype=tf.float32)
ksize = [1, 1, 1, 1, 1]
strides = [1, 1, 1, 1, 1]
padding = "SAME"

tf.raw_ops.MaxPool3DGradGrad(
    orig_input=orig_input, orig_output=orig_output, grad=grad, ksize=ksize,
    strides=strides, padding=padding)
```

The [implementation](https://github.com/tensorflow/tensorflow/blob/72fe792967e7fd25234342068806707bbc116618/tensorflow/core/kernels/pooling_ops_3d.cc#L679-L703) fails to validate that the 3 tensor inputs are not empty. If any of them is empty, then accessing the elements in the tensor results in dereferencing a null pointer.

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

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 Ying Wang and Yakun Zhang of Baidu X-Team.
Vulnerability ID: GHSA-828x-qc2p-wprq
CWE: CWE-476
Severity score: 2.5
Project: https://github.com/tensorflow/tensorflow
Published: 2021-05-21
File: tensorflow/core/kernels/pooling_ops_3d.cc
Commit message: Add missing validation to pooling_ops_3d

PiperOrigin-RevId: 372218727
Change-Id: I6b9ed4266aa7286c02f1f230d7bea922c1be547e
Commit author: Mihai Maruseac

Vulnerable version (before fix):
 class MaxPooling3dGradGradOp : public OpKernel {     OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(                                 {2}, 0, tensor_out.shape(), &output));      LaunchMaxPooling3dGradGradOp<Device, T>::launch(         context, params, tensor_in, tensor_out, out_grad_backprop, output);   }

Fixed version (after fix):
 class MaxPooling3dGradGradOp : public OpKernel {     OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(                                 {2}, 0, tensor_out.shape(), &output));      // Given access patterns in LaunchMaxPooling3dGradGradOp, these tensors must     // have elements.     OP_REQUIRES(context, tensor_in.NumElements() > 0,                 errors::InvalidArgument("received empty tensor tensor_in: ",                                         tensor_in.DebugString()));     OP_REQUIRES(context, tensor_out.NumElements() > 0,                 errors::InvalidArgument("received empty tensor tensor_out: ",                                         tensor_out.DebugString()));     OP_REQUIRES(         context, out_grad_backprop.NumElements() > 0,         errors::InvalidArgument("received empty tensor out_grad_backprop: ",                                 out_grad_backprop.DebugString()));      LaunchMaxPooling3dGradGradOp<Device, T>::launch(         context, params, tensor_in, tensor_out, out_grad_backprop, output);   }

Patch:
patch: @@ -698,6 +698,19 @@ class MaxPooling3dGradGradOp : public OpKernel {
     OP_REQUIRES_OK(context, context->forward_input_or_allocate_output(
                                 {2}, 0, tensor_out.shape(), &output));
 
+    // Given access patterns in LaunchMaxPooling3dGradGradOp, these tensors must
+    // have elements.
+    OP_REQUIRES(context, tensor_in.NumElements() > 0,
+                errors::InvalidArgument("received empty tensor tensor_in: ",
+                                        tensor_in.DebugString()));
+    OP_REQUIRES(context, tensor_out.NumElements() > 0,
+                errors::InvalidArgument("received empty tensor tensor_out: ",
+                                        tensor_out.DebugString()));
+    OP_REQUIRES(
+        context, out_grad_backprop.NumElements() > 0,
+        errors::InvalidArgument("received empty tensor out_grad_backprop: ",
+                                out_grad_backprop.DebugString()));
+
     LaunchMaxPooling3dGradGradOp<Device, T>::launch(
         context, params, tensor_in, tensor_out, out_grad_backprop, output);
   }
path: tensorflow/core/kernels/pooling_ops_3d.cc