CVE-2023-25669 (C++, published 2023-03-25T00:15Z)
Description: value: TensorFlow is an open source platform for machine learning. Prior to versions 2.12.0 and 2.11.1, if the stride and window size are not positive for `tf.raw_ops.AvgPoolGrad`, it can give a floating point exception. A fix is included in TensorFlow version 2.12.0 and version 2.11.1.

Severity: nan (CVSS v3 base score: 7.5)
Weakness: CWE-697 \u2014 Incorrect Comparison
The product compares two entities in a security-relevant context, but the comparison is incorrect, which may lead to resultant weaknesses.
Repository: https://github.com/tensorflow/tensorflow
Files changed:
tensorflow/compiler/tests/pooling_ops_test.py
tensorflow/compiler/tf2xla/kernels/pooling_ops.cc
tensorflow/compiler/xla/client/padding.cc
Commit message: [tf2xla] Validate that stride and window size are positive

PiperOrigin-RevId: 504866231


Vulnerable code:
    if (ctx->num_inputs() == 1) {
      return ksize_;
    }
    const TensorShape ksize_shape = ctx->InputShape(1);
    // Validate input sizes.
    if (!TensorShapeUtils::IsVector(ksize_shape)) {
      return errors::InvalidArgument("ksize must be a vector, not shape ",
                                     ksize_shape.DebugString());
    }
    if (ksize_shape.num_elements() != num_dims()) {
      return errors::InvalidArgument(
          "Sliding window ksize field must "
          "specify ",
          num_dims(), " dimensions");
    }
    auto status = ctx->ConstantInputAsIntVector(1, &ksize);
    if (!status.ok()) {
      return status;
    if (ctx->num_inputs() == 1) {
      return stride_;
    }
    const TensorShape stride_shape = ctx->InputShape(2);
    // Validate input sizes.
    if (!TensorShapeUtils::IsVector(stride_shape)) {
      return errors::InvalidArgument("stride must be a vector, not shape ",
                                     stride_shape.DebugString());
    }
    if (stride_shape.num_elements() != num_dims()) {
      return errors::InvalidArgument(
          "Sliding window stride field must "
          "specify ",
          num_dims(), " dimensions");
    }
    auto status = ctx->ConstantInputAsIntVector(2, &stride);
    if (!status.ok()) {
      return status;

Fixed code:
from tensorflow.python.framework import errors
from tensorflow.python.framework import test_util
  @test_util.disable_mlir_bridge(
      "TODO(b/266613412): investigate FPE in AvgPoolGrad for TPU"
  )
  def testAvgPoolGradSamePaddingZeroStrideZeroSize(self):
    output_gradient_vals = np.array([0.39117979], dtype=np.float32)
    output_gradient_vals = output_gradient_vals.reshape([1, 1, 1, 1])
    with self.session() as sess:
      with self.test_scope():
        output_gradients = array_ops.placeholder(
            dtypes.float32, shape=output_gradient_vals.shape
        )
        t = gen_nn_ops.avg_pool_grad(
            orig_input_shape=[1, 0, 0, 0],
            grad=output_gradients,
            ksize=[1, 0, 0, 0],
            strides=[1, 0, 0, 0],
            padding="SAME",
            data_format="NCHW",
        )
      with self.assertRaisesRegex(
          errors.InvalidArgumentError,
          (
              "Sliding window ksize field for dimension 1 must be positive but"
              " is 0"
          ),
      ):
        sess.run(t, {output_gradients: output_gradient_vals})

#include "tensorflow/core/framework/op_requires.h"
#include "tensorflow/tsl/platform/errors.h"
template <typename T>
static Status ValidateKernelSizes(const T& ksizes) {
  for (size_t i = 0; i < ksizes.size(); ++i) {
    if (ksizes[i] <= 0) {
      return errors::InvalidArgument(
          "Sliding window ksize field for dimension ", i,
          " must be positive but is ", ksizes[i]);
    }
  }
  return OkStatus();
}

template <typename T>
static Status ValidateStrides(const T& strides) {
  for (size_t i = 0; i < strides.size(); ++i) {
    if (strides[i] <= 0) {
      return errors::InvalidArgument(
          "Sliding window stride field for dimension ", i,
          " must be positive but is ", strides[i]);
    }
  }
  return OkStatus();
}

    if (ctx->num_inputs() == 1) {
      ksize = ksize_;
    } else {
      const TensorShape ksize_shape = ctx->InputShape(1);
      // Validate input sizes.
      if (!TensorShapeUtils::IsVector(ksize_shape)) {
        return errors::InvalidArgument("ksize must be a vector, not shape ",
                                       ksize_shape.DebugString());
      }
      if (ksize_shape.num_elements() != num_dims()) {
        return errors::InvalidArgument(
            "Sliding window ksize field must "
            "specify ",
            num_dims(), " dimensions");
      }
      auto status = ctx->ConstantInputAsIntVector(1, &ksize);
      if (!status.ok()) {
        return status;
      }
    TF_RETURN_IF_ERROR(ValidateKernelSizes(ksize));
    if (ctx->num_inputs() == 1) {
      stride = stride_;
    } else {
      const TensorShape stride_shape = ctx->InputShape(2);
      // Validate input sizes.
      if (!TensorShapeUtils::IsVector(stride_shape)) {
        return errors::InvalidArgument("stride must be a vector, not shape ",
                                       stride_shape.DebugString());
      }
      if (stride_shape.num_elements() != num_dims()) {
        return errors::InvalidArgument(
            "Sliding window stride field must "
            "specify ",
            num_dims(), " dimensions");
      }
      auto status = ctx->ConstantInputAsIntVector(2, &stride);
      if (!status.ok()) {
        return status;
      }
    TF_RETURN_IF_ERROR(ValidateStrides(stride));
    OP_REQUIRES_OK(ctx, ValidateKernelSizes(ksize_));
    OP_REQUIRES_OK(ctx, ValidateStrides(stride_));
    OP_REQUIRES_OK(ctx, ValidateKernelSizes(ksize_));
    OP_REQUIRES_OK(ctx, ValidateStrides(stride_));
    OP_REQUIRES_OK(ctx, ValidateKernelSizes(ksize_));
    OP_REQUIRES_OK(ctx, ValidateStrides(stride_));
  for (size_t i = 0; i < input_dimensions.size(); ++i) {
    if (window_dimensions[i] <= 0) {
      return InvalidArgument("Window dimension %u has non-positive size %d", i,
                             window_dimensions[i]);
    }
    if (window_strides[i] <= 0) {
      return InvalidArgument("Window dimension %u has non-positive stride %d",
                             i, window_strides[i]);
    }
  }