mitchcurtis / slate

Pixel Art Editor
GNU General Public License v3.0
1.05k stars 102 forks source link

heap-buffer-overflow in gif_load when exporting GIF #155

Closed mitchcurtis closed 3 years ago

mitchcurtis commented 3 years ago

Originally reported upstream, but couldn't reproduce with a minimal example:

https://github.com/wernsey/bitmap/issues/8

=================================================================
==41662==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040002c6bcd at pc 0x000101a6a97d bp 0x7ffeee1953f0 sp 0x7ffeee1953e8
READ of size 1 at 0x6040002c6bcd thread T0
    #0 0x101a6a97c in gif_load_fp gif.c:213
    #1 0x101a68ed2 in gif_load gif.c:825
    #2 0x101ba417c in tst_App::animationGifExport() tst_app.cpp:5301
    #3 0x101be7f81 in tst_App::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) tst_app.moc:748
    #4 0x1051cacce in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const+0xf8e (QtCore:x86_64+0x6c7cce)
    #5 0x1069fbf0e in QTest::TestMethods::invokeTestOnData(int) const+0xb8e (QtTest:x86_64+0xcf0e)
    #6 0x1069fee08 in QTest::TestMethods::invokeTest(int, char const*, QTest::WatchDog*) const+0x7b8 (QtTest:x86_64+0xfe08)
    #7 0x106a02285 in QTest::TestMethods::invokeTests(QObject*) const+0xc85 (QtTest:x86_64+0x13285)
    #8 0x106a0336c in QTest::qRun()+0x34c (QtTest:x86_64+0x1436c)
    #9 0x106a02a04 in QTest::qExec(QObject*, int, char**)+0x14 (QtTest:x86_64+0x13a04)
    #10 0x101be7637 in main tst_app.cpp:6672
    #11 0x101a68e33 in start+0x33 (test-app:x86_64+0x100001e33)

0x6040002c6bcd is located 3 bytes to the left of 48-byte region [0x6040002c6bd0,0x6040002c6c00)
allocated by thread T0 here:
    #0 0x1081ef84d in wrap__Znwm+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x5584d)
    #1 0x105238a2c in QObject::setObjectName(QString const&)+0xfc (QtCore:x86_64+0x735a2c)
    #2 0x10526269d in QObject::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)+0x22d (QtCore:x86_64+0x75f69d)
    #3 0x104056d07 in QQmlObjectCreator::setPropertyValue(QQmlPropertyData const*, QV4::CompiledData::Binding const*)+0x1fa7 (QtQml:x86_64+0x8d3d07)
    #4 0x10404ce89 in QQmlObjectCreator::setPropertyBinding(QQmlPropertyData const*, QV4::CompiledData::Binding const*)+0x20e9 (QtQml:x86_64+0x8c9e89)
    #5 0x10405420e in QQmlObjectCreator::setupBindings(bool)+0x145e (QtQml:x86_64+0x8d120e)
    #6 0x10406422d in QQmlObjectCreator::populateInstance(int, QObject*, QObject*, QQmlPropertyData const*)+0x276d (QtQml:x86_64+0x8e122d)
    #7 0x104047a8b in QQmlObjectCreator::createInstance(int, QObject*, bool)+0x3bcb (QtQml:x86_64+0x8c4a8b)
    #8 0x104042bd9 in QQmlObjectCreator::create(int, QObject*, QQmlInstantiationInterrupt*, int)+0x5a9 (QtQml:x86_64+0x8bfbd9)
    #9 0x103ec91f2 in QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt&)+0x862 (QtQml:x86_64+0x7461f2)
    #10 0x103ec7f5b in QQmlEnginePrivate::incubate(QQmlIncubator&, QQmlContextData*)+0x3eb (QtQml:x86_64+0x744f5b)
    #11 0x103ebcd27 in QQmlComponent::create(QQmlIncubator&, QQmlContext*, QQmlContext*)+0x6a7 (QtQml:x86_64+0x739d27)
    #12 0x1061c4420 in QQuickLoaderPrivate::_q_sourceLoaded()+0x410 (QtQuick:x86_64+0x601420)
    #13 0x1061c280b in QQuickLoaderPrivate::load()+0x21b (QtQuick:x86_64+0x5ff80b)
    #14 0x1061c7a15 in QQuickLoader::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)+0x535 (QtQuick:x86_64+0x604a15)
    #15 0x103ea336f in QQmlPropertyPrivate::write(QObject*, QQmlPropertyData const&, QVariant const&, QQmlContextData*, QFlags<QQmlPropertyData::WriteFlag>)+0x2f4f (QtQml:x86_64+0x72036f)
    #16 0x103ea0276 in QQmlPropertyPrivate::writeValueProperty(QObject*, QQmlPropertyData const&, QQmlPropertyData const&, QVariant const&, QQmlContextData*, QFlags<QQmlPropertyData::WriteFlag>)+0x3c6 (QtQml:x86_64+0x71d276)
    #17 0x104011312 in QQmlBinding::slowWrite(QQmlPropertyData const&, QQmlPropertyData const&, QV4::Value const&, bool, QFlags<QQmlPropertyData::WriteFlag>)+0x1292 (QtQml:x86_64+0x88e312)
    #18 0x10401c682 in GenericBinding<0>::write(QV4::Value const&, bool, QFlags<QQmlPropertyData::WriteFlag>)+0x1102 (QtQml:x86_64+0x899682)
    #19 0x1040170fa in QQmlNonbindingBinding::doUpdate(QQmlJavaScriptExpression::DeleteWatcher const&, QFlags<QQmlPropertyData::WriteFlag>, QV4::Scope&)+0x98a (QtQml:x86_64+0x8940fa)
    #20 0x10400ea03 in QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>)+0x4f3 (QtQml:x86_64+0x88ba03)
    #21 0x103f99226 in QQmlNotifier::emitNotify(QQmlNotifierEndpoint*, void**)+0x646 (QtQml:x86_64+0x816226)
    #22 0x103e6b2af in QQmlData::signalEmitted(QAbstractDeclarativeData*, QObject*, int, void**)+0x65f (QtQml:x86_64+0x6e82af)
    #23 0x105255456 in void doActivate<false>(QObject*, int, void**)+0x1b6 (QtCore:x86_64+0x752456)
    #24 0x103e5137b in QQmlVMEMetaObject::metaCall(QObject*, QMetaObject::Call, int, void**)+0x590b (QtQml:x86_64+0x6ce37b)
    #25 0x104018186 in QObjectPointerBinding::write(QV4::Value const&, bool, QFlags<QQmlPropertyData::WriteFlag>)+0xd96 (QtQml:x86_64+0x895186)
    #26 0x1040170fa in QQmlNonbindingBinding::doUpdate(QQmlJavaScriptExpression::DeleteWatcher const&, QFlags<QQmlPropertyData::WriteFlag>, QV4::Scope&)+0x98a (QtQml:x86_64+0x8940fa)
    #27 0x10400ea03 in QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>)+0x4f3 (QtQml:x86_64+0x88ba03)
    #28 0x103f99226 in QQmlNotifier::emitNotify(QQmlNotifierEndpoint*, void**)+0x646 (QtQml:x86_64+0x816226)
    #29 0x103e6b2af in QQmlData::signalEmitted(QAbstractDeclarativeData*, QObject*, int, void**)+0x65f (QtQml:x86_64+0x6e82af)

SUMMARY: AddressSanitizer: heap-buffer-overflow gif.c:213 in gif_load_fp
Shadow bytes around the buggy address:
  0x1c0800058d20: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
  0x1c0800058d30: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa
  0x1c0800058d40: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
  0x1c0800058d50: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
  0x1c0800058d60: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
=>0x1c0800058d70: fa fa fd fd fd fd fd fa fa[fa]00 00 00 00 00 00
  0x1c0800058d80: fa fa fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x1c0800058d90: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
  0x1c0800058da0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa
  0x1c0800058db0: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fd
  0x1c0800058dc0: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd
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
==41662==ABORTING
23:34:23: The program has unexpectedly finished.