CVE-2022-36014: NULL Pointer Dereference (CWE-476)
value: TensorFlow is an open source platform for machine learning. When `mlir::tfg::TFOp::nameAttr` receives null type list attributes, it crashes. We have patched the issue in GitHub commits 3a754740d5414e362512ee981eefba41561a63a6 and a0f0b9a21c9270930457095092f558fbad4c03e5. The fix will be included in TensorFlow 2.10.0. We will also cherrypick this commit on TensorFlow 2.9.1, TensorFlow 2.8.1, and TensorFlow 2.7.2, as these are also affected and still in supported range. There are no known workarounds for this issue.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 7.5
Published: 2022-09-16T23:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: Other
Files changed: tensorflow/core/ir/importexport/graphdef_import.cc, tensorflow/core/ir/importexport/tests/graphdef_to_mlir/invalid_backedge_input_size.pbtxt
Commit date: 2022-05-19 20:07:59 -0700
Commit message: [tfg] Fix null type attribute

Type attributes can be null and the input should be `dyn_cast_or_null`.

PiperOrigin-RevId: 449889247

Diff: diff --git a/tensorflow/core/ir/importexport/graphdef_import.cc b/tensorflow/core/ir/importexport/graphdef_import.cc
index e90ecf520f336..9d9480885aef3 100644
--- a/tensorflow/core/ir/importexport/graphdef_import.cc
+++ b/tensorflow/core/ir/importexport/graphdef_import.cc
@@ -697,11 +697,12 @@ Status GraphDefImporter::ConvertNodes(
 StatusOr<unsigned> GraphDefImporter::ArgNumType(const NamedAttrList &attrs,
                                                 const OpDef::ArgDef &arg_def,
                                                 SmallVectorImpl<Type> &types) {
   // Check whether a type list attribute is specified.
   if (!arg_def.type_list_attr().empty()) {
-    if (auto v = attrs.get(arg_def.type_list_attr()).dyn_cast<ArrayAttr>()) {
+    if (auto v =
+            attrs.get(arg_def.type_list_attr()).dyn_cast_or_null<ArrayAttr>()) {
       for (Attribute attr : v) {
         if (auto dtype = attr.dyn_cast<TypeAttr>()) {
           types.push_back(UnrankedTensorType::get(dtype.getValue()));
         } else {
           return InvalidArgument("Expected '", arg_def.type_list_attr(),
@@ -714,11 +715,12 @@ StatusOr<unsigned> GraphDefImporter::ArgNumType(const NamedAttrList &attrs,
   }
 
   unsigned num = 1;
   // Check whether a number attribute is specified.
   if (!arg_def.number_attr().empty()) {
-    if (auto v = attrs.get(arg_def.number_attr()).dyn_cast<IntegerAttr>()) {
+    if (auto v =
+            attrs.get(arg_def.number_attr()).dyn_cast_or_null<IntegerAttr>()) {
       num = v.getValue().getZExtValue();
     } else {
       return NotFound("Type attr not found: ", arg_def.number_attr());
     }
   }
@@ -729,11 +731,11 @@ StatusOr<unsigned> GraphDefImporter::ArgNumType(const NamedAttrList &attrs,
     TF_RETURN_IF_ERROR(ConvertDataType(arg_def.type(), b_, &dtype));
   } else if (arg_def.type_attr().empty()) {
     return InvalidArgument("Arg '", arg_def.name(),
                            "' has invalid type and no type attribute");
   } else {
-    if (auto v = attrs.get(arg_def.type_attr()).dyn_cast<TypeAttr>()) {
+    if (auto v = attrs.get(arg_def.type_attr()).dyn_cast_or_null<TypeAttr>()) {
       dtype = v.getValue();
     } else {
       return NotFound("Type attr not found: ", arg_def.type_attr());
     }
   }
diff --git a/tensorflow/core/ir/importexport/tests/graphdef_to_mlir/invalid_backedge_input_size.pbtxt b/tensorflow/core/ir/importexport/tests/graphdef_to_mlir/invalid_backedge_input_size.pbtxt
new file mode 100644
index 0000000000000..c3fd6ff2412be
--- /dev/null
+++ b/tensorflow/core/ir/importexport/tests/graphdef_to_mlir/invalid_backedge_input_size.pbtxt
@@ -0,0 +1,21 @@
+# RUN: not tfg-translate -graphdef-to-mlir %s 2>&1 | FileCheck %s
+
+# CHECK: Type attr not found
+
+library {
+  function {
+    signature {
+      name: "\344\264\264"
+      description: "value"
+      is_distributed_communication: true
+    }
+    node_def {
+      op: "Const"
+      input: "|"
+    }
+    control_ret {
+      key: ""
+      value: ""
+    }
+  }
+}
\ No newline at end of file

Vulnerable code:     if (auto v = attrs.get(arg_def.type_list_attr()).dyn_cast<ArrayAttr>()) {
    if (auto v = attrs.get(arg_def.number_attr()).dyn_cast<IntegerAttr>()) {
    if (auto v = attrs.get(arg_def.type_attr()).dyn_cast<TypeAttr>()) {
Fixed code:     if (auto v =
            attrs.get(arg_def.type_list_attr()).dyn_cast_or_null<ArrayAttr>()) {
    if (auto v =
            attrs.get(arg_def.number_attr()).dyn_cast_or_null<IntegerAttr>()) {
    if (auto v = attrs.get(arg_def.type_attr()).dyn_cast_or_null<TypeAttr>()) {
# RUN: not tfg-translate -graphdef-to-mlir %s 2>&1 | FileCheck %s

# CHECK: Type attr not found

library {
  function {
    signature {
      name: "\344\264\264"
      description: "value"
      is_distributed_communication: true
    }
    node_def {
      op: "Const"
      input: "|"
    }
    control_ret {
      key: ""
      value: ""
    }
  }
}