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

Buffer overrun and crash in QColorTransferTable::applyInverse()

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 6.4.0 RC1, 6.5.0 Beta1
    • 6.0, 6.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.2.4, 6.3.0, 6.3.1, 6.4.0 Beta1
    • GUI: Painting
    • None
    • All
    • a2501fff81 (qt/qtbase/dev) a2501fff81 (qt/tqtc-qtbase/dev) b2fe6b1c05 (qt/qtbase/6.4) b2fe6b1c05 (qt/tqtc-qtbase/6.4) 2648d10229 (qt/qtbase/6.3) 2648d10229 (qt/tqtc-qtbase/6.3)

    Description

      A bug presumably introduced in f493d41722fc76a04f699ea26128fdf3d215d913 causes to access a table at index -1.

      Callstack:

      >	Qt6Guid.dll!QColorTransferTable::applyInverse(float x, float resultLargerThan) Line 143	C++
       	Qt6Guid.dll!QColorTrcLut::fromTransferTable(const QColorTransferTable & table) Line 79	C++
       	Qt6Guid.dll!lutFromTrc(const QColorTrc & trc) Line 62	C++
       	Qt6Guid.dll!QColorTransformPrivate::updateLutsIn() Line 83	C++
       	Qt6Guid.dll!QColorTransformPrivate::apply<unsigned int>(unsigned int * dst, const unsigned int * src, __int64 count, QFlags<enum QColorTransformPrivate::TransformFlag> flags) Line 907	C++
       	Qt6Guid.dll!QColorTransformPrivate::apply(unsigned int * dst, const unsigned int * src, __int64 count, QFlags<enum QColorTransformPrivate::TransformFlag> flags) Line 1004	C++
       	Qt6Guid.dll!QImage::applyColorTransform::__l29::<lambda>(int yStart, int yEnd) Line 5063	C++
       	Qt6Guid.dll!std::invoke<void <lambda>(int, int) &,int,int>(QImage::applyColorTransform::__l29::void <lambda>(int, int) & _Obj, int && _Arg1, int && <_Args2_0>) Line 1503	C++
       	Qt6Guid.dll!std::_Invoker_ret<void,1>::_Call<void <lambda>(int, int) &,int,int>(QImage::applyColorTransform::__l29::void <lambda>(int, int) & _Func, int && <_Vals_0>, int && <_Vals_1>) Line 652	C++
       	Qt6Guid.dll!std::_Func_impl_no_alloc<void <lambda>(int, int),void,int,int>::_Do_call(int && <_Args_0>, int && <_Args_1>) Line 823	C++
       	Qt6Guid.dll!std::_Func_class<void,int,int>::operator()(int <_Args_0>, int <_Args_1>) Line 870	C++
       	Qt6Guid.dll!QImage::applyColorTransform(const QColorTransform & transform) Line 5087	C++
      
      

      Explanation:

      QColorTransferTable::applyInverse() is called in a for loop by QColorTrcLut::fromTransferTable(), here:

      minInverse = table.applyInverse(i / qreal(255 * 16), minInverse);
      

      The first time it is called, i is zero. I.e. the first argument passed to applyInverse() is zero. Therefore, applyInverse returns zero and minInverse becomes zero.

      When the second call is made, the first argument is no longer zero, but now the second argument is zero. When evaluating the line

      uint32_t i = static_cast<uint32_t>(std::floor(resultLargerThan * (m_tableSize - 1)));
      

      i is assigned zero. In the line

      auto it = std::lower_bound(m_table16.cbegin() + i, m_table16.cend(), v);
      

      cbegin() is assigned to it. Therefore, i stays zero during the assignment of

      i = it - m_table16.cbegin();
      

      And finally, when evaluating

      m_table16[i - 1];
      

      we are accessing the table at index -1. Applications compiled in debug mode will assert. All others will crash.

      Pls. note that the same broken logic is used a few lines below for m_table8.

       

      Attachments

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

        Activity

          People

            allan.jensen Allan Sandfeld Jensen
            derselbst Tom M
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes