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; }