CVE-2022-23593 (published 2022-02-04T23:15Z)

Tensorflow is an Open Source Machine Learning Framework. The `simplifyBroadcast` function in the MLIR-TFRT infrastructure in TensorFlow is vulnerable to a segfault (hence, denial of service), if called with scalar shapes. If all shapes are scalar, then `maxRank` is 0, so we build an empty `SmallVector`. The fix will be included in TensorFlow 2.8.0. This is the only affected version.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-754
cwe_name: Improper Check for Unusual or Exceptional Conditions
description: The product does not check or incorrectly checks for unusual or exceptional conditions that are not expected to occur frequently during day to day operation of the product.
extended_description: 
            The programmer may assume that certain events or conditions will never occur or do not need to be worried about, such as low memory conditions, lack of access to resources due to restrictive permissions, or misbehaving clients or components. However, attackers may intentionally trigger these unusual conditions, thus violating the programmer's assumptions, possibly introducing instability, incorrect behavior, or a vulnerability.
            Note that this entry is not exclusively about the use of exceptions and exception handling, which are mechanisms for both checking and handling unusual or unexpected conditions.
         
         

Fix information:
repo_url: https://github.com/tensorflow/tensorflow
commit_details: repo_url: https://github.com/tensorflow/tensorflow
author: Adrian Kuegel
author_date: 2021-12-21 01:01:24-08:00
msg: Avoid Segfault for scalar shapes.

Calling tensor::FromElementsOp with an empty vector of elements and no type
causes a segfault. We need to let the FromElementsOp know which scalar type it
should have.
Also add back the DynamicBroadcastInDimOp canonicalization patterns, which
previously prevented this bug from happening.
Add a regression test that demonstrates the bug.

PiperOrigin-RevId: 417561444
Change-Id: I6d1d6cfb71aabbad6102422625a00bbe253ac95a
repository: repo_url: https://github.com/tensorflow/tensorflow
repo_name: tensorflow/tensorflow
description: An Open Source Machine Learning Framework for Everyone
repo_language: C++
owner: tensorflow
file_changes: filename: tf_cpurt_symbolic_shape_optimization.cc
change_type: ModificationType.MODIFY
diff: @@ -157,6 +157,10 @@ llvm::Optional<Value> simplifyBroadcast(ShapeComponentAnalysis& analysis,
     shapes_found.push_back(*found_shape);
     maxRank = std::max(maxRank, found_shape->size());
   }
+  if (maxRank == 0) {
+    return Value(builder->create<tensor::FromElementsOp>(
+        loc, shapes[0].getType(), SmallVector<Value>()));
+  }
 
   SmallVector<const ShapeComponentAnalysis::SymbolicExpr*> joined_dimensions(
       maxRank);

programming_language: C++
filename: scalar_broadcast.mlir
change_type: ModificationType.ADD
diff: @@ -0,0 +1,11 @@
+builtin.func @test(%V__0 : tensor<i1> { python_test_attrs.static_type = tensor<i1> }, %V__1 : tensor<f32> { python_test_attrs.static_type = tensor<f32> }, %V__2 : tensor<f32> { python_test_attrs.static_type = tensor<f32> }) -> tensor<f32> {
+  %0 = "tf.Cast"(%V__0) : (tensor<i1>) -> tensor<i1>
+  %1 = "tf.Selu"(%V__2) : (tensor<f32>) -> tensor<f32>
+  %2 = "tf.NextAfter"(%1, %V__2) : (tensor<f32>, tensor<f32>) -> tensor<f32>
+  %3 = "tf.Elu"(%2) : (tensor<f32>) -> tensor<f32>
+  %4 = "tf.Cosh"(%3) : (tensor<f32>) -> tensor<f32>
+  %5 = "tf.Elu"(%4) : (tensor<f32>) -> tensor<f32>
+  %6 = "tf.Div"(%V__1, %5) : (tensor<f32>, tensor<f32>) -> tensor<f32>
+  %7 = "tf.Select"(%0, %6, %V__1) : (tensor<i1>, tensor<f32>, tensor<f32>) -> tensor<f32>
+  return %7 : tensor<f32>
+}
\ No newline at end of file

programming_language: CoffeeScript