TianoCore EDK2 master
Loading...
Searching...
No Matches
DxeTpmMeasureBootLibSanitization.c
Go to the documentation of this file.
1
24#include <Uefi.h>
25#include <Uefi/UefiSpec.h>
26#include <Library/SafeIntLib.h>
27#include <Library/UefiLib.h>
28#include <Library/DebugLib.h>
29#include <Library/BaseLib.h>
31#include <Protocol/BlockIo.h>
33
35
36#define GPT_HEADER_REVISION_V1 0x00010000
37
65EFIAPI
67 IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
69 )
70{
71 // Verify that the input parameters are safe to use
72 if (PrimaryHeader == NULL) {
73 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n"));
74 return EFI_INVALID_PARAMETER;
75 }
76
77 if ((BlockIo == NULL) || (BlockIo->Media == NULL)) {
78 DEBUG ((DEBUG_ERROR, "Invalid BlockIo!\n"));
79 return EFI_INVALID_PARAMETER;
80 }
81
82 // The signature must be EFI_PTAB_HEADER_ID ("EFI PART" in ASCII)
83 if (PrimaryHeader->Header.Signature != EFI_PTAB_HEADER_ID) {
84 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header!\n"));
85 return EFI_DEVICE_ERROR;
86 }
87
88 // The version must be GPT_HEADER_REVISION_V1 (0x00010000)
89 if (PrimaryHeader->Header.Revision != GPT_HEADER_REVISION_V1) {
90 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header Revision!\n"));
91 return EFI_DEVICE_ERROR;
92 }
93
94 // The HeaderSize must be greater than or equal to 92 and must be less than or equal to the logical block size
95 if ((PrimaryHeader->Header.HeaderSize < sizeof (EFI_PARTITION_TABLE_HEADER)) || (PrimaryHeader->Header.HeaderSize > BlockIo->Media->BlockSize)) {
96 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header HeaderSize!\n"));
97 return EFI_DEVICE_ERROR;
98 }
99
100 // check that the PartitionEntryLBA greater than the Max LBA
101 // This will be used later for multiplication
102 if (PrimaryHeader->PartitionEntryLBA > DivU64x32 (MAX_UINT64, BlockIo->Media->BlockSize)) {
103 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header PartitionEntryLBA!\n"));
104 return EFI_DEVICE_ERROR;
105 }
106
107 // Check that the number of partition entries is greater than zero
108 if (PrimaryHeader->NumberOfPartitionEntries == 0) {
109 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n"));
110 return EFI_DEVICE_ERROR;
111 }
112
113 // SizeOfPartitionEntry must be 128, 256, 512... improper size may lead to accessing uninitialized memory
114 if ((PrimaryHeader->SizeOfPartitionEntry < 128) || ((PrimaryHeader->SizeOfPartitionEntry & (PrimaryHeader->SizeOfPartitionEntry - 1)) != 0)) {
115 DEBUG ((DEBUG_ERROR, "SizeOfPartitionEntry shall be set to a value of 128 x 2^n where n is an integer greater than or equal to zero (e.g., 128, 256, 512, etc.)!\n"));
116 return EFI_DEVICE_ERROR;
117 }
118
119 // This check is to prevent overflow when calculating the allocation size for the partition entries
120 // This check will be used later for multiplication
121 if (PrimaryHeader->NumberOfPartitionEntries > DivU64x32 (MAX_UINT64, PrimaryHeader->SizeOfPartitionEntry)) {
122 DEBUG ((DEBUG_ERROR, "Invalid Partition Table Header NumberOfPartitionEntries!\n"));
123 return EFI_DEVICE_ERROR;
124 }
125
126 return EFI_SUCCESS;
127}
128
147EFIAPI
149 IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
150 OUT UINT32 *AllocationSize
151 )
152{
153 EFI_STATUS Status;
154
155 if (PrimaryHeader == NULL) {
156 return EFI_INVALID_PARAMETER;
157 }
158
159 if (AllocationSize == NULL) {
160 return EFI_INVALID_PARAMETER;
161 }
162
163 // Replacing logic:
164 // PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry;
165 Status = SafeUint32Mult (PrimaryHeader->NumberOfPartitionEntries, PrimaryHeader->SizeOfPartitionEntry, AllocationSize);
166 if (EFI_ERROR (Status)) {
167 DEBUG ((DEBUG_ERROR, "Allocation Size would have overflowed!\n"));
168 return EFI_BAD_BUFFER_SIZE;
169 }
170
171 return EFI_SUCCESS;
172}
173
198 IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader,
199 IN UINTN NumberOfPartition,
200 OUT UINT32 *EventSize
201 )
202{
203 EFI_STATUS Status;
204 UINT32 SafeNumberOfPartitions;
205
206 if (PrimaryHeader == NULL) {
207 return EFI_INVALID_PARAMETER;
208 }
209
210 if (EventSize == NULL) {
211 return EFI_INVALID_PARAMETER;
212 }
213
214 // We shouldn't even attempt to perform the multiplication if the number of partitions is greater than the maximum value of UINT32
215 Status = SafeUintnToUint32 (NumberOfPartition, &SafeNumberOfPartitions);
216 if (EFI_ERROR (Status)) {
217 DEBUG ((DEBUG_ERROR, "NumberOfPartition would have overflowed!\n"));
218 return EFI_INVALID_PARAMETER;
219 }
220
221 // Replacing logic:
222 // (UINT32)(sizeof (EFI_GPT_DATA) - sizeof (GptData->Partitions) + NumberOfPartition * PrimaryHeader.SizeOfPartitionEntry + sizeof (TCG_PCR_EVENT_HDR));
223 Status = SafeUint32Mult (SafeNumberOfPartitions, PrimaryHeader->SizeOfPartitionEntry, EventSize);
224 if (EFI_ERROR (Status)) {
225 DEBUG ((DEBUG_ERROR, "Event Size would have overflowed!\n"));
226 return EFI_BAD_BUFFER_SIZE;
227 }
228
229 Status = SafeUint32Add (
230 sizeof (TCG_PCR_EVENT_HDR) +
231 OFFSET_OF (EFI_GPT_DATA, Partitions),
232 *EventSize,
233 EventSize
234 );
235 if (EFI_ERROR (Status)) {
236 DEBUG ((DEBUG_ERROR, "Event Size would have overflowed because of GPTData!\n"));
237 return EFI_BAD_BUFFER_SIZE;
238 }
239
240 return EFI_SUCCESS;
241}
242
262 IN UINT32 FilePathSize,
263 OUT UINT32 *EventSize
264 )
265{
266 EFI_STATUS Status;
267
268 // Replacing logic:
269 // sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath) + FilePathSize;
270 Status = SafeUint32Add (OFFSET_OF (EFI_IMAGE_LOAD_EVENT, DevicePath), FilePathSize, EventSize);
271 if (EFI_ERROR (Status)) {
272 DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n"));
273 return EFI_BAD_BUFFER_SIZE;
274 }
275
276 // Replacing logic:
277 // EventSize + sizeof (TCG_PCR_EVENT_HDR)
278 Status = SafeUint32Add (*EventSize, sizeof (TCG_PCR_EVENT_HDR), EventSize);
279 if (EFI_ERROR (Status)) {
280 DEBUG ((DEBUG_ERROR, "EventSize would overflow!\n"));
281 return EFI_BAD_BUFFER_SIZE;
282 }
283
284 return EFI_SUCCESS;
285}
UINT64 UINTN
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
EFI_STATUS EFIAPI TpmSanitizePrimaryHeaderAllocationSize(IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, OUT UINT32 *AllocationSize)
EFI_STATUS TpmSanitizePrimaryHeaderGptEventSize(IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, IN UINTN NumberOfPartition, OUT UINT32 *EventSize)
EFI_STATUS EFIAPI TpmSanitizeEfiPartitionTableHeader(IN CONST EFI_PARTITION_TABLE_HEADER *PrimaryHeader, IN CONST EFI_BLOCK_IO_PROTOCOL *BlockIo)
EFI_STATUS TpmSanitizePeImageEventSize(IN UINT32 FilePathSize, OUT UINT32 *EventSize)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
RETURN_STATUS EFIAPI SafeUint32Add(IN UINT32 Augend, IN UINT32 Addend, OUT UINT32 *Result)
Definition: SafeIntLib.c:2927
RETURN_STATUS EFIAPI SafeUint32Mult(IN UINT32 Multiplicand, IN UINT32 Multiplier, OUT UINT32 *Result)
Definition: SafeIntLib.c:3283
RETURN_STATUS EFIAPI SafeUintnToUint32(IN UINTN Operand, OUT UINT32 *Result)
Definition: SafeIntLib32.c:177
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
#define EFI_PTAB_HEADER_ID
Definition: UefiGpt.h:20