Blame SOURCES/ovmf-BaseTools-Add-more-checker-in-Decompress-algorithm-t.patch

3c2ede
From 87af8da054900fd05701c6d60a496b83fb8dbb63 Mon Sep 17 00:00:00 2001
3c2ede
From: Philippe Mathieu-Daude <philmd@redhat.com>
3c2ede
Date: Wed, 13 Feb 2019 09:50:47 +0100
3c2ede
Subject: [PATCH 04/13] BaseTools: Add more checker in Decompress algorithm to
3c2ede
 access the valid buffer (CVE FIX)
3c2ede
3c2ede
Message-id: <20190213085050.20766-5-philmd@redhat.com>
3c2ede
Patchwork-id: 84481
3c2ede
O-Subject:  [RHEL-7.7 ovmf PATCH v3 4/7] BaseTools: Add more checker in
3c2ede
	Decompress algorithm to access the valid buffer (CVE FIX)
3c2ede
Bugzilla: 1666586
3c2ede
Acked-by: Laszlo Ersek <lersek@redhat.com>
3c2ede
Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
3c2ede
3c2ede
From: Laszlo Ersek <lersek@redhat.com>
3c2ede
3c2ede
From: Liming Gao <liming.gao@intel.com>
3c2ede
3c2ede
--v-- RHEL7 note start --v--
3c2ede
3c2ede
Unfortunately, the upstream patch series was not structured according to
3c2ede
the CVE reports. This patch contributes to fixing:
3c2ede
3c2ede
- CVE-2017-5731
3c2ede
- CVE-2017-5733
3c2ede
- CVE-2017-5734
3c2ede
- CVE-2017-5735
3c2ede
3c2ede
but not CVE-2017-5732 (contrarily to the upstream commit message). The
3c2ede
best I could achieve up-stream was to get the "CVE FIX" expression into
3c2ede
the subject, and a whole-sale dump of the CVEs into the body. I had not
3c2ede
been invited to the original (off-list, embargoed) analysis and review.
3c2ede
3c2ede
The differences that "git-backport-diff" reports as "functional" for this
3c2ede
backport aren't actually functional differences. They are due to
3c2ede
downstream lacking two upstream commits:
3c2ede
3c2ede
- f7496d717357 ("BaseTools: Clean up source files", 2018-07-09), with the
3c2ede
  "usual" diffstat "289 files changed, 10645 insertions(+), 10645
3c2ede
  deletions(-)";
3c2ede
3c2ede
- more importantly, 472eb3b89682 ("BaseTools: Add --uefi option to enable
3c2ede
  UefiCompress method", 2018-10-13).
3c2ede
3c2ede
(Side note: in upstream, commit 472eb3b89682 was incorrectly reverted as
3c2ede
part of 1ccc4d895dd8 ("Revert BaseTools: PYTHON3 migration", 2018-10-15),
3c2ede
but then it was re-applied in f1400101a732.)
3c2ede
3c2ede
In commit 472eb3b89682, the "UEFI" compression/decompression method was
3c2ede
added to BaseTools, beyond the original "Tiano" method. This caused the
3c2ede
Tiano method to be indented more deeply, in the main() function of
3c2ede
"TianoCompress.c". (Also the original Decompress() function was renamed to
3c2ede
TDecompress().) The CVE fix applies to the "Tiano" method, which RHEL8
3c2ede
does have, but at a different nesting level. Therefore the changes have
3c2ede
been backported manually, and the difference in indentation is also why
3c2ede
"git-backport-diff" thinks the changes are functional.
3c2ede
3c2ede
This backport, once applied, can be diffed against the upstream tree more
3c2ede
easily as follows:
3c2ede
3c2ede
  git diff -b HEAD..041d89bc0f01 -- \
3c2ede
    BaseTools/Source/C/Common/Decompress.c \
3c2ede
    BaseTools/Source/C/TianoCompress/TianoCompress.c
3c2ede
3c2ede
--^-- RHEL7 note end --^--
3c2ede
3c2ede
Fix CVE-2017-5731,CVE-2017-5732,CVE-2017-5733,CVE-2017-5734,CVE-2017-5735
3c2ede
https://bugzilla.tianocore.org/show_bug.cgi?id=686
3c2ede
3c2ede
Contributed-under: TianoCore Contribution Agreement 1.1
3c2ede
Signed-off-by: Holtsclaw Brent <brent.holtsclaw@intel.com>
3c2ede
Signed-off-by: Liming Gao <liming.gao@intel.com>
3c2ede
Reviewed-by: Star Zeng <star.zeng@intel.com>
3c2ede
Acked-by: Laszlo Ersek <lersek@redhat.com>
3c2ede
(cherry picked from commit 041d89bc0f0119df37a5fce1d0f16495ff905089)
3c2ede
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
3c2ede
(cherry picked from commit 29c394f110b1f769e629e8775874261e33d4abd9)
3c2ede
Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com>
3c2ede
---
3c2ede
 BaseTools/Source/C/Common/Decompress.c           | 23 +++++++++++++++++++--
3c2ede
 BaseTools/Source/C/TianoCompress/TianoCompress.c | 26 +++++++++++++++++++++++-
3c2ede
 2 files changed, 46 insertions(+), 3 deletions(-)
3c2ede
3c2ede
diff --git a/BaseTools/Source/C/Common/Decompress.c b/BaseTools/Source/C/Common/Decompress.c
3c2ede
index 8f1afb4..bdc10f5 100644
3c2ede
--- a/BaseTools/Source/C/Common/Decompress.c
3c2ede
+++ b/BaseTools/Source/C/Common/Decompress.c
3c2ede
@@ -194,12 +194,16 @@ Returns:
3c2ede
   UINT16  Avail;
3c2ede
   UINT16  NextCode;
3c2ede
   UINT16  Mask;
3c2ede
+  UINT16  MaxTableLength;
3c2ede
 
3c2ede
   for (Index = 1; Index <= 16; Index++) {
3c2ede
     Count[Index] = 0;
3c2ede
   }
3c2ede
 
3c2ede
   for (Index = 0; Index < NumOfChar; Index++) {
3c2ede
+    if (BitLen[Index] > 16) {
3c2ede
+      return (UINT16) BAD_TABLE;
3c2ede
+    }
3c2ede
     Count[BitLen[Index]]++;
3c2ede
   }
3c2ede
 
3c2ede
@@ -237,6 +241,7 @@ Returns:
3c2ede
 
3c2ede
   Avail = NumOfChar;
3c2ede
   Mask  = (UINT16) (1U << (15 - TableBits));
3c2ede
+  MaxTableLength = (UINT16) (1U << TableBits);
3c2ede
 
3c2ede
   for (Char = 0; Char < NumOfChar; Char++) {
3c2ede
 
3c2ede
@@ -250,6 +255,9 @@ Returns:
3c2ede
     if (Len <= TableBits) {
3c2ede
 
3c2ede
       for (Index = Start[Len]; Index < NextCode; Index++) {
3c2ede
+        if (Index >= MaxTableLength) {
3c2ede
+          return (UINT16) BAD_TABLE;
3c2ede
+        }
3c2ede
         Table[Index] = Char;
3c2ede
       }
3c2ede
 
3c2ede
@@ -643,10 +651,14 @@ Returns: (VOID)
3c2ede
 
3c2ede
       BytesRemain--;
3c2ede
       while ((INT16) (BytesRemain) >= 0) {
3c2ede
-        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
3c2ede
         if (Sd->mOutBuf >= Sd->mOrigSize) {
3c2ede
           return ;
3c2ede
         }
3c2ede
+        if (DataIdx >= Sd->mOrigSize) {
3c2ede
+          Sd->mBadTableFlag = (UINT16) BAD_TABLE;
3c2ede
+          return ;
3c2ede
+        }
3c2ede
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
3c2ede
 
3c2ede
         BytesRemain--;
3c2ede
       }
3c2ede
@@ -684,6 +696,7 @@ Returns:
3c2ede
 --*/
3c2ede
 {
3c2ede
   UINT8 *Src;
3c2ede
+  UINT32 CompSize;
3c2ede
 
3c2ede
   *ScratchSize  = sizeof (SCRATCH_DATA);
3c2ede
 
3c2ede
@@ -692,7 +705,13 @@ Returns:
3c2ede
     return EFI_INVALID_PARAMETER;
3c2ede
   }
3c2ede
 
3c2ede
+  CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
3c2ede
   *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
3c2ede
+
3c2ede
+  if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
3c2ede
+    return EFI_INVALID_PARAMETER;
3c2ede
+  }
3c2ede
+
3c2ede
   return EFI_SUCCESS;
3c2ede
 }
3c2ede
 
3c2ede
@@ -752,7 +771,7 @@ Returns:
3c2ede
   CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
3c2ede
   OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
3c2ede
 
3c2ede
-  if (SrcSize < CompSize + 8) {
3c2ede
+  if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
3c2ede
     return EFI_INVALID_PARAMETER;
3c2ede
   }
3c2ede
 
3c2ede
diff --git a/BaseTools/Source/C/TianoCompress/TianoCompress.c b/BaseTools/Source/C/TianoCompress/TianoCompress.c
3c2ede
index 046fb36..d07fd9e 100644
3c2ede
--- a/BaseTools/Source/C/TianoCompress/TianoCompress.c
3c2ede
+++ b/BaseTools/Source/C/TianoCompress/TianoCompress.c
3c2ede
@@ -1753,6 +1753,7 @@ Returns:
3c2ede
   SCRATCH_DATA      *Scratch;
3c2ede
   UINT8      *Src;
3c2ede
   UINT32     OrigSize;
3c2ede
+  UINT32     CompSize;
3c2ede
 
3c2ede
   SetUtilityName(UTILITY_NAME);
3c2ede
   
3c2ede
@@ -1761,6 +1762,7 @@ Returns:
3c2ede
   OutBuffer = NULL;
3c2ede
   Scratch   = NULL;
3c2ede
   OrigSize = 0;
3c2ede
+  CompSize = 0;
3c2ede
   InputLength = 0;
3c2ede
   InputFileName = NULL;
3c2ede
   OutputFileName = NULL;
3c2ede
@@ -1979,15 +1981,24 @@ Returns:
3c2ede
   if (DebugMode) {
3c2ede
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);
3c2ede
   }
3c2ede
+  if (InputLength < 8){
3c2ede
+    Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);
3c2ede
+    goto ERROR;
3c2ede
+  }
3c2ede
   //
3c2ede
   // Get Compressed file original size
3c2ede
   // 
3c2ede
   Src     = (UINT8 *)FileBuffer;                     
3c2ede
   OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);  
3c2ede
+  CompSize  = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);
3c2ede
   
3c2ede
   //
3c2ede
   // Allocate OutputBuffer
3c2ede
   //
3c2ede
+  if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {
3c2ede
+    Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);
3c2ede
+    goto ERROR;
3c2ede
+  }
3c2ede
   OutBuffer = (UINT8 *)malloc(OrigSize);
3c2ede
   if (OutBuffer == NULL) {
3c2ede
     Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
3c2ede
@@ -2171,12 +2182,16 @@ Returns:
3c2ede
   UINT16  Mask;
3c2ede
   UINT16  WordOfStart;
3c2ede
   UINT16  WordOfCount;
3c2ede
+  UINT16  MaxTableLength;
3c2ede
 
3c2ede
   for (Index = 0; Index <= 16; Index++) {
3c2ede
     Count[Index] = 0;
3c2ede
   }
3c2ede
 
3c2ede
   for (Index = 0; Index < NumOfChar; Index++) {
3c2ede
+    if (BitLen[Index] > 16) {
3c2ede
+      return (UINT16) BAD_TABLE;
3c2ede
+    }
3c2ede
     Count[BitLen[Index]]++;
3c2ede
   }
3c2ede
 
3c2ede
@@ -2220,6 +2235,7 @@ Returns:
3c2ede
 
3c2ede
   Avail = NumOfChar;
3c2ede
   Mask  = (UINT16) (1U << (15 - TableBits));
3c2ede
+  MaxTableLength = (UINT16) (1U << TableBits);
3c2ede
 
3c2ede
   for (Char = 0; Char < NumOfChar; Char++) {
3c2ede
 
3c2ede
@@ -2233,6 +2249,9 @@ Returns:
3c2ede
     if (Len <= TableBits) {
3c2ede
 
3c2ede
       for (Index = Start[Len]; Index < NextCode; Index++) {
3c2ede
+        if (Index >= MaxTableLength) {
3c2ede
+          return (UINT16) BAD_TABLE;
3c2ede
+        }
3c2ede
         Table[Index] = Char;
3c2ede
       }
3c2ede
 
3c2ede
@@ -2617,11 +2636,16 @@ Returns: (VOID)
3c2ede
       DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;
3c2ede
 
3c2ede
       BytesRemain--;
3c2ede
+
3c2ede
       while ((INT16) (BytesRemain) >= 0) {
3c2ede
-        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
3c2ede
         if (Sd->mOutBuf >= Sd->mOrigSize) {
3c2ede
           goto Done ;
3c2ede
         }
3c2ede
+        if (DataIdx >= Sd->mOrigSize) {
3c2ede
+          Sd->mBadTableFlag = (UINT16) BAD_TABLE;
3c2ede
+          goto Done ;
3c2ede
+        }
3c2ede
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
3c2ede
 
3c2ede
         BytesRemain--;
3c2ede
       }
3c2ede
-- 
3c2ede
1.8.3.1
3c2ede