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

Out of bounds read in function `QRadialFetchSimd<QSimdSse2>::fetch` when input craft svg file

    XMLWordPrintable

    Details

    • Platform/s:
      Linux/Other display system
    • Commits:
      bfd6ee0d8cf34b63d32adf10ed93daa0086b359f (qt/qtsvg/dev) 0fa522904d65b73d48d5fadf690131e9ebb58d2a (qt/qtsvg/6.0) 9f7ccbfc68d20d0dc2ddc1e7dee5572dcf7dcd48 (qt/qtsvg/6.1) 7bbf88403fd2d1fe79fab7c8e469f8aeafeb7372 (qt/tqtc-qtsvg/tqtc/lts-5.15)

      Description

      To Reproduce

      ./qtsvg_svg_qsvgrenderer_render ./1.svg
      

      Debug Info

      # ./qtsvg_svg_qsvgrenderer_render ./1.svg
      INFO: Seed: 3360833592
      ./qtsvg_svg_qsvgrenderer_render: Running 1 inputs 1 time(s) each.
      Running: ./1.svg
      UndefinedBehaviorSanitizer:DEADLYSIGNAL
      ==12881==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0xfffffffe01e5cbd0 (pc 0x00000086cd75 bp 0x7fffffff7bb0 sp 0x7fffffff7a30 T12881)
      ==12881==The signal is caused by a READ memory access.
          #0 0x86cd75 in QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double) /src/qt/qtbase/src/gui/painting/qdrawhelper_p.h:601:13
          #1 0x86c140 in unsigned int const* qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdSse2>, unsigned int>(unsigned int*, Operator const*, QSpanData const*, int, int, int) /src/qt/qtbase/src/gui/painting/qdrawhelper_p.h:469:9
          #2 0x86beed in qt_fetch_radial_gradient_sse2(unsigned int*, Operator const*, QSpanData const*, int, int, int) /src/qt/qtbase/src/gui/painting/qdrawhelper_sse2.cpp:515:12
          #3 0x81a1e6 in BlendSrcGeneric::fetch(int, int, int) /src/qt/qtbase/src/gui/painting/qdrawhelper.cpp:3141:16
          #4 0x81a09d in void handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, BlendSrcGeneric&) /src/qt/qtbase/src/gui/painting/qdrawhelper.cpp:3085:56
          #5 0x807b6a in blend_src_generic(int, QT_FT_Span_ const*, void*) /src/qt/qtbase/src/gui/painting/qdrawhelper.cpp:3193:5
          #6 0x807a0d in qBlendGradient(int, QT_FT_Span_ const*, void*) /src/qt/qtbase/src/gui/painting/qdrawhelper.cpp
          #7 0x6645a4 in qt_span_fill_clipRect(int, QT_FT_Span_ const*, void*) /src/qt/qtbase/src/gui/painting/qpaintengine_raster.cpp:4166:9
          #8 0x83f79b in drawPixel(QCosmeticStroker*, int, int, int) /src/qt/qtbase/src/gui/painting/qcosmeticstroker.cpp:165:13
          #9 0x842a6f in bool drawLineAA<&(drawPixel(QCosmeticStroker*, int, int, int)), (anonymous namespace)::NoDasher>(QCosmeticStroker*, double, double, double, double, int) /src/qt/qtbase/src/gui/painting/qcosmeticstroker.cpp:1070:21
          #10 0x83fda3 in QCosmeticStroker::drawPath(QVectorPath const&) /src/qt/qtbase/src/gui/painting/qcosmeticstroker.cpp:575:21
          #11 0x65c310 in QRasterPaintEngine::stroke(QVectorPath const&, QPen const&) /src/qt/qtbase/src/gui/painting/qpaintengine_raster.cpp:1622:17
          #12 0x84432e in QEmulationPaintEngine::stroke(QVectorPath const&, QPen const&) /src/qt/qtbase/src/gui/painting/qemulationpaintengine.cpp
          #13 0x66e33c in QPaintEngineEx::draw(QVectorPath const&) /src/qt/qtbase/src/gui/painting/qpaintengineex.cpp:606:9
          #14 0x66f40f in QPaintEngineEx::drawPath(QPainterPath const&) /src/qt/qtbase/src/gui/painting/qpaintengineex.cpp:845:9
          #15 0x674b86 in QPainter::drawPath(QPainterPath const&) /src/qt/qtbase/src/gui/painting/qpainter.cpp
          #16 0x77c2ae in QTextLine::draw_internal(QPainter*, QPointF const&, QTextLayout::FormatRange const*) const /src/qt/qtbase/src/gui/text/qtextlayout.cpp:2681:16
          #17 0x77c68a in QTextLine::draw(QPainter*, QPointF const&) const /src/qt/qtbase/src/gui/text/qtextlayout.cpp:2484:5
          #18 0x77ae0f in QTextLayout::draw(QPainter*, QPointF const&, QList<QTextLayout::FormatRange> const&, QRectF const&) const /src/qt/qtbase/src/gui/text/qtextlayout.cpp:1232:11
          #19 0x542460 in QSvgText::draw(QPainter*, QSvgExtraStates&) /src/qt/qtsvg/src/svg/qsvggraphics.cpp:445:16
          #20 0x513801 in QSvgTinyDocument::draw(QPainter*, QRectF const&) /src/qt/qtsvg/src/svg/qsvgtinydocument.cpp:284:19
          #21 0x51472c in QSvgTinyDocument::draw(QPainter*) /src/qt/qtsvg/src/svg/qsvgtinydocument.cpp:428:5
          #22 0x510c8e in QSvgRenderer::render(QPainter*) /src/qt/qtsvg/src/svg/qsvgrenderer.cpp:418:20
          #23 0x4b95c1 in LLVMFuzzerTestOneInput /src/qt/qtsvg/tests/libfuzzer/svg/qsvgrenderer/render/main.cpp:44:14
          #24 0x44ac71 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /local/mnt/workspace/bcain_clang_bcain-ubuntu_7561/final/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:559:15
          #25 0x436372 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /local/mnt/workspace/bcain_clang_bcain-ubuntu_7561/final/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:297:6
          #26 0x43c3de in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /local/mnt/workspace/bcain_clang_bcain-ubuntu_7561/final/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:797:9
          #27 0x463eb2 in main /local/mnt/workspace/bcain_clang_bcain-ubuntu_7561/final/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
          #28 0x7ffff69e883f in __libc_start_main /build/glibc-e6zv40/glibc-2.23/csu/../csu/libc-start.c:291
          #29 0x410a88 in _start (/src/qtsvg_svg_qsvgrenderer_render+0x410a88)
      
      UndefinedBehaviorSanitizer can not provide additional info.
      SUMMARY: UndefinedBehaviorSanitizer: SEGV /src/qt/qtbase/src/gui/painting/qdrawhelper_p.h:601:13 in QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)
      ==12881==ABORTING
      

      I think the invalid sign extension on 0x86cd6d causes integer overflow to be the root cause of this vulnerability

      [----------------------------------registers-----------------------------------]
      RAX: 0x0
      RBX: 0xffffffff
      RCX: 0xffffffff
      RDX: 0x1e5cea0 --> 0xffff0000ffff0000
      RSI: 0xffffffff80000000
           ^^^^^^^^^^^^^^^^^^
      RDI: 0x7ff
      RBP: 0x7fffffff7b50 --> 0x7fffffff7be0 --> 0x7fffffff7c00 --> 0x7fffffff7c40 --> 0x7fffffff7cc0 --> 0x7fffffffbe30 (--> ...)
      RSP: 0x7fffffff79d0 --> 0x7ff000007ff
      RIP: 0x86cd75 (<QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+725>:       and    ecx,DWORD PTR [rdx+rsi*4])
      R8 : 0x0
      R9 : 0x1
      R10: 0x7fffffffc0a8 --> 0xbff0000000000000
      R11: 0x1
      R12: 0x7fffffff7ce0 --> 0x3fbeb85100000003
      R13: 0x7fffffff9d78 --> 0x0
      R14: 0x7fffffff9d7c --> 0x0
      R15: 0x1e545c8 --> 0x1e4d310 --> 0xf6d8cb00
      EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
      [-------------------------------------code-------------------------------------]
         0x86cd64 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+708>:  or     ecx,ebx
         0x86cd66 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+710>:  mov    rdx,QWORD PTR [r15+0xe0]
         0x86cd6d <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+717>:  movsxd rsi,DWORD PTR [rbp+rax*1-0xf0]
      => 0x86cd75 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+725>:  and    ecx,DWORD PTR [rdx+rsi*4]
         0x86cd78 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+728>:  mov    DWORD PTR [r13+rax*1+0x0],ecx
         0x86cd7d <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+733>:  add    rax,0x4
         0x86cd81 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+737>:  cmp    rax,0x10
         0x86cd85 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+741>:
          jne    0x86cd60 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+704>:      jne    0x86cd60 <QRadialFetchSimd<QSimdSse2>::fetch(unsigned int*, unsigned int*, Operator const*, QSpanData const*, double, double, double, double, double)+704>
      [------------------------------------stack-------------------------------------]
      0000| 0x7fffffff79d0 --> 0x7ff000007ff
      0008| 0x7fffffff79d8 --> 0x7ff000007ff
      0016| 0x7fffffff79e0 --> 0x7ff000007ff
      0024| 0x7fffffff79e8 --> 0x7ff000007ff
      0032| 0x7fffffff79f0 --> 0x3ff000003ff
      0040| 0x7fffffff79f8 --> 0x3ff000003ff
      0048| 0x7fffffff7a00 --> 0xffc00000ffc00000
      0056| 0x7fffffff7a08 --> 0xffc00000ffc00000
      [------------------------------------------------------------------------------]
      Legend: code, data, rodata, value
      0x000000000086cd75      601                 FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_PAD)
      gdb-peda$ x/gx 0x7fffffff7b50-0xf0
      0x7fffffff7a60: 0x8000000080000000
                      ^^^^^^^^^^^^^^^^^^
      

      Environment:

      • version : Qt branch 6.0.0 master (4e43ed1f939a797a8562361145713be8a0780365)
      • OS: Ubuntu 16.04
      • clang version: 11

      Additional context

      compile argument´╝Ü

      https://github.com/google/oss-fuzz/tree/master/projects/qt

      Credit: 1vanChen of NSFOCUS Security Team

        Attachments

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

          Activity

            People

            Assignee:
            allan.jensen Allan Sandfeld Jensen
            Reporter:
            ivanchen chen ivan
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes