Vulnerability: Null pointer dereference in TensorFlow ### Impact 
The [implementation of `QuantizedMaxPool`](https://github.com/tensorflow/tensorflow/blob/5100e359aef5c8021f2e71c7b986420b85ce7b3d/tensorflow/core/kernels/quantized_pooling_ops.cc#L114-L130) has an undefined behavior where user controlled inputs can trigger a reference binding to null pointer.

```python
import tensorflow as tf

tf.raw_ops.QuantizedMaxPool(
    input = tf.constant([[[[4]]]], dtype=tf.quint8),
    min_input = [],
    max_input = [1],
    ksize = [1, 1, 1, 1],
    strides = [1, 1, 1, 1],
    padding = "SAME", name=None
)
```

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

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.

### 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 Faysal Hossain Shezan from University of Virginia.
Vulnerability ID: GHSA-3mw4-6rj6-74g5
CWE: CWE-476
Severity score: 6.5
Project: https://github.com/tensorflow/tensorflow
Published: 2022-02-09
File: tensorflow/core/kernels/quantized_pooling_ops.cc
Commit message: Fix nullptr exception in QuantizedMaxPool op when empty list is sent to min_input or max_input parameters.

PiperOrigin-RevId: 413960973
Change-Id: I9e3ded593f3c4eabf0d6d5dc356e6a19a3ad2682
Commit author: Isha Arkatkar

Vulnerable version (before fix):
 limitations under the License.  // See docs in ../ops/nn_ops.cc.  #define EIGEN_USE_THREADS  #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" class QuantizedMaxPoolingOp : public MaxPoolingOp<Device, T> {       : MaxPoolingOp<Device, T>(context) {}    void Compute(OpKernelContext* context) override {     const float min_input = context->input(1).flat<float>()(0);     const float max_input = context->input(2).flat<float>()(0);     MaxPoolingOp<Device, T>::Compute(context);

Fixed version (after fix):
 limitations under the License.  // See docs in ../ops/nn_ops.cc.  #include "tensorflow/core/framework/op_requires.h" #include "tensorflow/core/platform/errors.h" #define EIGEN_USE_THREADS  #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" class QuantizedMaxPoolingOp : public MaxPoolingOp<Device, T> {       : MaxPoolingOp<Device, T>(context) {}    void Compute(OpKernelContext* context) override {     auto min_input_tensor = context->input(1);     auto max_input_tensor = context->input(2);     OP_REQUIRES(         context, min_input_tensor.NumElements() == 1,         errors::InvalidArgument(             "min_input must be a scalar float value, got tensor with shape ",             min_input_tensor.shape()));     OP_REQUIRES(         context, max_input_tensor.NumElements() == 1,         errors::InvalidArgument(             "max_input must be a scalar float value, got tensor with shape ",             max_input_tensor.shape()));     const float min_input = context->input(1).flat<float>()(0);     const float max_input = context->input(2).flat<float>()(0);     MaxPoolingOp<Device, T>::Compute(context);

Patch:
patch: @@ -15,6 +15,8 @@ limitations under the License.
 
 // See docs in ../ops/nn_ops.cc.
 
+#include "tensorflow/core/framework/op_requires.h"
+#include "tensorflow/core/platform/errors.h"
 #define EIGEN_USE_THREADS
 
 #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
@@ -117,6 +119,18 @@ class QuantizedMaxPoolingOp : public MaxPoolingOp<Device, T> {
       : MaxPoolingOp<Device, T>(context) {}
 
   void Compute(OpKernelContext* context) override {
+    auto min_input_tensor = context->input(1);
+    auto max_input_tensor = context->input(2);
+    OP_REQUIRES(
+        context, min_input_tensor.NumElements() == 1,
+        errors::InvalidArgument(
+            "min_input must be a scalar float value, got tensor with shape ",
+            min_input_tensor.shape()));
+    OP_REQUIRES(
+        context, max_input_tensor.NumElements() == 1,
+        errors::InvalidArgument(
+            "max_input must be a scalar float value, got tensor with shape ",
+            max_input_tensor.shape()));
     const float min_input = context->input(1).flat<float>()(0);
     const float max_input = context->input(2).flat<float>()(0);
     MaxPoolingOp<Device, T>::Compute(context);
path: tensorflow/core/kernels/quantized_pooling_ops.cc