Details
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.