wernsey / bitmap

A C module for manipulating bitmap/raster graphics
MIT No Attribution
70 stars 12 forks source link

heap-buffer-overflow when loading gif #8

Closed mitchcurtis closed 4 years ago

mitchcurtis commented 4 years ago

I'm getting a heap-buffer-overflow when running my auto test which loads the attached gif:

16:56:20: Starting /home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/install-root/usr/local/test-app animationGifExport...
Failed to load qt_* translation for locale "en_GB" from "/home/mitch/dev/qt-dev2-debug/qtbase/translations"
********* Start testing of tst_App *********
Config: Using QtTest library 6.0.0, Qt 6.0.0 (x86_64-little_endian-lp64 shared (dynamic) debug build; by GCC 7.5.0)
PASS   : tst_App::initTestCase()
QDEBUG : tst_App::animationGifExport() "/tmp/Slate Test Suite-dVzHHb/animation.gif"
=================================================================
==27720==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040002eeccf at pc 0x55e95dd0ae9f bp 0x7ffe90423790 sp 0x7ffe90423780
READ of size 1 at 0x6040002eeccf thread T0
    #0 0x55e95dd0ae9e in gif_load_fp /home/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:213
    #1 0x55e95dd10d47 in gif_load /home/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:825
    #2 0x55e95dd51eb9 in tst_App::animationGifExport() /home/mitch/dev/slate/tests/auto/tst_app.cpp:1044
    #3 0x55e95de590af in tst_App::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/test-app.99bdad93/qt.headers/tst_app.moc:601
    #4 0x7fa80c9035cf in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /home/mitch/dev/qt-dev2/qtbase/src/corelib/kernel/qmetaobject.cpp:2301
    #5 0x7fa815cace02 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/home/mitch/dev/qt-dev2-debug/qtbase/lib/libQt6Test.so.6+0x4ce02)
    #6 0x7fa815c97a74 in QTest::TestMethods::invokeTestOnData(int) const /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:934
    #7 0x7fa815c99b46 in QTest::TestMethods::invokeTest(int, char const*, QTest::WatchDog*) const /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1162
    #8 0x7fa815c9cff4 in QTest::TestMethods::invokeTests(QObject*) const /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1503
    #9 0x7fa815c9e73b in QTest::qRun() /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1928
    #10 0x7fa815c9d960 in QTest::qExec(QObject*, int, char**) /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1836
    #11 0x55e95de58d96 in main /home/mitch/dev/slate/tests/auto/tst_app.cpp:6268
    #12 0x7fa80b38bb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #13 0x55e95dd09e29 in _start (/home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/install-root/usr/local/test-app+0x58e29)

Address 0x6040002eeccf is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:213 in gif_load_fp
Shadow bytes around the buggy address:
  0x0c0880055d40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c0880055d90: fa fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa fa
  0x0c0880055da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055db0: fa fa fa fa fa f
![animation](https://user-images.githubusercontent.com/6002340/88071598-54593a00-cb74-11ea-856b-b7451d65ff8b.gif)
a fa fa fa fa fa fa fa fa fa fa
  0x0c0880055dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880055de0: 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
==27720==ABORTING
16:56:24: /home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/install-root/usr/local/test-app exited with code 1

The stack trace prints to https://github.com/wernsey/bitmap/blob/master/misc/gif.c#L213, and if I split that expression up:

    uint8_t r = bg->r;
    uint8_t g = bg->g;
    uint8_t b = bg->b;
    file.gif->background = bm_rgb(r, g, b);

it points to bg->r.

I will try to come up with a minimal example.

mitchcurtis commented 4 years ago

animation

mitchcurtis commented 4 years ago

I can't reproduce this with a minimal example:

gif-bug.zip