X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FC%2FCommon%2FDecompress.c;h=d85098f1314050945140d4f7c785e208dd30ecaf;hb=2e351cbe8e190271b3716284fc1076551d005472;hp=48578ea2f2d27bc0cca2ac08bcc993ed7844497f;hpb=97fa0ee9b1cffbb4b97ee35365afa7afcf50e174;p=mirror_edk2.git
diff --git a/BaseTools/Source/C/Common/Decompress.c b/BaseTools/Source/C/Common/Decompress.c
index 48578ea2f2..d85098f131 100644
--- a/BaseTools/Source/C/Common/Decompress.c
+++ b/BaseTools/Source/C/Common/Decompress.c
@@ -1,20 +1,15 @@
/** @file
-Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
+Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano
compress algorithm.
-Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
--*/
#include
#include
+#include
#include "Decompress.h"
//
@@ -88,11 +83,11 @@ Returns: (VOID)
--*/
{
- Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
+ Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
while (NumOfBits > Sd->mBitCount) {
- Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
+ Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
if (Sd->mCompSize > 0) {
//
@@ -193,12 +188,16 @@ Returns:
UINT16 Avail;
UINT16 NextCode;
UINT16 Mask;
+ UINT16 MaxTableLength;
for (Index = 1; Index <= 16; Index++) {
Count[Index] = 0;
}
for (Index = 0; Index < NumOfChar; Index++) {
+ if (BitLen[Index] > 16) {
+ return (UINT16) BAD_TABLE;
+ }
Count[BitLen[Index]]++;
}
@@ -236,11 +235,12 @@ Returns:
Avail = NumOfChar;
Mask = (UINT16) (1U << (15 - TableBits));
+ MaxTableLength = (UINT16) (1U << TableBits);
for (Char = 0; Char < NumOfChar; Char++) {
Len = BitLen[Char];
- if (Len == 0) {
+ if (Len == 0 || Len >= 17) {
continue;
}
@@ -248,6 +248,10 @@ Returns:
if (Len <= TableBits) {
+ if (Start[Len] >= NextCode || NextCode > MaxTableLength){
+ return (UINT16) BAD_TABLE;
+ }
+
for (Index = Start[Len]; Index < NextCode; Index++) {
Table[Index] = Char;
}
@@ -373,6 +377,8 @@ Returns:
UINT16 Index;
UINT32 Mask;
+ assert (nn <= NPT);
+
Number = (UINT16) GetBits (Sd, nbit);
if (Number == 0) {
@@ -391,7 +397,7 @@ Returns:
Index = 0;
- while (Index < Number) {
+ while (Index < Number && Index < NPT) {
CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));
@@ -410,14 +416,14 @@ Returns:
if (Index == Special) {
CharC = (UINT16) GetBits (Sd, 2);
CharC--;
- while ((INT16) (CharC) >= 0) {
+ while ((INT16) (CharC) >= 0 && Index < NPT) {
Sd->mPTLen[Index++] = 0;
CharC--;
}
}
}
- while (Index < nn) {
+ while (Index < nn && Index < NPT) {
Sd->mPTLen[Index++] = 0;
}
@@ -640,13 +646,23 @@ Returns: (VOID)
BytesRemain--;
while ((INT16) (BytesRemain) >= 0) {
- Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
if (Sd->mOutBuf >= Sd->mOrigSize) {
return ;
}
+ if (DataIdx >= Sd->mOrigSize) {
+ Sd->mBadTableFlag = (UINT16) BAD_TABLE;
+ return ;
+ }
+ Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
BytesRemain--;
}
+ //
+ // Once mOutBuf is fully filled, directly return
+ //
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ return ;
+ }
}
}
@@ -675,12 +691,13 @@ Arguments:
Returns:
- EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
{
UINT8 *Src;
+ UINT32 CompSize;
*ScratchSize = sizeof (SCRATCH_DATA);
@@ -689,7 +706,13 @@ Returns:
return EFI_INVALID_PARAMETER;
}
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
*DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+
+ if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+
return EFI_SUCCESS;
}
@@ -719,7 +742,7 @@ Arguments:
Returns:
- EFI_SUCCESS - Decompression is successfull
+ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
@@ -749,7 +772,7 @@ Returns:
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
- if (SrcSize < CompSize + 8) {
+ if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {
return EFI_INVALID_PARAMETER;
}
@@ -810,7 +833,7 @@ Arguments:
Returns:
- EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
@@ -840,7 +863,7 @@ Arguments:
Returns:
- EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
+ EFI_SUCCESS - The size of destination buffer and the size of scratch buffer are successfully retrieved.
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
@@ -874,7 +897,7 @@ Arguments:
Returns:
- EFI_SUCCESS - Decompression is successfull
+ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
@@ -909,7 +932,7 @@ Arguments:
Returns:
- EFI_SUCCESS - Decompression is successfull
+ EFI_SUCCESS - Decompression is successful
EFI_INVALID_PARAMETER - The source data is corrupted
--*/
@@ -931,7 +954,9 @@ Extract (
UINT32 ScratchSize;
EFI_STATUS Status;
- Status = EFI_SUCCESS;
+ Scratch = NULL;
+ Status = EFI_SUCCESS;
+
switch (Algorithm) {
case 0:
*Destination = (VOID *)malloc(SrcSize);
@@ -945,30 +970,44 @@ Extract (
Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);
if (Status == EFI_SUCCESS) {
Scratch = (VOID *)malloc(ScratchSize);
+ if (Scratch == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
*Destination = (VOID *)malloc(*DstSize);
- if (Scratch != NULL && *Destination != NULL) {
- Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
- } else {
- Status = EFI_OUT_OF_RESOURCES;
+ if (*Destination == NULL) {
+ free (Scratch);
+ return EFI_OUT_OF_RESOURCES;
}
+
+ Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
}
break;
case 2:
Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);
if (Status == EFI_SUCCESS) {
Scratch = (VOID *)malloc(ScratchSize);
+ if (Scratch == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
*Destination = (VOID *)malloc(*DstSize);
- if (Scratch != NULL && *Destination != NULL) {
- Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
- } else {
- Status = EFI_OUT_OF_RESOURCES;
+ if (*Destination == NULL) {
+ free (Scratch);
+ return EFI_OUT_OF_RESOURCES;
}
+
+ Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);
}
break;
default:
Status = EFI_INVALID_PARAMETER;
}
+ if (Scratch != NULL) {
+ free (Scratch);
+ }
+
return Status;
}