From 63e0c3e1b5b0abe22086589fc18db9984342ce19 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 4 Sep 2018 14:10:41 +0200 Subject: qppmhandler: Fix undefined overflow behavior image/qppmhandler.cpp:77:25: runtime error: signed integer overflow: 10 * 300000000 cannot be represented in type 'int' #0 0x4cecb5 in read_pbm_int(QIODevice*) /src/qt/qtbase/src/gui/image/qppmhandler.cpp:77:25 #1 0x4cb1ac in read_pbm_body(QIODevice*, char, int, int, int, QImage*) /src/qt/qtbase/src/gui/image/qppmhandler.cpp:271:29 #2 0x4ca3d8 in QPpmHandler::read(QImage*) /src/qt/qtbase/src/gui/image/qppmhandler.cpp:509:10 #3 0x4b238d in QImageReader::read(QImage*) /src/qt/qtbase/src/gui/image/qimagereader.cpp:1253:22 #4 0x4b1b61 in QImageReader::read() /src/qt/qtbase/src/gui/image/qimagereader.cpp:1201:12 #5 0x486f66 in QImage::fromData(unsigned char const*, int, char const*) /src/qt/qtbase/src/gui/image/qimage.cpp:3624:37 #6 0x486cd8 in QImage::loadFromData(unsigned char const*, int, char const*) /src/qt/qtbase/src/gui/image/qimage.cpp:3590:13 #7 0x434b2e in LLVMFuzzerTestOneInput /src/qimage_fuzzer.cc:28:7 #8 0x44b167 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:570:15 #9 0x44a535 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:479:3 #10 0x44c428 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:707:19 #11 0x44d1b5 in fuzzer::Fuzzer::Loop(std::__1::vector, std::__1::allocator >, fuzzer::fuzzer_allocator, std::__1::allocator > > > const&) /src/libfuzzer/FuzzerLoop.cpp:838:5 #12 0x440a29 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6 #13 0x434bf8 in main /src/libfuzzer/FuzzerMain.cpp:20:10 #14 0x7fba939a082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) #15 0x409bb8 in _start (/out/qimage_fuzzer+0x409bb8) Change-Id: I9ad78afc4ea9c5c8b7530aa17013abe91202e84b Reviewed-by: Eirik Aavitsland --- src/gui/image/qppmhandler.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/gui/image/qppmhandler.cpp') diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 1863c58ff0..6f6469042b 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -68,13 +68,19 @@ static int read_pbm_int(QIODevice *d) char c; int val = -1; bool digit; + bool hasOverflow = false; for (;;) { if (!d->getChar(&c)) // end of file break; digit = isdigit((uchar) c); if (val != -1) { if (digit) { - val = 10*val + c - '0'; + const int cValue = c - '0'; + if (val <= (INT_MAX - cValue) / 10) { + val = 10*val + cValue; + } else { + hasOverflow = true; + } continue; } else { if (c == '#') // comment @@ -91,7 +97,7 @@ static int read_pbm_int(QIODevice *d) else break; } - return val; + return hasOverflow ? -1 : val; } static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int& mcc) -- cgit v1.2.3