The LzmaUefiDecompressGetInfo() function [MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c] currently silently truncates the UINT64 "DecodedSize" property of the compressed blob to the UINT32 "DestinationSize" output parameter. If "DecodedSize" is 0x1_0000_0100, for example, then the subsequent memory allocation (for decompression) will likely succeed (allocating 0x100 bytes only), but then the LzmaUefiDecompress() function (which re-fetches the uncompressed buffer size from the same LZMA header into a "SizeT" variable) will overwrite the buffer. Catch (DecodedSize > MAX_UINT32) in LzmaUefiDecompressGetInfo() at once. This should not be a practical limitation. (The issue cannot be fixed for 32-bit systems without spec modifications anyway, given that the "OutputSize" output parameter of EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL.ExtractSection() has type UINTN, not UINT64.) Cc: Dandan Bi <dandan.bi@intel.com> Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1816 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-Id: <20201119115034.12897-2-lersek@redhat.com>
		
			
				
	
	
		
			96 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  LZMA Decompress Library internal header file declares Lzma decompress interfaces.
 | 
						|
 | 
						|
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#ifndef __LZMADECOMPRESSLIB_INTERNAL_H__
 | 
						|
#define __LZMADECOMPRESSLIB_INTERNAL_H__
 | 
						|
 | 
						|
#include <Base.h>
 | 
						|
#include <PiPei.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/ExtractGuidedSectionLib.h>
 | 
						|
#include <Guid/LzmaDecompress.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Given a Lzma compressed source buffer, this function retrieves the size of
 | 
						|
  the uncompressed buffer and the size of the scratch buffer required
 | 
						|
  to decompress the compressed source buffer.
 | 
						|
 | 
						|
  Retrieves the size of the uncompressed buffer and the temporary scratch buffer
 | 
						|
  required to decompress the buffer specified by Source and SourceSize.
 | 
						|
  The size of the uncompressed buffer is returned in DestinationSize,
 | 
						|
  the size of the scratch buffer is returned in ScratchSize, and RETURN_SUCCESS is returned.
 | 
						|
  This function does not have scratch buffer available to perform a thorough
 | 
						|
  checking of the validity of the source data. It just retrieves the "Original Size"
 | 
						|
  field from the LZMA_HEADER_SIZE beginning bytes of the source data and output it as DestinationSize.
 | 
						|
  And ScratchSize is specific to the decompression implementation.
 | 
						|
 | 
						|
  If SourceSize is less than LZMA_HEADER_SIZE, then ASSERT().
 | 
						|
 | 
						|
  @param  Source          The source buffer containing the compressed data.
 | 
						|
  @param  SourceSize      The size, in bytes, of the source buffer.
 | 
						|
  @param  DestinationSize A pointer to the size, in bytes, of the uncompressed buffer
 | 
						|
                          that will be generated when the compressed buffer specified
 | 
						|
                          by Source and SourceSize is decompressed.
 | 
						|
  @param  ScratchSize     A pointer to the size, in bytes, of the scratch buffer that
 | 
						|
                          is required to decompress the compressed buffer specified
 | 
						|
                          by Source and SourceSize.
 | 
						|
 | 
						|
  @retval  RETURN_SUCCESS The size of the uncompressed data was returned
 | 
						|
                          in DestinationSize and the size of the scratch
 | 
						|
                          buffer was returned in ScratchSize.
 | 
						|
 | 
						|
  @retval RETURN_UNSUPPORTED  DestinationSize cannot be output because the
 | 
						|
                              uncompressed buffer size (in bytes) does not fit
 | 
						|
                              in a UINT32. Output parameters have not been
 | 
						|
                              modified.
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
LzmaUefiDecompressGetInfo (
 | 
						|
  IN  CONST VOID  *Source,
 | 
						|
  IN  UINT32      SourceSize,
 | 
						|
  OUT UINT32      *DestinationSize,
 | 
						|
  OUT UINT32      *ScratchSize
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Decompresses a Lzma compressed source buffer.
 | 
						|
 | 
						|
  Extracts decompressed data to its original form.
 | 
						|
  If the compressed source data specified by Source is successfully decompressed
 | 
						|
  into Destination, then RETURN_SUCCESS is returned.  If the compressed source data
 | 
						|
  specified by Source is not in a valid compressed data format,
 | 
						|
  then RETURN_INVALID_PARAMETER is returned.
 | 
						|
 | 
						|
  @param  Source      The source buffer containing the compressed data.
 | 
						|
  @param  SourceSize  The size of source buffer.
 | 
						|
  @param  Destination The destination buffer to store the decompressed data
 | 
						|
  @param  Scratch     A temporary scratch buffer that is used to perform the decompression.
 | 
						|
                      This is an optional parameter that may be NULL if the
 | 
						|
                      required scratch buffer size is 0.
 | 
						|
 | 
						|
  @retval  RETURN_SUCCESS Decompression completed successfully, and
 | 
						|
                          the uncompressed buffer is returned in Destination.
 | 
						|
  @retval  RETURN_INVALID_PARAMETER
 | 
						|
                          The source buffer specified by Source is corrupted
 | 
						|
                          (not in a valid compressed format).
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
LzmaUefiDecompress (
 | 
						|
  IN CONST VOID  *Source,
 | 
						|
  IN UINTN       SourceSize,
 | 
						|
  IN OUT VOID    *Destination,
 | 
						|
  IN OUT VOID    *Scratch
 | 
						|
  );
 | 
						|
 | 
						|
#endif
 | 
						|
 |