TianoCore EDK2 master
Loading...
Searching...
No Matches
VarCheckPcdLibNullClass.c
Go to the documentation of this file.
1
10#include <Library/BaseLib.h>
11#include <Library/DebugLib.h>
15
17
18// #define DUMP_VAR_CHECK_PCD
19
20GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckPcdHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
21
31VOID
33 IN UINTN Indent,
34 IN UINTN Offset,
35 IN UINTN DataSize,
36 IN VOID *UserData
37 )
38{
39 UINT8 *Data;
40
41 CHAR8 Val[50];
42
43 CHAR8 Str[20];
44
45 UINT8 TempByte;
46 UINTN Size;
47 UINTN Index;
48
49 Data = UserData;
50 while (DataSize != 0) {
51 Size = 16;
52 if (Size > DataSize) {
53 Size = DataSize;
54 }
55
56 for (Index = 0; Index < Size; Index += 1) {
57 TempByte = Data[Index];
58 Val[Index * 3 + 0] = mVarCheckPcdHex[TempByte >> 4];
59 Val[Index * 3 + 1] = mVarCheckPcdHex[TempByte & 0xF];
60 Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
61 Str[Index] = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
62 }
63
64 Val[Index * 3] = 0;
65 Str[Index] = 0;
66 DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
67
68 Data += Size;
69 Offset += Size;
70 DataSize -= Size;
71 }
72}
73
85BOOLEAN
88 IN VOID *Data,
89 IN UINTN DataSize
90 )
91{
92 UINT64 OneData;
93 UINT64 Minimum;
94 UINT64 Maximum;
95 UINT64 OneValue;
96 UINT8 *Ptr;
97
98 OneData = 0;
99 CopyMem (&OneData, (UINT8 *)Data + PcdValidData->VarOffset, PcdValidData->StorageWidth);
100
101 switch (PcdValidData->Type) {
102 case VarCheckPcdValidList:
103 Ptr = (UINT8 *)((VAR_CHECK_PCD_VALID_LIST *)PcdValidData + 1);
104 while ((UINTN)Ptr < (UINTN)PcdValidData + PcdValidData->Length) {
105 OneValue = 0;
106 CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
107 if (OneData == OneValue) {
108 //
109 // Match
110 //
111 break;
112 }
113
114 Ptr += PcdValidData->StorageWidth;
115 }
116
117 if ((UINTN)Ptr >= ((UINTN)PcdValidData + PcdValidData->Length)) {
118 //
119 // No match
120 //
121 DEBUG ((DEBUG_INFO, "VarCheckPcdValidData fail: ValidList mismatch (0x%lx)\n", OneData));
122 DEBUG_CODE (
123 VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *)PcdValidData);
124 );
125 return FALSE;
126 }
127
128 break;
129
130 case VarCheckPcdValidRange:
131 Minimum = 0;
132 Maximum = 0;
133 Ptr = (UINT8 *)((VAR_CHECK_PCD_VALID_RANGE *)PcdValidData + 1);
134 while ((UINTN)Ptr < (UINTN)PcdValidData + PcdValidData->Length) {
135 CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
136 Ptr += PcdValidData->StorageWidth;
137 CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
138 Ptr += PcdValidData->StorageWidth;
139
140 if ((OneData >= Minimum) && (OneData <= Maximum)) {
141 return TRUE;
142 }
143 }
144
145 DEBUG ((DEBUG_INFO, "VarCheckPcdValidData fail: ValidRange mismatch (0x%lx)\n", OneData));
146 DEBUG_CODE (
147 VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *)PcdValidData);
148 );
149 return FALSE;
150 break;
151
152 default:
153 ASSERT (FALSE);
154 break;
155 }
156
157 return TRUE;
158}
159
160VAR_CHECK_PCD_VARIABLE_HEADER *mVarCheckPcdBin = NULL;
161UINTN mVarCheckPcdBinSize = 0;
162
177EFIAPI
179 IN CHAR16 *VariableName,
180 IN EFI_GUID *VendorGuid,
181 IN UINT32 Attributes,
182 IN UINTN DataSize,
183 IN VOID *Data
184 )
185{
188
189 if (mVarCheckPcdBin == NULL) {
190 return EFI_SUCCESS;
191 }
192
193 if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
194 //
195 // Do not check delete variable.
196 //
197 return EFI_SUCCESS;
198 }
199
200 //
201 // For Pcd Variable header align.
202 //
203 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckPcdBin);
204 while ((UINTN)PcdVariable < ((UINTN)mVarCheckPcdBin + mVarCheckPcdBinSize)) {
205 if ((StrCmp ((CHAR16 *)(PcdVariable + 1), VariableName) == 0) &&
206 (CompareGuid (&PcdVariable->Guid, VendorGuid)))
207 {
208 //
209 // Found the Pcd Variable that could be used to do check.
210 //
211 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
212 if ((PcdVariable->Attributes != 0) && (PcdVariable->Attributes != Attributes)) {
213 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable fail for Attributes - 0x%08x\n", PcdVariable->Attributes));
214 return EFI_SECURITY_VIOLATION;
215 }
216
217 if (DataSize == 0) {
218 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - CHECK PASS with DataSize == 0 !\n"));
219 return EFI_SUCCESS;
220 }
221
222 //
223 // Do the check.
224 // For Pcd ValidData header align.
225 //
226 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->HeaderLength));
227 while ((UINTN)PcdValidData < ((UINTN)PcdVariable + PcdVariable->Length)) {
228 if (((UINTN)PcdValidData->VarOffset + PcdValidData->StorageWidth) <= DataSize) {
229 if (!VarCheckPcdValidData (PcdValidData, Data, DataSize)) {
230 return EFI_SECURITY_VIOLATION;
231 }
232 }
233
234 //
235 // For Pcd ValidData header align.
236 //
237 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdValidData + PcdValidData->Length));
238 }
239
240 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - ALL CHECK PASS!\n"));
241 return EFI_SUCCESS;
242 }
243
244 //
245 // For Pcd Variable header align.
246 //
247 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->Length));
248 }
249
250 // Not found, so pass.
251 return EFI_SUCCESS;
252}
253
254#ifdef DUMP_VAR_CHECK_PCD
255
262VOID
263DumpPcdValidData (
265 )
266{
267 UINT64 Minimum;
268 UINT64 Maximum;
269 UINT64 OneValue;
270 UINT8 *Ptr;
271
272 DEBUG ((DEBUG_INFO, " VAR_CHECK_PCD_VALID_DATA_HEADER\n"));
273 DEBUG ((DEBUG_INFO, " Type - 0x%02x\n", PcdValidData->Type));
274 DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", PcdValidData->Length));
275 DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x\n", PcdValidData->VarOffset));
276 DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x\n", PcdValidData->StorageWidth));
277
278 switch (PcdValidData->Type) {
279 case VarCheckPcdValidList:
280 Ptr = (UINT8 *)((VAR_CHECK_PCD_VALID_LIST *)PcdValidData + 1);
281 while ((UINTN)Ptr < ((UINTN)PcdValidData + PcdValidData->Length)) {
282 OneValue = 0;
283 CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
284 switch (PcdValidData->StorageWidth) {
285 case sizeof (UINT8):
286 DEBUG ((DEBUG_INFO, " ValidList - 0x%02x\n", OneValue));
287 break;
288 case sizeof (UINT16):
289 DEBUG ((DEBUG_INFO, " ValidList - 0x%04x\n", OneValue));
290 break;
291 case sizeof (UINT32):
292 DEBUG ((DEBUG_INFO, " ValidList - 0x%08x\n", OneValue));
293 break;
294 case sizeof (UINT64):
295 DEBUG ((DEBUG_INFO, " ValidList - 0x%016lx\n", OneValue));
296 break;
297 default:
298 ASSERT (FALSE);
299 break;
300 }
301
302 Ptr += PcdValidData->StorageWidth;
303 }
304
305 break;
306
307 case VarCheckPcdValidRange:
308 Minimum = 0;
309 Maximum = 0;
310 Ptr = (UINT8 *)((VAR_CHECK_PCD_VALID_RANGE *)PcdValidData + 1);
311 while ((UINTN)Ptr < (UINTN)PcdValidData + PcdValidData->Length) {
312 CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
313 Ptr += PcdValidData->StorageWidth;
314 CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
315 Ptr += PcdValidData->StorageWidth;
316
317 switch (PcdValidData->StorageWidth) {
318 case sizeof (UINT8):
319 DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));
320 DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));
321 break;
322 case sizeof (UINT16):
323 DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));
324 DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));
325 break;
326 case sizeof (UINT32):
327 DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));
328 DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));
329 break;
330 case sizeof (UINT64):
331 DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));
332 DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));
333 break;
334 default:
335 ASSERT (FALSE);
336 break;
337 }
338 }
339
340 break;
341
342 default:
343 ASSERT (FALSE);
344 break;
345 }
346}
347
354VOID
355DumpPcdVariable (
357 )
358{
360
361 DEBUG ((DEBUG_INFO, "VAR_CHECK_PCD_VARIABLE_HEADER\n"));
362 DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", PcdVariable->Revision));
363 DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", PcdVariable->HeaderLength));
364 DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", PcdVariable->Length));
365 DEBUG ((DEBUG_INFO, " Type - 0x%02x\n", PcdVariable->Type));
366 DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", PcdVariable->Attributes));
367 DEBUG ((DEBUG_INFO, " Guid - %g\n", &PcdVariable->Guid));
368 DEBUG ((DEBUG_INFO, " Name - %s\n", PcdVariable + 1));
369
370 //
371 // For Pcd ValidData header align.
372 //
373 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->HeaderLength));
374 while ((UINTN)PcdValidData < ((UINTN)PcdVariable + PcdVariable->Length)) {
375 //
376 // Dump Pcd ValidData related to the Pcd Variable.
377 //
378 DumpPcdValidData (PcdValidData);
379 //
380 // For Pcd ValidData header align.
381 //
382 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdValidData + PcdValidData->Length));
383 }
384}
385
393VOID
394DumpVarCheckPcd (
395 IN VOID *VarCheckPcdBin,
396 IN UINTN VarCheckPcdBinSize
397 )
398{
400
401 DEBUG ((DEBUG_INFO, "DumpVarCheckPcd\n"));
402
403 //
404 // For Pcd Variable header align.
405 //
406 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckPcdBin);
407 while ((UINTN)PcdVariable < ((UINTN)VarCheckPcdBin + VarCheckPcdBinSize)) {
408 DumpPcdVariable (PcdVariable);
409 //
410 // For Pcd Variable header align.
411 //
412 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->Length));
413 }
414}
415
416#endif
417
422VOID
423EFIAPI
425 VOID
426 )
427{
428 EFI_STATUS Status;
429 VAR_CHECK_PCD_VARIABLE_HEADER *VarCheckPcdBin;
430 UINTN VarCheckPcdBinSize;
431
432 //
433 // Search the VarCheckPcdBin from the first RAW section of current FFS.
434 //
435 Status = GetSectionFromFfs (
436 EFI_SECTION_RAW,
437 0,
438 (VOID **)&VarCheckPcdBin,
439 &VarCheckPcdBinSize
440 );
441 if (!EFI_ERROR (Status)) {
442 //
443 // AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
444 // in SetVariable check handler.
445 //
446 mVarCheckPcdBin = AllocateRuntimeCopyPool (VarCheckPcdBinSize, VarCheckPcdBin);
447 ASSERT (mVarCheckPcdBin != NULL);
448 //
449 // Make sure the allocated buffer for VarCheckPcdBin at required alignment.
450 //
451 ASSERT ((((UINTN)mVarCheckPcdBin) & (HEADER_ALIGNMENT - 1)) == 0);
452 mVarCheckPcdBinSize = VarCheckPcdBinSize;
453 FreePool (VarCheckPcdBin);
454
455 DEBUG ((DEBUG_INFO, "VarCheckPcdBin - at 0x%x size = 0x%x\n", mVarCheckPcdBin, mVarCheckPcdBinSize));
456
457 #ifdef DUMP_VAR_CHECK_PCD
458 DEBUG_CODE (
459 DumpVarCheckPcd (mVarCheckPcdBin, mVarCheckPcdBinSize);
460 );
461 #endif
462 } else {
463 DEBUG ((DEBUG_INFO, "[VarCheckPcd] No VarCheckPcdBin found at the first RAW section\n"));
464 }
465}
466
477EFIAPI
479 IN EFI_HANDLE ImageHandle,
480 IN EFI_SYSTEM_TABLE *SystemTable
481 )
482{
484 VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckPcdBin);
486
487 return EFI_SUCCESS;
488}
UINT64 UINTN
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
EFI_STATUS EFIAPI GetSectionFromFfs(IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **Buffer, OUT UINTN *Size)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateRuntimeCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI VarCheckLibRegisterAddressPointer(IN VOID **AddressPointer)
Definition: VarCheckLib.c:398
EFI_STATUS EFIAPI VarCheckLibRegisterSetVariableCheckHandler(IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler)
Definition: VarCheckLib.c:440
EFI_STATUS EFIAPI VarCheckPcdLibNullClassConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI SetVariableCheckHandlerPcd(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
BOOLEAN VarCheckPcdValidData(IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData, IN VOID *Data, IN UINTN DataSize)
VOID VarCheckPcdInternalDumpHex(IN UINTN Indent, IN UINTN Offset, IN UINTN DataSize, IN VOID *UserData)
VOID EFIAPI LocateVarCheckPcdBin(VOID)
#define HEADER_ALIGNMENT
Definition: Base.h:213