Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.15.1, 6.0.0, 6.0.2, 6.2
-
None
-
-
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
For Gerrit Dashboard: QTBUG-91507 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
337585,2 | Clamp parsed doubles to float representable values | 6.1 | qt/qtsvg | Status: MERGED | +2 | 0 |
337587,4 | Clamp parsed doubles to float representable values | dev | qt/qtsvg | Status: MERGED | +2 | 0 |
337646,2 | Clamp parsed doubles to float representable values | 6.0 | qt/qtsvg | Status: MERGED | +2 | 0 |
337647,3 | Clamp parsed doubles to float representable values | 5.12 | qt/qtsvg | Status: MERGED | +2 | 0 |
337649,2 | Clamp parsed doubles to float representable values | tqtc/lts-5.15 | qt/tqtc-qtsvg | Status: MERGED | +2 | 0 |