You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Huaisi Xu (JIRA)" <ji...@apache.org> on 2016/05/09 20:48:12 UTC

[jira] [Created] (THRIFT-3821) TMemoryBuffer buffer may overflow when resizing

Huaisi Xu created THRIFT-3821:
---------------------------------

             Summary: TMemoryBuffer buffer may overflow when resizing
                 Key: THRIFT-3821
                 URL: https://issues.apache.org/jira/browse/THRIFT-3821
             Project: Thrift
          Issue Type: Bug
    Affects Versions: 0.9.3
            Reporter: Huaisi Xu
            Priority: Critical


  uint32_t new_size = bufferSize_;
  while (len > avail) {
    new_size = new_size > 0 ? new_size * 2 : 1;
    avail = available_write() + (new_size - bufferSize_);
  }

  // Allocate into a new pointer so we don't bork ours if it fails.
  uint8_t* new_buffer = static_cast<uint8_t*>(std::realloc(buffer_, new_size));
  if (new_buffer == NULL) {
    throw std::bad_alloc();
  }

  rBase_ = new_buffer + (rBase_ - buffer_);
  rBound_ = new_buffer + (rBound_ - buffer_);
  wBase_ = new_buffer + (wBase_ - buffer_);
  wBound_ = new_buffer + new_size;
  buffer_ = new_buffer;
  bufferSize_ = new_size;



If old bufferSize_ is lager than 2gb, then calculating new size will overflow.
i.e. if bufferSize_ = 3355443200, then new buffer size will be 2415919104, which is less than old size.

However, avail = available_write() + (new_size - bufferSize_) overflows again, so we will end up with an shrinked buffer.

What is worse is that after
  wBase_ = new_buffer + (wBase_ - buffer_);
  wBound_ = new_buffer + new_size;
wBase_ stays the same, but wBound_ becomes lower than it. What happens next is that   uint32_t avail = available_write() may overflow every time subsequently. and thrift writes to unknown memory.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)