CVE-2022-31796: Out-of-bounds Read (CWE-125)
value: libjpeg 1.63 has a heap-based buffer over-read in HierarchicalBitmapRequester::FetchRegion in hierarchicalbitmaprequester.cpp because the MCU size can be different between allocation and use.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 6.5
Published: 2022-06-02T14:15Z
Repository: https://github.com/thorfdbg/libjpeg
Language: Other
Files changed: README, README.history, control/hierarchicalbitmaprequester.cpp
Commit date: 2022-05-24 07:44:38 +0200
Commit message: The code now checks for consistency of the MCU sizes across
hierarchical levels, and fails in case they are different.

Diff: diff --git a/README b/README
index 40ef320..124c958 100644
--- a/README
+++ b/README
@@ -458,10 +458,12 @@ The lossless scan, the arithmetically coded lossless scan and the
 arithmetically coded sequential scan could run into cases where an
 out-of-bounds symbol triggered and out-of-bounds array access and could
 have crashed the decoder. The code is now more carefully changing the
 validity of the symbols and aborts with an error if it finds illegal
 codes.
+The code now also checks the consistency of the MCU sizes in the
+hierarchical process and fails if they differ across levels.
 
 --------------------------------------------------------------------------
 
 For license conditions, please check the file README.license in this
 directory.
diff --git a/README.history b/README.history
index 672d08d..09f0d87 100644
--- a/README.history
+++ b/README.history
@@ -562,7 +562,9 @@ The lossless scan, the arithmetically coded lossless scan and the
 arithmetically coded sequential scan could run into cases where an
 out-of-bounds symbol triggered and out-of-bounds array access and could
 have crashed the decoder. The code is now more carefully changing the
 validity of the symbols and aborts with an error if it finds illegal
 codes.
+The code now also checks the consistency of the MCU sizes in the
+hierarchical process and fails if they differ across levels.
 
 --------------------------------------------------------------------------
diff --git a/control/hierarchicalbitmaprequester.cpp b/control/hierarchicalbitmaprequester.cpp
index 14aefd1..bc636f6 100644
--- a/control/hierarchicalbitmaprequester.cpp
+++ b/control/hierarchicalbitmaprequester.cpp
@@ -43,11 +43,11 @@
 ** This is the top-level bitmap requester that distributes data to
 ** image scales on encoding, and collects data from image scales on
 ** decoding. It also keeps the top-level color transformer and the
 ** toplevel subsampling expander.
 **
-** $Id: hierarchicalbitmaprequester.cpp,v 1.42 2020/04/08 10:05:41 thor Exp $
+** $Id: hierarchicalbitmaprequester.cpp,v 1.43 2022/05/24 05:42:35 thor Exp $
 **
 */
 
 /// Includes
 #include "control/hierarchicalbitmaprequester.hpp"
@@ -243,10 +243,20 @@ void HierarchicalBitmapRequester::PrepareForDecoding(void)
     for(i = 0;i < m_ucCount;i++) {
       class Component *comp = m_pFrame->ComponentOf(i);
       UBYTE sx = comp->SubXOf();
       UBYTE sy = comp->SubYOf();
 
+      if (m_pLargestScale) {
+        class Frame *frame = m_pLargestScale->FrameOf();
+        while(frame) {
+          if (frame->ComponentOf(i)->SubXOf() != sx || frame->ComponentOf(i)->SubYOf() != sy)
+            JPG_THROW(MALFORMED_STREAM,"HierarchicalBitmapRequester::PrepareForDecoding",
+                      "component subsampling is inconsistent across hierarchical levels");
+          frame = frame->NextOf();
+        }
+      }
+
       if (sx > 1 || sy > 1) {
         m_ppUpsampler[i] = UpsamplerBase::CreateUpsampler(m_pEnviron,sx,sy,
                                                           m_ulPixelWidth,m_ulPixelHeight,
                                                           m_pFrame->TablesOf()->isChromaCentered());
         m_bSubsampling   = true;

Vulnerable code: ** $Id: hierarchicalbitmaprequester.cpp,v 1.42 2020/04/08 10:05:41 thor Exp $
Fixed code: The code now also checks the consistency of the MCU sizes in the
hierarchical process and fails if they differ across levels.
The code now also checks the consistency of the MCU sizes in the
hierarchical process and fails if they differ across levels.
** $Id: hierarchicalbitmaprequester.cpp,v 1.43 2022/05/24 05:42:35 thor Exp $
      if (m_pLargestScale) {
        class Frame *frame = m_pLargestScale->FrameOf();
        while(frame) {
          if (frame->ComponentOf(i)->SubXOf() != sx || frame->ComponentOf(i)->SubYOf() != sy)
            JPG_THROW(MALFORMED_STREAM,"HierarchicalBitmapRequester::PrepareForDecoding",
                      "component subsampling is inconsistent across hierarchical levels");
          frame = frame->NextOf();
        }
      }