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

QImage PNG write heap-buffer-overflow

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • Not Evaluated
    • None
    • 6.2.2, 6.2.3
    • Core: Other
    • None
    • Linux/X11, Windows

    Description

      The first observation was part of data on certain input was ruined, when the PNG save was done.

       

      I re-compiled with

      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
      set (CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
      

      And noticed that i received an error during write. Now i created simple program that reproduces the error:

      #include <memory>
      #include <QImage>
      #include <QBuffer>
      const int xsize = 2557;
      const int ysize = 2078;
      int main(void)
      {  
          uint16_t* spoof_data = new uint16_t[ xsize * ysize ];
          memset( spoof_data, 0x00, xsize*ysize * sizeof(uint16_t) );
          QImage qimg_out((const unsigned char *)(spoof_data),xsize, ysize, QImage::Format_Grayscale16);
          auto buffer = std::make_unique<QBuffer>();
          buffer->open(QIODevice::WriteOnly);
          
          qimg_out.save(buffer.get(), "PNG"); // writes image into ba in PNG format
          delete[] spoof_data;
          
          printf("All good!\n");
      }
      
      

       

      Compiled with:

      cmake_minimum_required(VERSION 3.16)
      project(helloworld VERSION 1.0.0 LANGUAGES CXX)
      set(CMAKE_CXX_STANDARD 17)
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      set(CMAKE_AUTOMOC ON)
      set(CMAKE_AUTORCC ON)
      set(CMAKE_AUTOUIC ON)
      find_package(Qt6 REQUIRED COMPONENTS Widgets)
      add_executable(silly test.cpp)
      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
      set (CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
      target_link_libraries(silly PRIVATE Qt6::Widgets)
      

      Produces:

       % ./silly
      =================================================================
      ==53193==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fcce5efef4c at pc 0x7fccedd55490 bp 0x7ffd0371e4a0 sp 0x7ffd0371dc48
      READ of size 5114 at 0x7fcce5efef4c thread T0
          #0 0x7fccedd5548f in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790
          #1 0x7fcced36a8a2 in png_write_row /home/qt/work/qt/qtbase/src/3rdparty/libpng/pngwrite.c:842
          #2 0x7fcced36b087 in png_write_image /home/qt/work/qt/qtbase/src/3rdparty/libpng/pngwrite.c:626
          #3 0x7fcced36b087 in png_write_image /home/qt/work/qt/qtbase/src/3rdparty/libpng/pngwrite.c:601
          #4 0x7fcced1f8644 in QPNGImageWriter::writeImage(QImage const&, int, QString const&, int, int) /home/qt/work/qt/qtbase/src/gui/image/qpnghandler.cpp:1127
          #5 0x7fcced1f900a in QPNGImageWriter::writeImage(QImage const&, int, QString const&) /home/qt/work/qt/qtbase/src/gui/image/qpnghandler.cpp:182
          #6 0x7fcced1f900a in write_png_image /home/qt/work/qt/qtbase/src/gui/image/qpnghandler.cpp:1179
          #7 0x7fcced1f900a in QPngHandler::write(QImage const&) /home/qt/work/qt/qtbase/src/gui/image/qpnghandler.cpp:1226
          #8 0x7fccece16f07 in QImageWriter::write(QImage const&) /home/qt/work/qt/qtbase/src/gui/image/qimagewriter.cpp:720
          #9 0x7fccecde8cbb in QImage::save(QIODevice*, char const*, int) const /home/qt/work/qt/qtbase/src/gui/image/qimage.cpp:3864
          #10 0x56470e47862a in main (/home/xx/DEV/qt-bug-png-write/silly+0x262a)
          #11 0x7fccec0850b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
          #12 0x56470e47832d in _start (/home/xx/DEV/qt-bug-png-write/silly+0x232d)0x7fcce5efef4c is located 0 bytes to the right of 10626892-byte region [0x7fcce54dc800,0x7fcce5efef4c)
      allocated by thread T0 here:
          #0 0x7fcceddc9787 in operator new[](unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cc:107
          #1 0x56470e4784c2 in main (/home/xx/DEV/qt-bug-png-write/silly+0x24c2)
          #2 0x7fccec0850b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:790 in __interceptor_memcpy
      Shadow bytes around the buggy address:
        0x0ffa1cbd7d90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0ffa1cbd7da0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0ffa1cbd7db0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0ffa1cbd7dc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0ffa1cbd7dd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      =>0x0ffa1cbd7de0: 00 00 00 00 00 00 00 00 00[04]fa fa fa fa fa fa
        0x0ffa1cbd7df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0ffa1cbd7e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0ffa1cbd7e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0ffa1cbd7e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0ffa1cbd7e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      Shadow byte legend (one shadow byte represents 8 application bytes):
        Addressable:           00
        Partially addressable: 01 02 03 04 05 06 07 
        Heap left redzone:       fa
        Freed heap region:       fd
        Stack left redzone:      f1
        Stack mid redzone:       f2
        Stack right redzone:     f3
        Stack after return:      f5
        Stack use after scope:   f8
        Global redzone:          f9
        Global init order:       f6
        Poisoned by user:        f7
        Container overflow:      fc
        Array cookie:            ac
        Intra object redzone:    bb
        ASan internal:           fe
        Left alloca redzone:     ca
        Right alloca redzone:    cb
        Shadow gap:              cc
      ==53193==ABORTING
      
      

       

      When testing more, seems like if xsize=2558 it works ok, but if xsize is odd (tried few) it causes the issue.

       When testing more, seems like 6.2.3 is also affected.

       

      Attachments

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

        Activity

          People

            vgt Eirik Aavitsland
            salmenrinnep Pauli Salmenrinne
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes