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

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