VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLibNullClass.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette