CVE-2022-23581: Reachable Assertion (CWE-617)
value: Tensorflow is an Open Source Machine Learning Framework. The Grappler optimizer in TensorFlow can be used to cause a denial of service by altering a `SavedModel` such that `IsSimplifiableReshape` would trigger `CHECK` failures. 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.
CWE description: The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary.
CVSS v3 base score: 6.5
Published: 2022-02-04T23:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/grappler/optimizers/constant_folding.cc
Commit date: 2021-11-11 09:21:05 -0800
Commit message: Remove `CHECK`-fails from `IsSimplifiableReshape`

PiperOrigin-RevId: 409164987
Change-Id: I58c7dd459ff348c3dbae95e00c4c5e63b30a4e65

Diff: diff --git a/tensorflow/core/grappler/optimizers/constant_folding.cc b/tensorflow/core/grappler/optimizers/constant_folding.cc
index 9087ddb599412..a2050899f6072 100644
--- a/tensorflow/core/grappler/optimizers/constant_folding.cc
+++ b/tensorflow/core/grappler/optimizers/constant_folding.cc
@@ -1687,11 +1687,15 @@ Status ConstantFolding::FoldGraph(
 Status ConstantFolding::IsSimplifiableReshape(
     const NodeDef& node, const GraphProperties& properties) const {
   if (!IsReshape(node)) {
     return errors::Internal("Node ", node.name(), " is not a Reshape node");
   }
-  CHECK_LE(2, node.input_size());
+  if (2 > node.input_size()) {
+    return errors::Internal("Node ", node.name(),
+                            " must have at most 2 inputs but has ",
+                            node.input_size());
+  }
   const NodeDef* new_shape = node_map_->GetNode(node.input(1));
   if (!IsReallyConstant(*new_shape)) {
     return errors::Internal("Node ", node.name(), " has shape ",
                             new_shape->DebugString(),
                             " which is not a constant");
@@ -1705,11 +1709,15 @@ Status ConstantFolding::IsSimplifiableReshape(
 
   Status s = EvaluateNode(*new_shape, TensorVector(), &outputs);
   if (!s.ok()) {
     return errors::Internal("Could not evaluate node ", node.name());
   }
-  CHECK_EQ(1, outputs.size());
+  if (outputs.size() != 1) {
+    return errors::Internal("Node ", node.name(),
+                            " must have exactly 1 output but has ",
+                            outputs.size());
+  }
 
   const std::vector<OpInfo::TensorProperties>& props =
       properties.GetInputProperties(node.name());
   if (props.empty()) {
     return errors::Internal("Node ", node.name(), " has no properties");

Vulnerable code:   CHECK_LE(2, node.input_size());
  CHECK_EQ(1, outputs.size());
Fixed code:   if (2 > node.input_size()) {
    return errors::Internal("Node ", node.name(),
                            " must have at most 2 inputs but has ",
                            node.input_size());
  }
  if (outputs.size() != 1) {
    return errors::Internal("Node ", node.name(),
                            " must have exactly 1 output but has ",
                            outputs.size());
  }