CVE-2022-29205: NULL Pointer Dereference (CWE-476)
value: TensorFlow is an open source platform for machine learning. Prior to versions 2.9.0, 2.8.1, 2.7.2, and 2.6.4, there is a potential for segfault / denial of service in TensorFlow by calling `tf.compat.v1.*` ops which don't yet have support for quantized types, which was added after migration to TensorFlow 2.x. In these scenarios, since the kernel is missing, a `nullptr` value is passed to `ParseDimensionValue` for the `py_value` argument. Then, this is dereferenced, resulting in segfault. Versions 2.9.0, 2.8.1, 2.7.2, and 2.6.4 contain a patch for this issue.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2022-05-20T23:15Z
Repository: https://github.com/tensorflow/tensorflow
Language: C++
Files changed: tensorflow/core/kernels/strided_slice_op.cc, tensorflow/core/kernels/strided_slice_op_impl.h, tensorflow/python/eager/pywrap_tfe_src.cc
Commit date: 2022-04-27 20:55:48 -0700
Commit message: Fix tf.compat.v1.placeholder_with_default vulnerability with quantized types.

When iterating through the tensor to extract shape values, an underlying missing kernel
(`StridedSlice` for quantized types) causes an error, which then results in a `nullptr`
being passed to `ParseDimensionValue()`, causing a segfault.

The `nullptr` check allows the missing kernel error to propagate.
Adding the missing kernel registrations allows the shape values
to be extracted successfully.

PiperOrigin-RevId: 445045957

Diff: diff --git a/tensorflow/core/kernels/strided_slice_op.cc b/tensorflow/core/kernels/strided_slice_op.cc
index 30f083dae1a41..3ec2d6bbcc3c1 100644
--- a/tensorflow/core/kernels/strided_slice_op.cc
+++ b/tensorflow/core/kernels/strided_slice_op.cc
@@ -429,10 +429,11 @@ class StridedSliceAssignOp : public OpKernel {
                               .HostMemory("end")                        \
                               .HostMemory("strides"),                   \
                           StridedSliceAssignOp<CPUDevice, type, true>)
 
 TF_CALL_ALL_TYPES(REGISTER_STRIDED_SLICE);
+TF_CALL_QUANTIZED_TYPES(REGISTER_STRIDED_SLICE);
 
 #undef REGISTER_STRIDED_SLICE
 
 #if GOOGLE_CUDA || TENSORFLOW_USE_ROCM
 
diff --git a/tensorflow/core/kernels/strided_slice_op_impl.h b/tensorflow/core/kernels/strided_slice_op_impl.h
index d4dd85eebdeb2..7ec7d868f2263 100644
--- a/tensorflow/core/kernels/strided_slice_op_impl.h
+++ b/tensorflow/core/kernels/strided_slice_op_impl.h
@@ -290,11 +290,11 @@ TF_CALL_int64(DECLARE_FOR_N_GPU);
 TF_CALL_uint32(DECLARE_FOR_N_GPU);
 TF_CALL_GPU_ALL_TYPES(DECLARE_FOR_N_GPU);
 #endif  // END GOOGLE_CUDA || TENSORFLOW_USE_ROCM
 
 TF_CALL_ALL_TYPES(DECLARE_FOR_N_CPU);
-
+TF_CALL_QUANTIZED_TYPES(DECLARE_FOR_N_CPU);
 
 #undef INSTANTIATE
 #undef DECLARE_FOR_N_CPU
 #undef DECLARE_FOR_N_GPU
 
diff --git a/tensorflow/python/eager/pywrap_tfe_src.cc b/tensorflow/python/eager/pywrap_tfe_src.cc
index e1ed3bd94f5aa..53e75e976c5c8 100644
--- a/tensorflow/python/eager/pywrap_tfe_src.cc
+++ b/tensorflow/python/eager/pywrap_tfe_src.cc
@@ -686,13 +686,16 @@ bool SetOpAttrScalar(TFE_Context* ctx, TFE_Op* op, const char* key,
       }
       std::unique_ptr<int64_t[]> dims(new int64_t[num_dims]);
       for (int i = 0; i < num_dims; ++i) {
         tensorflow::Safe_PyObjectPtr inner_py_value(
             PySequence_ITEM(py_value, i));
+        // If an error is generated when iterating through object, we can
+        // sometimes get a nullptr.
         if (inner_py_value.get() == Py_None) {
           dims[i] = -1;
-        } else if (!ParseDimensionValue(key, inner_py_value.get(), status,
+        } else if (inner_py_value.get() == nullptr ||
+                   !ParseDimensionValue(key, inner_py_value.get(), status,
                                         &dims[i])) {
           return false;
         }
       }
       TFE_OpSetAttrShape(op, key, dims.get(), num_dims, status);

Vulnerable code: 
        } else if (!ParseDimensionValue(key, inner_py_value.get(), status,
Fixed code: TF_CALL_QUANTIZED_TYPES(REGISTER_STRIDED_SLICE);
TF_CALL_QUANTIZED_TYPES(DECLARE_FOR_N_CPU);
        // If an error is generated when iterating through object, we can
        // sometimes get a nullptr.
        } else if (inner_py_value.get() == nullptr ||
                   !ParseDimensionValue(key, inner_py_value.get(), status,