You've already forked slimbootloader
mirror of
https://github.com/Dasharo/slimbootloader.git
synced 2026-03-06 15:26:20 -08:00
Resolved below issues. Untrusted pointer read(CWE 129) Operands don't affect result(CWE 569) Unchecked return value(CWE 252) Logically dead code(CWE 561) Unused value(CWE 563) Unintended sign extension(CWE 194) Out-of-bounds access(CWE 119) Signed-off-by: Kevin Tsai <kevin.tsai@intel.com>
353 lines
9.3 KiB
C
353 lines
9.3 KiB
C
/** @file
|
|
The driver internal functions are implmented here.
|
|
They build Pei PCD database, and provide access service to PCD database.
|
|
|
|
Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include "Service.h"
|
|
|
|
/**
|
|
Get Local Token Number by Token Number.
|
|
|
|
@param[in] Database PCD database.
|
|
@param[in] TokenNumber The PCD token number.
|
|
|
|
@return Local Token Number.
|
|
**/
|
|
UINT32
|
|
GetLocalTokenNumber (
|
|
IN PEI_PCD_DATABASE *Database,
|
|
IN UINTN TokenNumber
|
|
)
|
|
{
|
|
UINT32 LocalTokenNumber;
|
|
|
|
//
|
|
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
|
|
// We have to decrement TokenNumber by 1 to make it usable
|
|
// as the array index.
|
|
//
|
|
TokenNumber--;
|
|
|
|
LocalTokenNumber = * ((UINT32 *) ((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + TokenNumber);
|
|
|
|
return LocalTokenNumber;
|
|
}
|
|
|
|
/**
|
|
Get PCD type by Local Token Number.
|
|
|
|
@param[in] LocalTokenNumber The PCD local token number.
|
|
|
|
@return PCD type.
|
|
**/
|
|
EFI_PCD_TYPE
|
|
GetPcdType (
|
|
IN UINT32 LocalTokenNumber
|
|
)
|
|
{
|
|
switch (LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) {
|
|
case PCD_DATUM_TYPE_POINTER:
|
|
return EFI_PCD_TYPE_PTR;
|
|
case PCD_DATUM_TYPE_UINT8:
|
|
if ((LocalTokenNumber & PCD_DATUM_TYPE_UINT8_BOOLEAN) == PCD_DATUM_TYPE_UINT8_BOOLEAN) {
|
|
return EFI_PCD_TYPE_BOOL;
|
|
} else {
|
|
return EFI_PCD_TYPE_8;
|
|
}
|
|
case PCD_DATUM_TYPE_UINT16:
|
|
return EFI_PCD_TYPE_16;
|
|
case PCD_DATUM_TYPE_UINT32:
|
|
return EFI_PCD_TYPE_32;
|
|
case PCD_DATUM_TYPE_UINT64:
|
|
return EFI_PCD_TYPE_64;
|
|
default:
|
|
ASSERT (FALSE);
|
|
return EFI_PCD_TYPE_8;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Wrapper function for setting non-pointer type value for a PCD entry.
|
|
|
|
@param TokenNumber Pcd token number autogenerated by build tools.
|
|
@param Data Value want to be set for PCD entry
|
|
@param Size Size of value.
|
|
|
|
@return status of SetWorker.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SetValueWorker (
|
|
IN UINTN TokenNumber,
|
|
IN VOID *Data,
|
|
IN UINTN Size
|
|
)
|
|
{
|
|
return SetWorker (TokenNumber, Data, &Size, FALSE);
|
|
}
|
|
|
|
/**
|
|
Set value for an PCD entry
|
|
|
|
@param TokenNumber Pcd token number autogenerated by build tools.
|
|
@param Data Value want to be set for PCD entry
|
|
@param Size Size of value.
|
|
@param PtrType If TRUE, the type of PCD entry's value is Pointer.
|
|
If False, the type of PCD entry's value is not Pointer.
|
|
|
|
@retval EFI_INVALID_PARAMETER If this PCD type is VPD, VPD PCD can not be set.
|
|
@retval EFI_INVALID_PARAMETER If Size can not be set to size table.
|
|
@retval EFI_INVALID_PARAMETER If Size of non-Ptr type PCD does not match the size information in PCD database.
|
|
@retval EFI_NOT_FOUND If value type of PCD entry is intergrate, but not in
|
|
range of UINT8, UINT16, UINT32, UINT64
|
|
@retval EFI_NOT_FOUND Can not find the PCD type according to token number.
|
|
**/
|
|
EFI_STATUS
|
|
SetWorker (
|
|
IN UINTN TokenNumber,
|
|
IN VOID *Data,
|
|
IN OUT UINTN *Size,
|
|
IN BOOLEAN PtrType
|
|
)
|
|
{
|
|
UINT32 LocalTokenNumber;
|
|
PEI_PCD_DATABASE *PeiPcdDb;
|
|
STRING_HEAD StringTableIdx;
|
|
UINTN Offset;
|
|
VOID *InternalData;
|
|
UINTN MaxSize;
|
|
UINT32 LocalTokenCount;
|
|
|
|
//
|
|
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
|
|
// We have to decrement TokenNumber by 1 to make it usable
|
|
// as the array index.
|
|
//
|
|
TokenNumber--;
|
|
PeiPcdDb = GetPcdDatabase ();
|
|
LocalTokenCount = PeiPcdDb->LocalTokenCount;
|
|
|
|
// EBC compiler is very choosy. It may report warning about comparison
|
|
// between UINTN and 0 . So we add 1 in each size of the
|
|
// comparison.
|
|
ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
|
|
|
|
if (PtrType) {
|
|
//
|
|
// Get MaxSize first, then check new size with max buffer size.
|
|
//
|
|
GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb);
|
|
if (*Size > MaxSize) {
|
|
*Size = MaxSize;
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
} else {
|
|
if (*Size != PeiPcdGetSize (TokenNumber + 1)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We only invoke the callback function for Dynamic Type PCD Entry.
|
|
// For Dynamic EX PCD entry, we have invoked the callback function for Dynamic EX
|
|
// type PCD entry in ExSetWorker.
|
|
//
|
|
LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
|
|
|
|
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
|
|
InternalData = (VOID *) ((UINT8 *) PeiPcdDb + Offset);
|
|
|
|
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
|
|
case PCD_TYPE_VPD:
|
|
case PCD_TYPE_HII:
|
|
case PCD_TYPE_HII|PCD_TYPE_STRING: {
|
|
ASSERT (FALSE);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
case PCD_TYPE_STRING:
|
|
if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
|
|
StringTableIdx = * ((STRING_HEAD *)InternalData);
|
|
CopyMem ((UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset + StringTableIdx, Data, *Size);
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
case PCD_TYPE_DATA: {
|
|
if (PtrType) {
|
|
if (SetPtrTypeSize (TokenNumber, Size, PeiPcdDb)) {
|
|
CopyMem (InternalData, Data, *Size);
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
switch (*Size) {
|
|
case sizeof (UINT8):
|
|
* ((UINT8 *) InternalData) = * ((UINT8 *) Data);
|
|
return EFI_SUCCESS;
|
|
|
|
case sizeof (UINT16):
|
|
* ((UINT16 *) InternalData) = * ((UINT16 *) Data);
|
|
return EFI_SUCCESS;
|
|
|
|
case sizeof (UINT32):
|
|
* ((UINT32 *) InternalData) = * ((UINT32 *) Data);
|
|
return EFI_SUCCESS;
|
|
|
|
case sizeof (UINT64):
|
|
* ((UINT64 *) InternalData) = * ((UINT64 *) Data);
|
|
return EFI_SUCCESS;
|
|
|
|
default:
|
|
ASSERT (FALSE);
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
ASSERT (FALSE);
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
/**
|
|
Get the PCD entry pointer in PCD database.
|
|
|
|
This routine will visit PCD database to find the PCD entry according to given
|
|
token number. The given token number is autogened by build tools and it will be
|
|
translated to local token number. Local token number contains PCD's type and
|
|
offset of PCD entry in PCD database.
|
|
|
|
@param TokenNumber Token's number, it is autogened by build tools
|
|
@param GetSize The size of token's value
|
|
|
|
@return PCD entry pointer in PCD database
|
|
|
|
**/
|
|
VOID *
|
|
GetWorker (
|
|
IN UINTN TokenNumber,
|
|
IN UINTN GetSize
|
|
)
|
|
{
|
|
UINT32 Offset;
|
|
UINT8 *StringTable;
|
|
STRING_HEAD StringTableIdx;
|
|
PEI_PCD_DATABASE *PeiPcdDb;
|
|
UINT32 LocalTokenNumber;
|
|
UINT32 LocalTokenCount;
|
|
|
|
//
|
|
// TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER.
|
|
// We have to decrement TokenNumber by 1 to make it usable
|
|
// as the array index.
|
|
//
|
|
TokenNumber--;
|
|
|
|
PeiPcdDb = GetPcdDatabase ();
|
|
LocalTokenCount = PeiPcdDb->LocalTokenCount;
|
|
|
|
// EBC compiler is very choosy. It may report warning about comparison
|
|
// between UINTN and 0 . So we add 1 in each size of the
|
|
// comparison.
|
|
ASSERT (TokenNumber + 1 < (LocalTokenCount + 1));
|
|
|
|
ASSERT ((GetSize == PeiPcdGetSize (TokenNumber + 1)) || (GetSize == 0));
|
|
|
|
LocalTokenNumber = GetLocalTokenNumber (PeiPcdDb, TokenNumber + 1);
|
|
|
|
Offset = LocalTokenNumber & PCD_DATABASE_OFFSET_MASK;
|
|
StringTable = (UINT8 *)PeiPcdDb + PeiPcdDb->StringTableOffset;
|
|
|
|
switch (LocalTokenNumber & PCD_TYPE_ALL_SET) {
|
|
case PCD_TYPE_DATA:
|
|
return (VOID *) ((UINT8 *)PeiPcdDb + Offset);
|
|
|
|
case PCD_TYPE_STRING:
|
|
StringTableIdx = * (STRING_HEAD *) ((UINT8 *) PeiPcdDb + Offset);
|
|
return (VOID *) (StringTable + StringTableIdx);
|
|
|
|
default:
|
|
ASSERT (FALSE);
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
/**
|
|
Get PCD database from GUID HOB in PEI phase.
|
|
|
|
@return Pointer to PCD database.
|
|
|
|
**/
|
|
PEI_PCD_DATABASE *
|
|
GetPcdDatabase (
|
|
VOID
|
|
)
|
|
{
|
|
return (PEI_PCD_DATABASE *) GetPcdDataPtr ();
|
|
}
|
|
|
|
/**
|
|
Get index of PCD entry in size table.
|
|
|
|
@param LocalTokenNumberTableIdx Index of this PCD in local token number table.
|
|
@param Database Pointer to PCD database in PEI phase.
|
|
|
|
@return index of PCD entry in size table.
|
|
|
|
**/
|
|
UINTN
|
|
GetSizeTableIndex (
|
|
IN UINTN LocalTokenNumberTableIdx,
|
|
IN PEI_PCD_DATABASE *Database
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN SizeTableIdx;
|
|
UINTN LocalTokenNumber;
|
|
|
|
SizeTableIdx = 0;
|
|
|
|
for (Index = 0; Index < LocalTokenNumberTableIdx; Index++) {
|
|
LocalTokenNumber = * ((UINT32 *) ((UINT8 *)Database + Database->LocalTokenNumberTableOffset) + Index);
|
|
|
|
if ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) == PCD_DATUM_TYPE_POINTER) {
|
|
//
|
|
// SizeTable only contain record for PCD_DATUM_TYPE_POINTER type
|
|
// PCD entry.
|
|
//
|
|
if ((LocalTokenNumber & PCD_TYPE_VPD) != 0) {
|
|
//
|
|
// We have only two entry for VPD enabled PCD entry:
|
|
// 1) MAX Size.
|
|
// 2) Current Size
|
|
// Current size is equal to MAX size.
|
|
//
|
|
SizeTableIdx += 2;
|
|
} else {
|
|
//
|
|
// We have only two entry for Non-Sku enabled PCD entry:
|
|
// 1) MAX SIZE
|
|
// 2) Current Size
|
|
//
|
|
SizeTableIdx += 2;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return SizeTableIdx;
|
|
}
|