]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLibNullClass.c
MdeModulePkg: Change use of EFI_D_* to DEBUG_*
[mirror_edk2.git] / MdeModulePkg / Library / VarCheckPcdLib / VarCheckPcdLibNullClass.c
CommitLineData
a2918326
SZ
1/** @file\r
2 Var Check PCD handler.\r
3\r
cd16355b 4Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
a2918326
SZ
6\r
7**/\r
8\r
9#include <Library/VarCheckLib.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/DebugLib.h>\r
12#include <Library/BaseMemoryLib.h>\r
13#include <Library/MemoryAllocationLib.h>\r
14#include <Library/DxeServicesLib.h>\r
15\r
16#include "VarCheckPcdStructure.h"\r
17\r
18//#define DUMP_VAR_CHECK_PCD\r
19\r
20GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckPcdHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};\r
21\r
22/**\r
23 Dump some hexadecimal data.\r
24\r
25 @param[in] Indent How many spaces to indent the output.\r
26 @param[in] Offset The offset of the dump.\r
27 @param[in] DataSize The size in bytes of UserData.\r
28 @param[in] UserData The data to dump.\r
29\r
30**/\r
31VOID\r
32VarCheckPcdInternalDumpHex (\r
33 IN UINTN Indent,\r
34 IN UINTN Offset,\r
35 IN UINTN DataSize,\r
36 IN VOID *UserData\r
37 )\r
38{\r
39 UINT8 *Data;\r
40\r
41 CHAR8 Val[50];\r
42\r
43 CHAR8 Str[20];\r
44\r
45 UINT8 TempByte;\r
46 UINTN Size;\r
47 UINTN Index;\r
48\r
49 Data = UserData;\r
50 while (DataSize != 0) {\r
51 Size = 16;\r
52 if (Size > DataSize) {\r
53 Size = DataSize;\r
54 }\r
55\r
56 for (Index = 0; Index < Size; Index += 1) {\r
57 TempByte = Data[Index];\r
58 Val[Index * 3 + 0] = mVarCheckPcdHex[TempByte >> 4];\r
59 Val[Index * 3 + 1] = mVarCheckPcdHex[TempByte & 0xF];\r
60 Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');\r
61 Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);\r
62 }\r
63\r
64 Val[Index * 3] = 0;\r
65 Str[Index] = 0;\r
87000d77 66 DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));\r
a2918326
SZ
67\r
68 Data += Size;\r
69 Offset += Size;\r
70 DataSize -= Size;\r
71 }\r
72}\r
73\r
74/**\r
75 Var Check Pcd ValidData.\r
76\r
77 @param[in] PcdValidData Pointer to Pcd ValidData\r
78 @param[in] Data Data pointer.\r
79 @param[in] DataSize Size of Data to set.\r
80\r
81 @retval TRUE Check pass\r
82 @retval FALSE Check fail.\r
83\r
84**/\r
85BOOLEAN\r
86VarCheckPcdValidData (\r
87 IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData,\r
88 IN VOID *Data,\r
89 IN UINTN DataSize\r
90 )\r
91{\r
92 UINT64 OneData;\r
93 UINT64 Minimum;\r
94 UINT64 Maximum;\r
95 UINT64 OneValue;\r
96 UINT8 *Ptr;\r
97\r
98 OneData = 0;\r
99 CopyMem (&OneData, (UINT8 *) Data + PcdValidData->VarOffset, PcdValidData->StorageWidth);\r
100\r
101 switch (PcdValidData->Type) {\r
102 case VarCheckPcdValidList:\r
103 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);\r
104 while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {\r
105 OneValue = 0;\r
106 CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);\r
107 if (OneData == OneValue) {\r
108 //\r
109 // Match\r
110 //\r
111 break;\r
112 }\r
113 Ptr += PcdValidData->StorageWidth;\r
114 }\r
115 if ((UINTN) Ptr >= ((UINTN) PcdValidData + PcdValidData->Length)) {\r
116 //\r
117 // No match\r
118 //\r
87000d77 119 DEBUG ((DEBUG_INFO, "VarCheckPcdValidData fail: ValidList mismatch (0x%lx)\n", OneData));\r
a2918326
SZ
120 DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););\r
121 return FALSE;\r
122 }\r
123 break;\r
124\r
125 case VarCheckPcdValidRange:\r
126 Minimum = 0;\r
127 Maximum = 0;\r
128 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);\r
129 while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {\r
130 CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);\r
131 Ptr += PcdValidData->StorageWidth;\r
132 CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);\r
133 Ptr += PcdValidData->StorageWidth;\r
134\r
135 if ((OneData >= Minimum) && (OneData <= Maximum)) {\r
136 return TRUE;\r
137 }\r
138 }\r
87000d77 139 DEBUG ((DEBUG_INFO, "VarCheckPcdValidData fail: ValidRange mismatch (0x%lx)\n", OneData));\r
a2918326
SZ
140 DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););\r
141 return FALSE;\r
142 break;\r
143\r
144 default:\r
145 ASSERT (FALSE);\r
146 break;\r
147 }\r
148\r
149 return TRUE;\r
150}\r
151\r
152VAR_CHECK_PCD_VARIABLE_HEADER *mVarCheckPcdBin = NULL;\r
153UINTN mVarCheckPcdBinSize = 0;\r
154\r
155/**\r
156 SetVariable check handler PCD.\r
157\r
158 @param[in] VariableName Name of Variable to set.\r
159 @param[in] VendorGuid Variable vendor GUID.\r
160 @param[in] Attributes Attribute value of the variable.\r
161 @param[in] DataSize Size of Data to set.\r
162 @param[in] Data Data pointer.\r
163\r
164 @retval EFI_SUCCESS The SetVariable check result was success.\r
165 @retval EFI_SECURITY_VIOLATION Check fail.\r
166\r
167**/\r
168EFI_STATUS\r
169EFIAPI\r
170SetVariableCheckHandlerPcd (\r
171 IN CHAR16 *VariableName,\r
172 IN EFI_GUID *VendorGuid,\r
173 IN UINT32 Attributes,\r
174 IN UINTN DataSize,\r
175 IN VOID *Data\r
176 )\r
177{\r
178 VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable;\r
179 VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;\r
180\r
181 if (mVarCheckPcdBin == NULL) {\r
182 return EFI_SUCCESS;\r
183 }\r
184\r
185 if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {\r
186 //\r
187 // Do not check delete variable.\r
188 //\r
189 return EFI_SUCCESS;\r
190 }\r
191\r
192 //\r
193 // For Pcd Variable header align.\r
194 //\r
195 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (mVarCheckPcdBin);\r
196 while ((UINTN) PcdVariable < ((UINTN) mVarCheckPcdBin + mVarCheckPcdBinSize)) {\r
197 if ((StrCmp ((CHAR16 *) (PcdVariable + 1), VariableName) == 0) &&\r
198 (CompareGuid (&PcdVariable->Guid, VendorGuid))) {\r
199 //\r
200 // Found the Pcd Variable that could be used to do check.\r
201 //\r
87000d77 202 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));\r
a2918326 203 if ((PcdVariable->Attributes != 0) && PcdVariable->Attributes != Attributes) {\r
87000d77 204 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable fail for Attributes - 0x%08x\n", PcdVariable->Attributes));\r
a2918326
SZ
205 return EFI_SECURITY_VIOLATION;\r
206 }\r
207\r
208 if (DataSize == 0) {\r
87000d77 209 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - CHECK PASS with DataSize == 0 !\n"));\r
a2918326
SZ
210 return EFI_SUCCESS;\r
211 }\r
212\r
213 //\r
214 // Do the check.\r
215 // For Pcd ValidData header align.\r
216 //\r
217 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));\r
218 while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {\r
219 if (((UINTN) PcdValidData->VarOffset + PcdValidData->StorageWidth) <= DataSize) {\r
220 if (!VarCheckPcdValidData (PcdValidData, Data, DataSize)) {\r
221 return EFI_SECURITY_VIOLATION;\r
222 }\r
223 }\r
224 //\r
225 // For Pcd ValidData header align.\r
226 //\r
227 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));\r
228 }\r
229\r
87000d77 230 DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - ALL CHECK PASS!\n"));\r
a2918326
SZ
231 return EFI_SUCCESS;\r
232 }\r
233 //\r
234 // For Pcd Variable header align.\r
235 //\r
236 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));\r
237 }\r
238\r
239 // Not found, so pass.\r
240 return EFI_SUCCESS;\r
241}\r
242\r
243#ifdef DUMP_VAR_CHECK_PCD\r
244/**\r
245 Dump Pcd ValidData.\r
246\r
247 @param[in] PcdValidData Pointer to Pcd ValidData.\r
248\r
249**/\r
250VOID\r
251DumpPcdValidData (\r
252 IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData\r
253 )\r
254{\r
255 UINT64 Minimum;\r
256 UINT64 Maximum;\r
257 UINT64 OneValue;\r
258 UINT8 *Ptr;\r
259\r
87000d77
MK
260 DEBUG ((DEBUG_INFO, " VAR_CHECK_PCD_VALID_DATA_HEADER\n"));\r
261 DEBUG ((DEBUG_INFO, " Type - 0x%02x\n", PcdValidData->Type));\r
262 DEBUG ((DEBUG_INFO, " Length - 0x%02x\n", PcdValidData->Length));\r
263 DEBUG ((DEBUG_INFO, " VarOffset - 0x%04x\n", PcdValidData->VarOffset));\r
264 DEBUG ((DEBUG_INFO, " StorageWidth - 0x%02x\n", PcdValidData->StorageWidth));\r
a2918326
SZ
265\r
266 switch (PcdValidData->Type) {\r
267 case VarCheckPcdValidList:\r
268 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);\r
269 while ((UINTN) Ptr < ((UINTN) PcdValidData + PcdValidData->Length)) {\r
270 OneValue = 0;\r
271 CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);\r
272 switch (PcdValidData->StorageWidth) {\r
273 case sizeof (UINT8):\r
87000d77 274 DEBUG ((DEBUG_INFO, " ValidList - 0x%02x\n", OneValue));\r
a2918326
SZ
275 break;\r
276 case sizeof (UINT16):\r
87000d77 277 DEBUG ((DEBUG_INFO, " ValidList - 0x%04x\n", OneValue));\r
a2918326
SZ
278 break;\r
279 case sizeof (UINT32):\r
87000d77 280 DEBUG ((DEBUG_INFO, " ValidList - 0x%08x\n", OneValue));\r
a2918326
SZ
281 break;\r
282 case sizeof (UINT64):\r
87000d77 283 DEBUG ((DEBUG_INFO, " ValidList - 0x%016lx\n", OneValue));\r
a2918326
SZ
284 break;\r
285 default:\r
286 ASSERT (FALSE);\r
287 break;\r
288 }\r
289 Ptr += PcdValidData->StorageWidth;\r
290 }\r
291 break;\r
292\r
293 case VarCheckPcdValidRange:\r
294 Minimum = 0;\r
295 Maximum = 0;\r
296 Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);\r
297 while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {\r
298 CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);\r
299 Ptr += PcdValidData->StorageWidth;\r
300 CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);\r
301 Ptr += PcdValidData->StorageWidth;\r
302\r
303 switch (PcdValidData->StorageWidth) {\r
304 case sizeof (UINT8):\r
87000d77
MK
305 DEBUG ((DEBUG_INFO, " Minimum - 0x%02x\n", Minimum));\r
306 DEBUG ((DEBUG_INFO, " Maximum - 0x%02x\n", Maximum));\r
a2918326
SZ
307 break;\r
308 case sizeof (UINT16):\r
87000d77
MK
309 DEBUG ((DEBUG_INFO, " Minimum - 0x%04x\n", Minimum));\r
310 DEBUG ((DEBUG_INFO, " Maximum - 0x%04x\n", Maximum));\r
a2918326
SZ
311 break;\r
312 case sizeof (UINT32):\r
87000d77
MK
313 DEBUG ((DEBUG_INFO, " Minimum - 0x%08x\n", Minimum));\r
314 DEBUG ((DEBUG_INFO, " Maximum - 0x%08x\n", Maximum));\r
a2918326
SZ
315 break;\r
316 case sizeof (UINT64):\r
87000d77
MK
317 DEBUG ((DEBUG_INFO, " Minimum - 0x%016lx\n", Minimum));\r
318 DEBUG ((DEBUG_INFO, " Maximum - 0x%016lx\n", Maximum));\r
a2918326
SZ
319 break;\r
320 default:\r
321 ASSERT (FALSE);\r
322 break;\r
323 }\r
324 }\r
325 break;\r
326\r
327 default:\r
328 ASSERT (FALSE);\r
329 break;\r
330 }\r
331}\r
332\r
333/**\r
334 Dump Pcd Variable.\r
335\r
336 @param[in] PcdVariable Pointer to Pcd Variable.\r
337\r
338**/\r
339VOID\r
340DumpPcdVariable (\r
341 IN VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable\r
342 )\r
343{\r
344 VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;\r
345\r
87000d77
MK
346 DEBUG ((DEBUG_INFO, "VAR_CHECK_PCD_VARIABLE_HEADER\n"));\r
347 DEBUG ((DEBUG_INFO, " Revision - 0x%04x\n", PcdVariable->Revision));\r
348 DEBUG ((DEBUG_INFO, " HeaderLength - 0x%04x\n", PcdVariable->HeaderLength));\r
349 DEBUG ((DEBUG_INFO, " Length - 0x%08x\n", PcdVariable->Length));\r
350 DEBUG ((DEBUG_INFO, " Type - 0x%02x\n", PcdVariable->Type));\r
351 DEBUG ((DEBUG_INFO, " Attributes - 0x%08x\n", PcdVariable->Attributes));\r
352 DEBUG ((DEBUG_INFO, " Guid - %g\n", &PcdVariable->Guid));\r
353 DEBUG ((DEBUG_INFO, " Name - %s\n", PcdVariable + 1));\r
a2918326
SZ
354\r
355 //\r
356 // For Pcd ValidData header align.\r
357 //\r
358 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));\r
359 while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {\r
360 //\r
361 // Dump Pcd ValidData related to the Pcd Variable.\r
362 //\r
363 DumpPcdValidData (PcdValidData);\r
364 //\r
365 // For Pcd ValidData header align.\r
366 //\r
367 PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));\r
368 }\r
369}\r
370\r
371/**\r
372 Dump Var Check PCD.\r
373\r
374 @param[in] VarCheckPcdBin Pointer to VarCheckPcdBin.\r
375 @param[in] VarCheckPcdBinSize VarCheckPcdBin size.\r
376\r
377**/\r
378VOID\r
379DumpVarCheckPcd (\r
380 IN VOID *VarCheckPcdBin,\r
381 IN UINTN VarCheckPcdBinSize\r
382 )\r
383{\r
384 VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable;\r
385\r
87000d77 386 DEBUG ((DEBUG_INFO, "DumpVarCheckPcd\n"));\r
a2918326
SZ
387\r
388 //\r
389 // For Pcd Variable header align.\r
390 //\r
391 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (VarCheckPcdBin);\r
392 while ((UINTN) PcdVariable < ((UINTN) VarCheckPcdBin + VarCheckPcdBinSize)) {\r
393 DumpPcdVariable (PcdVariable);\r
394 //\r
395 // For Pcd Variable header align.\r
396 //\r
397 PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));\r
398 }\r
399}\r
400#endif\r
401\r
402/**\r
403 Locate VarCheckPcdBin.\r
404\r
405**/\r
406VOID\r
407EFIAPI\r
408LocateVarCheckPcdBin (\r
409 VOID\r
410 )\r
411{\r
412 EFI_STATUS Status;\r
413 VAR_CHECK_PCD_VARIABLE_HEADER *VarCheckPcdBin;\r
414 UINTN VarCheckPcdBinSize;\r
415\r
416 //\r
417 // Search the VarCheckPcdBin from the first RAW section of current FFS.\r
418 //\r
419 Status = GetSectionFromFfs (\r
420 EFI_SECTION_RAW,\r
421 0,\r
422 (VOID **) &VarCheckPcdBin,\r
423 &VarCheckPcdBinSize\r
424 );\r
425 if (!EFI_ERROR (Status)) {\r
426 //\r
427 // AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access\r
428 // in SetVariable check handler.\r
429 //\r
430 mVarCheckPcdBin = AllocateRuntimeCopyPool (VarCheckPcdBinSize, VarCheckPcdBin);\r
431 ASSERT (mVarCheckPcdBin != NULL);\r
cd16355b
SZ
432 //\r
433 // Make sure the allocated buffer for VarCheckPcdBin at required alignment.\r
434 //\r
435 ASSERT ((((UINTN) mVarCheckPcdBin) & (HEADER_ALIGNMENT - 1)) == 0);\r
a2918326
SZ
436 mVarCheckPcdBinSize = VarCheckPcdBinSize;\r
437 FreePool (VarCheckPcdBin);\r
438\r
87000d77 439 DEBUG ((DEBUG_INFO, "VarCheckPcdBin - at 0x%x size = 0x%x\n", mVarCheckPcdBin, mVarCheckPcdBinSize));\r
a2918326
SZ
440\r
441#ifdef DUMP_VAR_CHECK_PCD\r
442 DEBUG_CODE (\r
443 DumpVarCheckPcd (mVarCheckPcdBin, mVarCheckPcdBinSize);\r
444 );\r
445#endif\r
446 } else {\r
87000d77 447 DEBUG ((DEBUG_INFO, "[VarCheckPcd] No VarCheckPcdBin found at the first RAW section\n"));\r
a2918326
SZ
448 }\r
449}\r
450\r
451/**\r
452 Constructor function of VarCheckPcdLib to register var check PCD handler.\r
453\r
454 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
455 @param[in] SystemTable A pointer to the EFI System Table.\r
456\r
457 @retval EFI_SUCCESS The constructor executed correctly.\r
458\r
459**/\r
460EFI_STATUS\r
461EFIAPI\r
462VarCheckPcdLibNullClassConstructor (\r
463 IN EFI_HANDLE ImageHandle,\r
464 IN EFI_SYSTEM_TABLE *SystemTable\r
465 )\r
466{\r
467 LocateVarCheckPcdBin ();\r
468 VarCheckLibRegisterAddressPointer ((VOID **) &mVarCheckPcdBin);\r
469 VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerPcd);\r
470\r
471 return EFI_SUCCESS;\r
472}\r