CVE-2022-41898 (Python, published 2022-11-18T22:15Z)
Description: value: TensorFlow is an open source platform for machine learning. If `SparseFillEmptyRowsGrad` is given empty inputs, TensorFlow will crash. We have patched the issue in GitHub commit af4a6a3c8b95022c351edae94560acc61253a1b8. The fix will be included in TensorFlow 2.11. We will also cherrypick this commit on TensorFlow 2.10.1, 2.9.3, and TensorFlow 2.8.4, as these are also affected and still in supported range.
Severity: nan (CVSS v3 base score: 7.5)
Weakness: NVD-CWE-Other \u2014 Other
NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Repository: https://github.com/tensorflow/tensorflow
Files changed:
tensorflow/core/kernels/sparse_fill_empty_rows_op_gpu.cu.cc
tensorflow/python/kernel_tests/sparse_ops/sparse_ops_test.py
Commit message: Fix empty input crash for SparseFillEmptyRowsGrad.

PiperOrigin-RevId: 478085721


Vulnerable code:
    TF_RETURN_IF_ERROR(wrap_kernel_call(ComputeEmptyRowIndicatorKernel<Tindex>,
                                        /*device=*/device, /*size=*/dense_rows,
                                        elements_per_row, empty_row_indicator));
      OP_REQUIRES_OK_ASYNC(
          context,
          wrap_kernel_call(ScatterNewElementsKernel<T, Tindex>,
                           /*device=*/device, /*size=*/dense_rows, rank,
                           default_value, num_empty_rows_through,
                           input_row_ends, empty_row_indicator, output_indices,
                           output_values),
          done);
    TF_RETURN_IF_ERROR(wrap_kernel_call(CopyRowIndicesKernel<Tindex>,
                                        /*device=*/device, /*size=*/N, rank,
                                        indices, row_indices));
    TF_RETURN_IF_ERROR(wrap_kernel_call(
        GatherOriginalGradValuesKernel<T, Tindex>, /*device=*/device,
        /*size=*/N, reverse_index_map, grad_values, d_values, visited));

Fixed code:
    if (dense_rows > 0) {
      TF_RETURN_IF_ERROR(
          wrap_kernel_call(ComputeEmptyRowIndicatorKernel<Tindex>,
                           /*device=*/device, /*size=*/dense_rows,
                           elements_per_row, empty_row_indicator));
    }
      if (dense_rows > 0) {
        OP_REQUIRES_OK_ASYNC(
            context,
            wrap_kernel_call(ScatterNewElementsKernel<T, Tindex>,
                             /*device=*/device, /*size=*/dense_rows, rank,
                             default_value, num_empty_rows_through,
                             input_row_ends, empty_row_indicator,
                             output_indices, output_values),
            done);
      }
    if (N > 0) {
      TF_RETURN_IF_ERROR(wrap_kernel_call(CopyRowIndicesKernel<Tindex>,
                                          /*device=*/device, /*size=*/N, rank,
                                          indices, row_indices));
    }
    if (N > 0) {
      TF_RETURN_IF_ERROR(wrap_kernel_call(
          GatherOriginalGradValuesKernel<T, Tindex>, /*device=*/device,
          /*size=*/N, reverse_index_map, grad_values, d_values, visited));
    }
  def testSparseFillEmptyRowsGradEmpty(self):
    with test_util.use_gpu():
      grad, _ = self.evaluate(
          sparse_ops.sparse_fill_empty_rows_grad(
              reverse_index_map=[], grad_values=[]))
      self.assertAllEqual(grad, [])