Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-52125

QContiguousCache may leak after setCapacity is called

    XMLWordPrintable

Details

    • fc1ab49cd75608f257fb9aa577fed490c5a8e551 (qt/qtbase/5.12)

    Description

      In QContiguousCache::setCapacity, not all fields of QContiguousCacheData are initialized after the new data is allocated, including the reference count d->ref.

      Since the reference count will be an arbitrary number after setCapacity is called, the data may not be freed after the destructor is called.

      This error (memory leak and use of uninitialized data) was found by the dynamic analysis tool Pareon Verify. Here's an excerpt of the report we get when analyzing tst_qcontiguouscache:

      [M0181] Memory leak detected:
        the heap object of size 632 allocated through a call to `realloc' in
          function qReallocAligned(void*, unsigned long, unsigned long, unsigned long) at qtbase/src/corelib/global/qmalloc.cpp:81
          called from function qMallocAligned(unsigned long, unsigned long) at qtbase/src/corelib/global/qmalloc.cpp:70
          called from function QContiguousCacheData::allocateData(int, int) at qtbase/src/corelib/tools/qcontiguouscache.cpp:53
          called from function QContiguousCache<int>::allocateData(int) at qtbase/src/corelib/tools/qcontiguouscache.h:276
          called from function QContiguousCache<int>::setCapacity(int) at qtbase/src/corelib/tools/qcontiguouscache.h:212
          called from function tst_QContiguousCache::setCapacity() at qtbase/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp:338
          (...)
          ^^^ application start ^^^
         has become unreachable.
        This object was last accessible as the result of the call to function `QContiguousCache<int>::at(int) const' in
          function tst_QContiguousCache::setCapacity() at qtbase/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp:347
          (...)
          ^^^ application start ^^^
        This object was last accessed by:
        the atomic memory access in
          function std::__atomic_base<int>::operator--()
          called from function bool QAtomicOps<int>::deref<int>(std::atomic<int>&) at qtbase/src/corelib/arch/qatomic_cxx11.h:140
          called from function QBasicAtomicInteger<int>::deref() at qtbase/src/corelib/thread/qbasicatomic.h:132
          called from function QContiguousCache<int>::detach_helper() at qtbase/src/corelib/tools/qcontiguouscache.h:200
          called from function QContiguousCache<int>::detach() at qtbase/src/corelib/tools/qcontiguouscache.h:97
          called from function QContiguousCache<int>::setCapacity(int) at qtbase/src/corelib/tools/qcontiguouscache.h:210
          called from function tst_QContiguousCache::setCapacity() at qtbase/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp:350
          (...)
          ^^^ application start ^^^
      

      For a possible fix, simply initialize all fields of QContiguousData:

      diff --git a/qtbase/src/corelib/tools/qcontiguouscache.h b/qtbase/src/corelib/tools/qcontiguouscache.h
      index 41d198f..79515bc 100644
      --- a/qtbase/src/corelib/tools/qcontiguouscache.h
      +++ b/qtbase/src/corelib/tools/qcontiguouscache.h
      @@ -210,6 +210,9 @@ void QContiguousCache<T>::setCapacity(int asize)
           detach();
           union { QContiguousCacheData *d; QContiguousCacheTypedData<T> *p; } x;
           x.d = allocateData(asize);
      +    x.d->ref.store(1);
      +    x.d->sharable = true;
      +    x.d->reserved = 0;
           x.d->alloc = asize;
           x.d->count = qMin(d->count, asize);
           x.d->offset = d->offset + d->count - x.d->count;
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            poikelin Joni Poikelin
            lessandrovf Lessandro Mariano
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes