CVE-2023-25666: Incorrect Comparison (CWE-697)
value: TensorFlow is an open source platform for machine learning. Prior to versions 2.12.0 and 2.11.1, there is a floating point exception in AudioSpectrogram. A fix is included in TensorFlow version 2.12.0 and version 2.11.1.
CWE description: The product compares two entities in a security-relevant context, but the comparison is incorrect, which may lead to resultant weaknesses.
CVSS v3 base score: 7.5
Published: 2023-03-25T00:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/kernels/BUILD, tensorflow/core/kernels/spectrogram_op_test.cc, tensorflow/core/ops/audio_ops.cc
Commit date: 2023-01-20 11:09:46 -0800
Commit message: Fix audio spectrogram FPE.

Do input validation in shape function.

PiperOrigin-RevId: 503481241

Diff: diff --git a/tensorflow/core/kernels/BUILD b/tensorflow/core/kernels/BUILD
index 3de7248525674..af071dfbcdf03 100644
--- a/tensorflow/core/kernels/BUILD
+++ b/tensorflow/core/kernels/BUILD
@@ -5920,10 +5920,11 @@ tf_cuda_cc_test(
         "//tensorflow/core:protos_all_cc",
         "//tensorflow/core:tensorflow",
         "//tensorflow/core:test",
         "//tensorflow/core:test_main",
         "//tensorflow/core:testlib",
+        "//tensorflow/core/platform:status_matchers",
     ],
 )
 
 cc_library(
     name = "mfcc_dct",
diff --git a/tensorflow/core/kernels/spectrogram_op_test.cc b/tensorflow/core/kernels/spectrogram_op_test.cc
index 380c51e6508b5..3ffb83a83f472 100644
--- a/tensorflow/core/kernels/spectrogram_op_test.cc
+++ b/tensorflow/core/kernels/spectrogram_op_test.cc
@@ -17,20 +17,25 @@ limitations under the License.
 
 #include <functional>
 #include <memory>
 #include <vector>
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
 #include "tensorflow/cc/client/client_session.h"
 #include "tensorflow/cc/ops/audio_ops.h"
 #include "tensorflow/cc/ops/const_op.h"
 #include "tensorflow/cc/ops/math_ops.h"
 #include "tensorflow/core/framework/tensor_testutil.h"
 #include "tensorflow/core/framework/types.h"
 #include "tensorflow/core/framework/types.pb.h"
 #include "tensorflow/core/kernels/ops_util.h"
 #include "tensorflow/core/lib/core/status_test_util.h"
 #include "tensorflow/core/platform/test.h"
+#include "tensorflow/tsl/lib/core/status_test_util.h"
+#include "tensorflow/tsl/platform/errors.h"
+#include "tensorflow/tsl/platform/status_matchers.h"
 
 namespace tensorflow {
 namespace ops {
 namespace {
 
@@ -138,8 +143,44 @@ TEST(SpectrogramOpTest, MultichannelTest) {
         spectrogram_tensor.SubSlice(channel),
         test::AsTensor<float>({0, 1, 2, 1, 0}, TensorShape({1, 5})), 1e-3);
   }
 }
 
+TEST(SpectrogramOpTest, InvalidWindowSize) {
+  Scope root = Scope::NewRootScope();
+  const int audio_size = 8;
+  const int channel_size = 2;
+  Tensor audio_tensor(DT_FLOAT, TensorShape({audio_size, channel_size}));
+  test::FillValues<float>(
+      &audio_tensor, {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
+                      -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f});
+  Output audio_const_op = Const(root.WithOpName("audio_const_op"),
+                                Input::Initializer(audio_tensor));
+  AudioSpectrogram spectrogram_op =
+      AudioSpectrogram(root.WithOpName("spectrogram_op"), audio_const_op,
+                       /*window_size=*/1, /*stride=*/1);
+  EXPECT_THAT(root.status(),
+              tsl::testing::StatusIs(tsl::error::Code::INVALID_ARGUMENT,
+                                     ::testing::ContainsRegex("window size")));
+}
+
+TEST(SpectrogramOpTest, InvalidStride) {
+  Scope root = Scope::NewRootScope();
+  const int audio_size = 8;
+  const int channel_size = 2;
+  Tensor audio_tensor(DT_FLOAT, TensorShape({audio_size, channel_size}));
+  test::FillValues<float>(
+      &audio_tensor, {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
+                      -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f});
+  Output audio_const_op = Const(root.WithOpName("audio_const_op"),
+                                Input::Initializer(audio_tensor));
+  AudioSpectrogram spectrogram_op =
+      AudioSpectrogram(root.WithOpName("spectrogram_op"), audio_const_op,
+                       /*window_size=*/2, /*stride=*/0);
+  EXPECT_THAT(root.status(),
+              tsl::testing::StatusIs(tsl::error::Code::INVALID_ARGUMENT,
+                                     ::testing::ContainsRegex("stride")));
+}
+
 }  // namespace
 }  // namespace ops
 }  // namespace tensorflow
diff --git a/tensorflow/core/ops/audio_ops.cc b/tensorflow/core/ops/audio_ops.cc
index 807cd6d9b48ae..240567c53072d 100644
--- a/tensorflow/core/ops/audio_ops.cc
+++ b/tensorflow/core/ops/audio_ops.cc
@@ -15,10 +15,11 @@ limitations under the License.
 
 #include "tensorflow/core/framework/common_shape_fns.h"
 #include "tensorflow/core/framework/op.h"
 #include "tensorflow/core/framework/shape_inference.h"
 #include "tensorflow/core/lib/core/bits.h"
+#include "tensorflow/core/platform/errors.h"
 
 namespace tensorflow {
 
 namespace {
 
@@ -70,12 +71,21 @@ Status EncodeWavShapeFn(InferenceContext* c) {
 Status SpectrogramShapeFn(InferenceContext* c) {
   ShapeHandle input;
   TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 2, &input));
   int32_t window_size;
   TF_RETURN_IF_ERROR(c->GetAttr("window_size", &window_size));
+  if (window_size <= 1) {
+    return errors::InvalidArgument("window size must be > 1, got ",
+                                   window_size);
+  }
+
   int32_t stride;
   TF_RETURN_IF_ERROR(c->GetAttr("stride", &stride));
+  if (stride <= 0) {
+    return errors::InvalidArgument("stride must be strictly positive, got ",
+                                   stride);
+  }
 
   DimensionHandle input_length = c->Dim(input, 0);
   DimensionHandle input_channels = c->Dim(input, 1);
 
   DimensionHandle output_length;

Fixed code:         "//tensorflow/core/platform:status_matchers",
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "tensorflow/tsl/lib/core/status_test_util.h"
#include "tensorflow/tsl/platform/errors.h"
#include "tensorflow/tsl/platform/status_matchers.h"
TEST(SpectrogramOpTest, InvalidWindowSize) {
  Scope root = Scope::NewRootScope();
  const int audio_size = 8;
  const int channel_size = 2;
  Tensor audio_tensor(DT_FLOAT, TensorShape({audio_size, channel_size}));
  test::FillValues<float>(
      &audio_tensor, {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
                      -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f});
  Output audio_const_op = Const(root.WithOpName("audio_const_op"),
                                Input::Initializer(audio_tensor));
  AudioSpectrogram spectrogram_op =
      AudioSpectrogram(root.WithOpName("spectrogram_op"), audio_const_op,
                       /*window_size=*/1, /*stride=*/1);
  EXPECT_THAT(root.status(),
              tsl::testing::StatusIs(tsl::error::Code::INVALID_ARGUMENT,
                                     ::testing::ContainsRegex("window size")));
}

TEST(SpectrogramOpTest, InvalidStride) {
  Scope root = Scope::NewRootScope();
  const int audio_size = 8;
  const int channel_size = 2;
  Tensor audio_tensor(DT_FLOAT, TensorShape({audio_size, channel_size}));
  test::FillValues<float>(
      &audio_tensor, {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
                      -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f});
  Output audio_const_op = Const(root.WithOpName("audio_const_op"),
                                Input::Initializer(audio_tensor));
  AudioSpectrogram spectrogram_op =
      AudioSpectrogram(root.WithOpName("spectrogram_op"), audio_const_op,
                       /*window_size=*/2, /*stride=*/0);
  EXPECT_THAT(root.status(),
              tsl::testing::StatusIs(tsl::error::Code::INVALID_ARGUMENT,
                                     ::testing::ContainsRegex("stride")));
}

#include "tensorflow/core/platform/errors.h"
  if (window_size <= 1) {
    return errors::InvalidArgument("window size must be > 1, got ",
                                   window_size);
  }

  if (stride <= 0) {
    return errors::InvalidArgument("stride must be strictly positive, got ",
                                   stride);
  }