VYPR
Low severityNVD Advisory· Published May 14, 2021· Updated Aug 3, 2024

Null pointer dereference in `EditDistance`

CVE-2021-29564

Description

TensorFlow is an end-to-end open source platform for machine learning. An attacker can trigger a null pointer dereference in the implementation of tf.raw_ops.EditDistance. This is because the implementation(https://github.com/tensorflow/tensorflow/blob/79865b542f9ffdc9caeb255631f7c56f1d4b6517/tensorflow/core/kernels/edit_distance_op.cc#L103-L159) has incomplete validation of the input parameters. The fix will be included in TensorFlow 2.5.0. We will also cherrypick this commit on TensorFlow 2.4.2, TensorFlow 2.3.3, TensorFlow 2.2.3 and TensorFlow 2.1.4, as these are also affected and still in supported range.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
tensorflowPyPI
< 2.1.42.1.4
tensorflowPyPI
>= 2.2.0, < 2.2.32.2.3
tensorflowPyPI
>= 2.3.0, < 2.3.32.3.3
tensorflowPyPI
>= 2.4.0, < 2.4.22.4.2
tensorflow-cpuPyPI
< 2.1.42.1.4
tensorflow-cpuPyPI
>= 2.2.0, < 2.2.32.2.3
tensorflow-cpuPyPI
>= 2.3.0, < 2.3.32.3.3
tensorflow-cpuPyPI
>= 2.4.0, < 2.4.22.4.2
tensorflow-gpuPyPI
< 2.1.42.1.4
tensorflow-gpuPyPI
>= 2.2.0, < 2.2.32.2.3
tensorflow-gpuPyPI
>= 2.3.0, < 2.3.32.3.3
tensorflow-gpuPyPI
>= 2.4.0, < 2.4.22.4.2

Affected products

1

Patches

1
f4c364a5d688

Fix multiple issues in EditDistance

https://github.com/tensorflow/tensorflowMihai MaruseacMay 5, 2021via ghsa
1 file changed · +47 0
  • tensorflow/core/kernels/edit_distance_op.cc+47 0 modified
    @@ -64,6 +64,12 @@ Status ValidateShapes(OpKernelContext* ctx, const Tensor& hypothesis_indices,
         return errors::InvalidArgument(
             "truth_shape should be a vector, but got shape: ",
             truth_shape.shape().DebugString());
    +  if (hypothesis_values.NumElements() != hypothesis_indices.dim_size(0))
    +    return errors::InvalidArgument(
    +        "Expected hypothesis_values.NumElements == "
    +        "#rows(hypothesis_indices), their shapes are: ",
    +        hypothesis_values.shape().DebugString(), " and ",
    +        hypothesis_indices.shape().DebugString());
       if (hypothesis_shape.NumElements() != hypothesis_indices.dim_size(1))
         return errors::InvalidArgument(
             "Expected hypothesis_shape.NumElements == "
    @@ -75,6 +81,12 @@ Status ValidateShapes(OpKernelContext* ctx, const Tensor& hypothesis_indices,
             "Input SparseTensors must have rank at least 2, but truth_shape "
             "rank is: ",
             truth_shape.NumElements());
    +  if (truth_values.NumElements() != truth_indices.dim_size(0))
    +    return errors::InvalidArgument(
    +        "Expected truth_values.NumElements == "
    +        "#rows(truth_indices), their shapes are: ",
    +        truth_values.shape().DebugString(), " and ",
    +        truth_indices.shape().DebugString());
       if (truth_shape.NumElements() != truth_indices.dim_size(1))
         return errors::InvalidArgument(
             "Expected truth_shape.NumElements == "
    @@ -153,6 +165,11 @@ class EditDistanceOp : public OpKernel {
           output_shape.AddDim(std::max(hypothesis_st_shape.dim_size(d),
                                        truth_st_shape.dim_size(d)));
         }
    +    const auto output_elements = output_shape.num_elements();
    +    OP_REQUIRES(
    +        ctx, output_elements > 0,
    +        errors::InvalidArgument("Got output shape ", output_shape.DebugString(),
    +                                " which has 0 elements"));
     
         Tensor* output = nullptr;
         OP_REQUIRES_OK(ctx, ctx->allocate_output("output", output_shape, &output));
    @@ -185,6 +202,12 @@ class EditDistanceOp : public OpKernel {
           if (g_truth == g_hypothesis) {
             auto loc = std::inner_product(g_truth.begin(), g_truth.end(),
                                           output_strides.begin(), int64{0});
    +        OP_REQUIRES(
    +            ctx, loc < output_elements,
    +            errors::Internal("Got an inner product ", loc,
    +                             " which would require in writing to outside of "
    +                             "the buffer for the output tensor (max elements ",
    +                             output_elements, ")"));
             output_t(loc) =
                 gtl::LevenshteinDistance<T>(truth_seq, hypothesis_seq, cmp);
             if (normalize_) output_t(loc) /= truth_seq.size();
    @@ -194,6 +217,12 @@ class EditDistanceOp : public OpKernel {
           } else if (g_truth > g_hypothesis) {  // zero-length truth
             auto loc = std::inner_product(g_hypothesis.begin(), g_hypothesis.end(),
                                           output_strides.begin(), int64{0});
    +        OP_REQUIRES(
    +            ctx, loc < output_elements,
    +            errors::Internal("Got an inner product ", loc,
    +                             " which would require in writing to outside of "
    +                             "the buffer for the output tensor (max elements ",
    +                             output_elements, ")"));
             output_t(loc) = hypothesis_seq.size();
             if (normalize_ && output_t(loc) != 0.0f) {
               output_t(loc) = std::numeric_limits<float>::infinity();
    @@ -202,6 +231,12 @@ class EditDistanceOp : public OpKernel {
           } else {  // zero-length hypothesis
             auto loc = std::inner_product(g_truth.begin(), g_truth.end(),
                                           output_strides.begin(), int64{0});
    +        OP_REQUIRES(
    +            ctx, loc < output_elements,
    +            errors::Internal("Got an inner product ", loc,
    +                             " which would require in writing to outside of "
    +                             "the buffer for the output tensor (max elements ",
    +                             output_elements, ")"));
             output_t(loc) = (normalize_) ? 1.0 : truth_seq.size();
             ++truth_iter;
           }
    @@ -212,6 +247,12 @@ class EditDistanceOp : public OpKernel {
           auto hypothesis_seq = hypothesis_j.values<T>();
           auto loc = std::inner_product(g_hypothesis.begin(), g_hypothesis.end(),
                                         output_strides.begin(), int64{0});
    +      OP_REQUIRES(
    +          ctx, loc < output_elements,
    +          errors::Internal("Got an inner product ", loc,
    +                           " which would require in writing to outside of the "
    +                           "buffer for the output tensor (max elements ",
    +                           output_elements, ")"));
           output_t(loc) = hypothesis_seq.size();
           if (normalize_ && output_t(loc) != 0.0f) {
             output_t(loc) = std::numeric_limits<float>::infinity();
    @@ -224,6 +265,12 @@ class EditDistanceOp : public OpKernel {
           auto truth_seq = truth_i.values<T>();
           auto loc = std::inner_product(g_truth.begin(), g_truth.end(),
                                         output_strides.begin(), int64{0});
    +      OP_REQUIRES(
    +          ctx, loc < output_elements,
    +          errors::Internal("Got an inner product ", loc,
    +                           " which would require in writing to outside of the "
    +                           "buffer for the output tensor (max elements ",
    +                           output_elements, ")"));
           output_t(loc) = (normalize_) ? 1.0 : truth_seq.size();
           ++truth_iter;
         }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.