CVE-2020-15192 (C++, published 2020-09-25T19:15Z)
Description: value: In Tensorflow before versions 2.2.1 and 2.3.1, if a user passes a list of strings to `dlpack.to_dlpack` there is a memory leak following an expected validation failure. The issue occurs because the `status` argument during validation failures is not properly checked. Since each of the above methods can return an error status, the `status` value must be checked before continuing. The issue is patched in commit 22e07fb204386768e5bcbea563641ea11f96ceb8 and is released in TensorFlow versions 2.2.1, or 2.3.1.
Severity: MEDIUM (CVSS v3 base score: 4.3)
Weakness: CWE-20 \u2014 Improper Input Validation
The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Repository: https://github.com/tensorflow/tensorflow
Files changed:
tensorflow/c/eager/dlpack.cc
tensorflow/python/dlpack/BUILD
tensorflow/python/dlpack/dlpack_test.py
tensorflow/python/tfe_wrapper.cc
Commit message: Fix multiple vulnerabilities in `tf.experimental.dlpack.to_dlpack`.

We have a use after free caused by memory coruption, a segmentation fault caused by memory corruption, several memory leaks and an undefined behavior when taking the reference of a nullptr.

PiperOrigin-RevId: 332568894
Change-Id: Ife0fc05e103b35325094ae5d822ee5fdea764572


Vulnerable code:
  TensorReference tensor_ref(*tensor);  // This will call buf_->Ref()
  dlm_tensor->dl_tensor.ctx = GetDlContext(h, status);
  dlm_tensor->dl_tensor.data = TFE_TensorHandleDevicePointer(h, status);
  dlm_tensor->dl_tensor.dtype = GetDlDataType(data_type, status);
  dlm_tensor->dl_tensor.shape = &(*shape_arr)[0];
  dlm_tensor->dl_tensor.strides = &(*stride_arr)[0];
    tags = ["noasan"],  # TODO(b/159774807)
    TFE_TensorHandle* thandle = EagerTensor_Handle(eager_tensor_pyobject_ptr);

Fixed code:
  auto tf_dlm_context = GetDlContext(h, status);
  if (!status->status.ok()) {
    return nullptr;
  }

  auto* tf_dlm_data = TFE_TensorHandleDevicePointer(h, status);
  if (!status->status.ok()) {
    return nullptr;
  }

  auto tf_dlm_type = GetDlDataType(data_type, status);
  if (!status->status.ok()) {
    return nullptr;
  }

  TensorReference tensor_ref(*tensor);  // This will call buf_->Ref()
  dlm_tensor->dl_tensor.ctx = tf_dlm_context;
  dlm_tensor->dl_tensor.data = tf_dlm_data;
  dlm_tensor->dl_tensor.dtype = tf_dlm_type;
  dlm_tensor->dl_tensor.shape = shape_arr->data();
  dlm_tensor->dl_tensor.strides = stride_arr->data();


from tensorflow.python.framework import errors
  def testMustPassTensorArgumentToDLPack(self):
    with self.assertRaisesRegex(
        errors.InvalidArgumentError,
        "The argument to `to_dlpack` must be a TF tensor, not Python object"):
      dlpack.to_dlpack([1])


    if (!EagerTensor_CheckExact(eager_tensor_pyobject_ptr)) {
      status->status = tensorflow::errors::InvalidArgument(
          "The argument to `to_dlpack` must be a TF tensor, not Python object");
      tensorflow::MaybeRaiseRegisteredFromTFStatus(status.get());
    }

    TFE_TensorHandle* thandle = EagerTensor_Handle(eager_tensor_pyobject_ptr);