From 6254529d2d427a5558deb15efb61929dab93e3f4 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Fri, 18 Aug 2023 14:09:00 +0000 Subject: [PATCH] qoi: fix buffer overflow - fix buffer overflow with corrupted images without image data - fix unable to read very small images (e.g. 1x1 px) - new test cases added - detect incomplete files by checking the end of streams as written in the specs --- autotests/read/qoi/1px.png | Bin 0 -> 551 bytes autotests/read/qoi/1px.qoi | Bin 0 -> 23 bytes autotests/read/qoi/2px.png | Bin 0 -> 561 bytes autotests/read/qoi/2px.qoi | Bin 0 -> 24 bytes autotests/read/qoi/bnm_rgb.png | Bin 0 -> 13611 bytes autotests/read/qoi/bnm_rgb.qoi | Bin 0 -> 16406 bytes autotests/read/qoi/bnm_rgba.png | Bin 0 -> 17782 bytes autotests/read/qoi/bnm_rgba.qoi | Bin 0 -> 20502 bytes src/imageformats/qoi.cpp | 25 +++++++++++++++++++++---- 9 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 autotests/read/qoi/1px.png create mode 100644 autotests/read/qoi/1px.qoi create mode 100644 autotests/read/qoi/2px.png create mode 100644 autotests/read/qoi/2px.qoi create mode 100644 autotests/read/qoi/bnm_rgb.png create mode 100644 autotests/read/qoi/bnm_rgb.qoi create mode 100644 autotests/read/qoi/bnm_rgba.png create mode 100644 autotests/read/qoi/bnm_rgba.qoi diff --git a/autotests/read/qoi/1px.png b/autotests/read/qoi/1px.png new file mode 100644 index 0000000000000000000000000000000000000000..01928c89d990c4874254c247fc6fbc46d5ddd3d1 GIT binary patch literal 551 zcmV+?0@(eDP))HmbgCOVu(Y8&iqBbGZf5$)xy_Y-Z zPyjR1Rcls1G+@K4~SZw z_q83ajAF__mxnwn>qeO@z7^Rh>w@>m9yu>%$QNY4!2^Y5^7=G3zL$alAE=M*C ze4GOVDPZUh=wEC2_V*rVk3eFR*L4dV90C*E?_TfV#hC3yoDP`mU4hE3LyQI_a)JKv z@A(Dbt8;WH6@PF5000SaNLh0L04^f{04^f|c%?sf00007bV*G`2j>V85hf>Oa0RIV p000k3L_t(|oB;#?`~Lv{|NjO40{$Ca&HexY002ovPDHLkV1o9E?sNbE literal 0 HcmV?d00001 diff --git a/autotests/read/qoi/1px.qoi b/autotests/read/qoi/1px.qoi new file mode 100644 index 0000000000000000000000000000000000000000..f3a3da5c5498c77e652206ce181b1fc643c40a21 GIT binary patch literal 23 XcmXTS&rD-rU|E5N99XN^L^ImIb|KQ@{|R+C%XFj zuWP-mtMi<9s*U%zw2JLfN zU)SyOZ=H*F>$EhQZ?(!`#zg0NJMC79hJ{LOz9M=~Y1JdXf7RJ(=}f(^&M92@ofSD> z*x^23!1~B*=Q~rc`ZvB4e-M@ZY-QXBv~d=AL;|BvPZ@+6E0)@q0R`DhJbhi+pK}NbYKY&_ xlIR8sNqV|ChE&X900004XF*Lt006OS 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 literal 0 HcmV?d00001 diff --git a/autotests/read/qoi/bnm_rgba.png b/autotests/read/qoi/bnm_rgba.png new file mode 100644 index 0000000000000000000000000000000000000000..41b1e5aebb8478b7ea19131879a9924ac03794b8 GIT binary patch literal 17782 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 N002ovPDHLkV1gT=ME?K) literal 0 HcmV?d00001 diff --git a/autotests/read/qoi/bnm_rgba.qoi b/autotests/read/qoi/bnm_rgba.qoi new file mode 100644 index 0000000000000000000000000000000000000000..35cdd4a362827e8187c7174e817334bd545d35a9 GIT binary patch literal 20502 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 literal 0 HcmV?d00001 diff --git a/src/imageformats/qoi.cpp b/src/imageformats/qoi.cpp index a7b5dd4..fae24eb 100644 --- a/src/imageformats/qoi.cpp +++ b/src/imageformats/qoi.cpp @@ -26,6 +26,7 @@ namespace // Private #define QOI_MAGIC (((unsigned int)'q') << 24 | ((unsigned int)'o') << 16 | ((unsigned int)'i') << 8 | ((unsigned int)'f')) #define QOI_HEADER_SIZE 14 +#define QOI_END_STREAM_PAD 8 struct QoiHeader { quint32 MagicNumber; @@ -62,6 +63,10 @@ static bool IsSupported(const QoiHeader &head) if (head.Width == 0 || head.Height == 0 || head.Channels < 3 || head.Colorspace > 1) { return false; } + // Set a reasonable upper limit + if (head.Width > 300000 || head.Height > 300000) { + return false; + } return true; } @@ -94,7 +99,12 @@ static bool LoadQOI(QIODevice *device, const QoiHeader &qoi, QImage &img) 255, }; - quint64 px_len = quint64(qoi.Width) * qoi.Channels * 3 / 2; + // The px_len should be enough to read a complete "compressed" row: an uncompressible row can become + // larger than the row itself. It should never be more than 1/3 (RGB) or 1/4 (RGBA) the length of the + // row itself (see test bnm_rgb*.qoi) so I set the extra data to 1/2. + // The minimum value is to ensure that enough bytes are read when the image is very small (e.g. 1x1px): + // it can be set as large as you like. + quint64 px_len = std::max(quint64(1024), quint64(qoi.Width) * qoi.Channels * 3 / 2); if (px_len > kMaxQVectorSize) { return false; } @@ -120,10 +130,14 @@ static bool LoadQOI(QIODevice *device, const QoiHeader &qoi, QImage &img) ba.append(device->read(px_len)); } - quint64 chunks_len = ba.size() - 8; // 8 is the size of the QOI padding + if (ba.size() < QOI_END_STREAM_PAD) { + return false; + } + + quint64 chunks_len = ba.size() - QOI_END_STREAM_PAD; quint64 p = 0; QRgb *scanline = (QRgb *)img.scanLine(y); - quint8 *input = reinterpret_cast(ba.data()); + const quint8 *input = reinterpret_cast(ba.constData()); for (quint32 x = 0; x < qoi.Width; ++x) { if (run > 0) { run--; @@ -165,7 +179,10 @@ static bool LoadQOI(QIODevice *device, const QoiHeader &qoi, QImage &img) } } - return true; + // From specs the byte stream's end is marked with 7 0x00 bytes followed by a single 0x01 byte. + // NOTE: Instead of using "ba == QByteArray::fromRawData("\x00\x00\x00\x00\x00\x00\x00\x01", 8)" + // we preferred a generic check that allows data to exist after the end of the file. + return (ba.startsWith(QByteArray::fromRawData("\x00\x00\x00\x00\x00\x00\x00\x01", 8))); } } // namespace