• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Implementation functions and structures for var check uefi library.
3 
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT 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/BaseMemoryLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/DevicePathLib.h>
20 
21 #include <Guid/VariableFormat.h>
22 #include <Guid/GlobalVariable.h>
23 #include <Guid/HardwareErrorVariable.h>
24 #include <Guid/ImageAuthentication.h>
25 
26 typedef
27 EFI_STATUS
28 (EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
29   IN VAR_CHECK_VARIABLE_PROPERTY    *Propery,
30   IN UINTN                          DataSize,
31   IN VOID                           *Data
32   );
33 
34 typedef struct {
35   CHAR16                        *Name;
36   VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
37   INTERNAL_VAR_CHECK_FUNCTION   CheckFunction;
38 } UEFI_DEFINED_VARIABLE_ENTRY;
39 
40 /**
41   Internal check for load option.
42 
43   @param[in] VariablePropery    Pointer to variable property.
44   @param[in] DataSize           Data size.
45   @param[in] Data               Pointer to data buffer.
46 
47   @retval EFI_SUCCESS           The SetVariable check result was success.
48   @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
49 
50 **/
51 EFI_STATUS
52 EFIAPI
InternalVarCheckLoadOption(IN VAR_CHECK_VARIABLE_PROPERTY * VariablePropery,IN UINTN DataSize,IN VOID * Data)53 InternalVarCheckLoadOption (
54   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
55   IN UINTN                          DataSize,
56   IN VOID                           *Data
57   )
58 {
59   UINT16                    FilePathListLength;
60   CHAR16                    *Description;
61   EFI_DEVICE_PATH_PROTOCOL  *FilePathList;
62 
63   FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));
64 
65   //
66   // Check Description
67   //
68   Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));
69   while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
70     if (*Description == L'\0') {
71       break;
72     }
73     Description++;
74   }
75   if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
76     return EFI_INVALID_PARAMETER;
77   }
78   Description++;
79 
80   //
81   // Check FilePathList
82   //
83   FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
84   if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {
85     return EFI_INVALID_PARAMETER;
86   }
87   if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {
88     return EFI_INVALID_PARAMETER;
89   }
90   if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
91     return EFI_INVALID_PARAMETER;
92   }
93   if (!IsDevicePathValid (FilePathList, FilePathListLength)) {
94     return EFI_INVALID_PARAMETER;
95   }
96 
97   return EFI_SUCCESS;
98 }
99 
100 /**
101   Internal check for key option.
102 
103   @param[in] VariablePropery    Pointer to variable property.
104   @param[in] DataSize           Data size.
105   @param[in] Data               Pointer to data buffer.
106 
107   @retval EFI_SUCCESS           The SetVariable check result was success.
108   @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
109 
110 **/
111 EFI_STATUS
112 EFIAPI
InternalVarCheckKeyOption(IN VAR_CHECK_VARIABLE_PROPERTY * VariablePropery,IN UINTN DataSize,IN VOID * Data)113 InternalVarCheckKeyOption (
114   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
115   IN UINTN                          DataSize,
116   IN VOID                           *Data
117   )
118 {
119   if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
120     return EFI_INVALID_PARAMETER;
121   }
122 
123   return EFI_SUCCESS;
124 }
125 
126 /**
127   Internal check for device path.
128 
129   @param[in] VariablePropery    Pointer to variable property.
130   @param[in] DataSize           Data size.
131   @param[in] Data               Pointer to data buffer.
132 
133   @retval EFI_SUCCESS           The SetVariable check result was success.
134   @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
135 
136 **/
137 EFI_STATUS
138 EFIAPI
InternalVarCheckDevicePath(IN VAR_CHECK_VARIABLE_PROPERTY * VariablePropery,IN UINTN DataSize,IN VOID * Data)139 InternalVarCheckDevicePath (
140   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
141   IN UINTN                          DataSize,
142   IN VOID                           *Data
143   )
144 {
145   if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
146     return EFI_INVALID_PARAMETER;
147   }
148   return EFI_SUCCESS;
149 }
150 
151 /**
152   Internal check for ASCII string.
153 
154   @param[in] VariablePropery    Pointer to variable property.
155   @param[in] DataSize           Data size.
156   @param[in] Data               Pointer to data buffer.
157 
158   @retval EFI_SUCCESS           The SetVariable check result was success.
159   @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.
160 
161 **/
162 EFI_STATUS
163 EFIAPI
InternalVarCheckAsciiString(IN VAR_CHECK_VARIABLE_PROPERTY * VariablePropery,IN UINTN DataSize,IN VOID * Data)164 InternalVarCheckAsciiString (
165   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
166   IN UINTN                          DataSize,
167   IN VOID                           *Data
168   )
169 {
170   CHAR8     *String;
171   UINTN     Index;
172 
173   String = (CHAR8 *) Data;
174   if (String[DataSize - 1] == '\0') {
175     return EFI_SUCCESS;
176   } else {
177     for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
178     if (Index == DataSize) {
179       return EFI_INVALID_PARAMETER;
180     }
181   }
182   return EFI_SUCCESS;
183 }
184 
185 /**
186   Internal check for size array.
187 
188   @param[in] VariablePropery    Pointer to variable property.
189   @param[in] DataSize           Data size.
190   @param[in] Data               Pointer to data buffer.
191 
192   @retval EFI_SUCCESS           The SetVariable check result was success.
193   @retval EFI_INVALID_PARAMETER The DataSize is not size array.
194 
195 **/
196 EFI_STATUS
197 EFIAPI
InternalVarCheckSizeArray(IN VAR_CHECK_VARIABLE_PROPERTY * VariablePropery,IN UINTN DataSize,IN VOID * Data)198 InternalVarCheckSizeArray (
199   IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
200   IN UINTN                          DataSize,
201   IN VOID                           *Data
202   )
203 {
204   if ((DataSize % VariablePropery->MinSize) != 0) {
205     return EFI_INVALID_PARAMETER;
206   }
207   return EFI_SUCCESS;
208 }
209 
210 //
211 // To prevent name collisions with possible future globally defined variables,
212 // other internal firmware data variables that are not defined here must be
213 // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
214 // any other GUID defined by the UEFI Specification. Implementations must
215 // only permit the creation of variables with a UEFI Specification-defined
216 // VendorGuid when these variables are documented in the UEFI Specification.
217 //
218 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
219   {
220     EFI_LANG_CODES_VARIABLE_NAME,
221     {
222       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
223       0,
224       VARIABLE_ATTRIBUTE_BS_RT,
225       1,
226       MAX_UINTN
227     },
228     InternalVarCheckAsciiString
229   },
230   {
231     EFI_LANG_VARIABLE_NAME,
232     {
233       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
234       0,
235       VARIABLE_ATTRIBUTE_NV_BS_RT,
236       1,
237       MAX_UINTN
238     },
239     InternalVarCheckAsciiString
240   },
241   {
242     EFI_TIME_OUT_VARIABLE_NAME,
243     {
244       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
245       0,
246       VARIABLE_ATTRIBUTE_NV_BS_RT,
247       sizeof (UINT16),
248       sizeof (UINT16)
249     },
250     NULL
251   },
252   {
253     EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
254     {
255       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
256       0,
257       VARIABLE_ATTRIBUTE_BS_RT,
258       1,
259       MAX_UINTN
260     },
261     InternalVarCheckAsciiString
262   },
263   {
264     EFI_PLATFORM_LANG_VARIABLE_NAME,
265     {
266       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
267       0,
268       VARIABLE_ATTRIBUTE_NV_BS_RT,
269       1,
270       MAX_UINTN
271     },
272     InternalVarCheckAsciiString
273   },
274   {
275     EFI_CON_IN_VARIABLE_NAME,
276     {
277       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
278       0,
279       VARIABLE_ATTRIBUTE_NV_BS_RT,
280       sizeof (EFI_DEVICE_PATH_PROTOCOL),
281       MAX_UINTN
282     },
283     InternalVarCheckDevicePath
284   },
285   {
286     EFI_CON_OUT_VARIABLE_NAME,
287     {
288       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
289       0,
290       VARIABLE_ATTRIBUTE_NV_BS_RT,
291       sizeof (EFI_DEVICE_PATH_PROTOCOL),
292       MAX_UINTN
293     },
294     InternalVarCheckDevicePath
295   },
296   {
297     EFI_ERR_OUT_VARIABLE_NAME,
298     {
299       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
300       0,
301       VARIABLE_ATTRIBUTE_NV_BS_RT,
302       sizeof (EFI_DEVICE_PATH_PROTOCOL),
303       MAX_UINTN
304     },
305     InternalVarCheckDevicePath
306   },
307   {
308     EFI_CON_IN_DEV_VARIABLE_NAME,
309     {
310       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
311       0,
312       VARIABLE_ATTRIBUTE_BS_RT,
313       sizeof (EFI_DEVICE_PATH_PROTOCOL),
314       MAX_UINTN
315     },
316     InternalVarCheckDevicePath
317   },
318   {
319     EFI_CON_OUT_DEV_VARIABLE_NAME,
320     {
321       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
322       0,
323       VARIABLE_ATTRIBUTE_BS_RT,
324       sizeof (EFI_DEVICE_PATH_PROTOCOL),
325       MAX_UINTN
326     },
327     InternalVarCheckDevicePath
328   },
329   {
330     EFI_ERR_OUT_DEV_VARIABLE_NAME,
331     {
332       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
333       0,
334       VARIABLE_ATTRIBUTE_BS_RT,
335       sizeof (EFI_DEVICE_PATH_PROTOCOL),
336       MAX_UINTN
337     },
338     InternalVarCheckDevicePath
339   },
340   {
341     EFI_BOOT_ORDER_VARIABLE_NAME,
342     {
343       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
344       0,
345       VARIABLE_ATTRIBUTE_NV_BS_RT,
346       sizeof (UINT16),
347       MAX_UINTN
348     },
349     InternalVarCheckSizeArray
350   },
351   {
352     EFI_BOOT_NEXT_VARIABLE_NAME,
353     {
354       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
355       0,
356       VARIABLE_ATTRIBUTE_NV_BS_RT,
357       sizeof (UINT16),
358       sizeof (UINT16)
359     },
360     NULL
361   },
362   {
363     EFI_BOOT_CURRENT_VARIABLE_NAME,
364     {
365       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
366       0,
367       VARIABLE_ATTRIBUTE_BS_RT,
368       sizeof (UINT16),
369       sizeof (UINT16)
370     },
371     NULL
372   },
373   {
374     EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
375     {
376       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
377       0,
378       VARIABLE_ATTRIBUTE_BS_RT,
379       sizeof (UINT32),
380       sizeof (UINT32)
381     },
382     NULL
383   },
384   {
385     EFI_DRIVER_ORDER_VARIABLE_NAME,
386     {
387       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
388       0,
389       VARIABLE_ATTRIBUTE_NV_BS_RT,
390       sizeof (UINT16),
391       MAX_UINTN
392     },
393     InternalVarCheckSizeArray
394   },
395   {
396     EFI_SYS_PREP_ORDER_VARIABLE_NAME,
397     {
398       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
399       0,
400       VARIABLE_ATTRIBUTE_NV_BS_RT,
401       sizeof (UINT16),
402       MAX_UINTN
403     },
404     InternalVarCheckSizeArray
405   },
406   {
407     EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
408     {
409       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
410       0,
411       VARIABLE_ATTRIBUTE_NV_BS_RT,
412       sizeof (UINT16),
413       sizeof (UINT16)
414     },
415     NULL
416   },
417   {
418     EFI_SETUP_MODE_NAME,
419     {
420       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
421       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
422       VARIABLE_ATTRIBUTE_BS_RT,
423       sizeof (UINT8),
424       sizeof (UINT8)
425     },
426     NULL
427   },
428   {
429     EFI_AUDIT_MODE_NAME,
430     {
431       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
432       0,
433       VARIABLE_ATTRIBUTE_BS_RT,
434       sizeof (UINT8),
435       sizeof (UINT8)
436     },
437     NULL
438   },
439   {
440     EFI_DEPLOYED_MODE_NAME,
441     {
442       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
443       0,
444       VARIABLE_ATTRIBUTE_BS_RT,
445       sizeof (UINT8),
446       sizeof (UINT8)
447     },
448     NULL
449   },
450   {
451     EFI_KEY_EXCHANGE_KEY_NAME,
452     {
453       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
454       0,
455       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
456       1,
457       MAX_UINTN
458     },
459     NULL
460   },
461   {
462     EFI_PLATFORM_KEY_NAME,
463     {
464       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
465       0,
466       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
467       1,
468       MAX_UINTN
469     },
470     NULL
471   },
472   {
473     EFI_SIGNATURE_SUPPORT_NAME,
474     {
475       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
476       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
477       VARIABLE_ATTRIBUTE_BS_RT,
478       sizeof (EFI_GUID),
479       MAX_UINTN
480     },
481     InternalVarCheckSizeArray
482   },
483   {
484     EFI_SECURE_BOOT_MODE_NAME,
485     {
486       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
487       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
488       VARIABLE_ATTRIBUTE_BS_RT,
489       sizeof (UINT8),
490       sizeof (UINT8)
491     },
492     NULL
493   },
494   {
495     EFI_KEK_DEFAULT_VARIABLE_NAME,
496     {
497       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
498       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
499       VARIABLE_ATTRIBUTE_BS_RT,
500       1,
501       MAX_UINTN
502     },
503     NULL
504   },
505   {
506     EFI_PK_DEFAULT_VARIABLE_NAME,
507     {
508       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
509       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
510       VARIABLE_ATTRIBUTE_BS_RT,
511       1,
512       MAX_UINTN
513     },
514     NULL
515   },
516   {
517     EFI_DB_DEFAULT_VARIABLE_NAME,
518     {
519       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
520       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
521       VARIABLE_ATTRIBUTE_BS_RT,
522       1,
523       MAX_UINTN
524     },
525     NULL
526   },
527   {
528     EFI_DBX_DEFAULT_VARIABLE_NAME,
529     {
530       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
531       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
532       VARIABLE_ATTRIBUTE_BS_RT,
533       1,
534       MAX_UINTN
535     },
536     NULL
537   },
538   {
539     EFI_DBT_DEFAULT_VARIABLE_NAME,
540     {
541       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
542       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
543       VARIABLE_ATTRIBUTE_BS_RT,
544       1,
545       MAX_UINTN
546     },
547     NULL
548   },
549   {
550     EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
551     {
552       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
553       0,
554       VARIABLE_ATTRIBUTE_BS_RT,
555       sizeof (UINT64),
556       sizeof (UINT64)
557     },
558     NULL
559   },
560   {
561     EFI_OS_INDICATIONS_VARIABLE_NAME,
562     {
563       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
564       0,
565       VARIABLE_ATTRIBUTE_NV_BS_RT,
566       sizeof (UINT64),
567       sizeof (UINT64)
568     },
569     NULL
570   },
571   {
572     EFI_VENDOR_KEYS_VARIABLE_NAME,
573     {
574       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
575       VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
576       VARIABLE_ATTRIBUTE_BS_RT,
577       sizeof (UINT8),
578       sizeof (UINT8)
579     },
580     NULL
581   },
582 };
583 
584 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
585   {
586     L"Boot####",
587     {
588       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
589       0,
590       VARIABLE_ATTRIBUTE_NV_BS_RT,
591       sizeof (UINT32) + sizeof (UINT16),
592       MAX_UINTN
593     },
594     InternalVarCheckLoadOption
595   },
596   {
597     L"Driver####",
598     {
599       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
600       0,
601       VARIABLE_ATTRIBUTE_NV_BS_RT,
602       sizeof (UINT32) + sizeof (UINT16),
603       MAX_UINTN
604     },
605     InternalVarCheckLoadOption
606   },
607   {
608     L"SysPrep####",
609     {
610       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
611       0,
612       VARIABLE_ATTRIBUTE_NV_BS_RT,
613       sizeof (UINT32) + sizeof (UINT16),
614       MAX_UINTN
615     },
616     InternalVarCheckLoadOption
617   },
618   {
619     L"Key####",
620     {
621       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
622       0,
623       VARIABLE_ATTRIBUTE_NV_BS_RT,
624       sizeof (EFI_KEY_OPTION),
625       sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
626     },
627     InternalVarCheckKeyOption
628   },
629   {
630     L"PlatformRecovery####",
631     {
632       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
633       0,
634       VARIABLE_ATTRIBUTE_BS_RT,
635       sizeof (UINT32) + sizeof (UINT16),
636       MAX_UINTN
637     },
638     InternalVarCheckLoadOption
639   },
640 };
641 
642 //
643 // EFI_IMAGE_SECURITY_DATABASE_GUID
644 //
645 UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {
646   {
647     EFI_IMAGE_SECURITY_DATABASE,
648     {
649       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
650       0,
651       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
652       1,
653       MAX_UINTN
654     },
655     NULL
656   },
657   {
658     EFI_IMAGE_SECURITY_DATABASE1,
659     {
660       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
661       0,
662       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
663       1,
664       MAX_UINTN
665     },
666     NULL
667   },
668   {
669     EFI_IMAGE_SECURITY_DATABASE2,
670     {
671       VAR_CHECK_VARIABLE_PROPERTY_REVISION,
672       0,
673       VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
674       1,
675       MAX_UINTN
676     },
677     NULL
678   },
679 };
680 
681 //
682 // EFI_HARDWARE_ERROR_VARIABLE
683 //
684 UEFI_DEFINED_VARIABLE_ENTRY mHwErrRecVariable = {
685   L"HwErrRec####",
686   {
687     VAR_CHECK_VARIABLE_PROPERTY_REVISION,
688     0,
689     VARIABLE_ATTRIBUTE_NV_BS_RT_HR,
690     1,
691     MAX_UINTN
692   },
693   NULL
694 };
695 
696 EFI_GUID *mUefiDefinedGuid[] = {
697   &gEfiGlobalVariableGuid,
698   &gEfiImageSecurityDatabaseGuid,
699   &gEfiHardwareErrorVariableGuid
700 };
701 
702 /**
703   Check if a Unicode character is a hexadecimal character.
704 
705   This function checks if a Unicode character is a
706   hexadecimal character.  The valid hexadecimal character is
707   L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
708 
709 
710   @param[in] Char       The character to check against.
711 
712   @retval TRUE          If the Char is a hexadecmial character.
713   @retval FALSE         If the Char is not a hexadecmial character.
714 
715 **/
716 BOOLEAN
717 EFIAPI
VarCheckUefiIsHexaDecimalDigitCharacter(IN CHAR16 Char)718 VarCheckUefiIsHexaDecimalDigitCharacter (
719   IN CHAR16             Char
720   )
721 {
722   return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f'));
723 }
724 
725 /**
726 
727   This code checks if variable is hardware error record variable or not.
728 
729   According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid
730   and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value.
731 
732   @param[in] VariableName   Pointer to variable name.
733   @param[in] VendorGuid     Variable Vendor Guid.
734 
735   @retval TRUE              Variable is hardware error record variable.
736   @retval FALSE             Variable is not hardware error record variable.
737 
738 **/
739 BOOLEAN
740 EFIAPI
IsHwErrRecVariable(IN CHAR16 * VariableName,IN EFI_GUID * VendorGuid)741 IsHwErrRecVariable (
742   IN CHAR16             *VariableName,
743   IN EFI_GUID           *VendorGuid
744   )
745 {
746   if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) ||
747       (StrLen (VariableName) != StrLen (L"HwErrRec####")) ||
748       (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) ||
749       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x8]) ||
750       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x9]) ||
751       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xA]) ||
752       !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xB])) {
753     return FALSE;
754   }
755 
756   return TRUE;
757 }
758 
759 /**
760   Get UEFI defined var check function.
761 
762   @param[in]  VariableName      Pointer to variable name.
763   @param[in]  VendorGuid        Pointer to variable vendor GUID.
764   @param[out] VariableProperty  Pointer to variable property.
765 
766   @return Internal var check function, NULL if no specific check function.
767 
768 **/
769 INTERNAL_VAR_CHECK_FUNCTION
GetUefiDefinedVarCheckFunction(IN CHAR16 * VariableName,IN EFI_GUID * VendorGuid,OUT VAR_CHECK_VARIABLE_PROPERTY ** VariableProperty)770 GetUefiDefinedVarCheckFunction (
771   IN CHAR16                         *VariableName,
772   IN EFI_GUID                       *VendorGuid,
773   OUT VAR_CHECK_VARIABLE_PROPERTY   **VariableProperty
774   )
775 {
776   UINTN     Index;
777   UINTN     NameLength;
778 
779   if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
780     //
781     // Try list 1, exactly match.
782     //
783     for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
784       if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
785         *VariableProperty = &(mGlobalVariableList[Index].VariableProperty);
786         return mGlobalVariableList[Index].CheckFunction;
787       }
788     }
789 
790     //
791     // Try list 2.
792     //
793     NameLength = StrLen (VariableName) - 4;
794     for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
795       if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
796           (StrnCmp (VariableName, mGlobalVariableList2[Index].Name, NameLength) == 0) &&
797           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
798           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
799           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
800           VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
801         *VariableProperty = &(mGlobalVariableList2[Index].VariableProperty);
802         return mGlobalVariableList2[Index].CheckFunction;
803       }
804     }
805   }
806 
807   return NULL;
808 }
809 
810 /**
811   SetVariable check handler UEFI defined.
812 
813   @param[in] VariableName       Name of Variable to set.
814   @param[in] VendorGuid         Variable vendor GUID.
815   @param[in] Attributes         Attribute value of the variable.
816   @param[in] DataSize           Size of Data to set.
817   @param[in] Data               Data pointer.
818 
819   @retval EFI_SUCCESS           The SetVariable check result was success.
820   @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, GUID,
821                                 DataSize and Data value was supplied.
822   @retval EFI_WRITE_PROTECTED   The variable in question is read-only.
823 
824 **/
825 EFI_STATUS
826 EFIAPI
SetVariableCheckHandlerUefiDefined(IN CHAR16 * VariableName,IN EFI_GUID * VendorGuid,IN UINT32 Attributes,IN UINTN DataSize,IN VOID * Data)827 SetVariableCheckHandlerUefiDefined (
828   IN CHAR16     *VariableName,
829   IN EFI_GUID   *VendorGuid,
830   IN UINT32     Attributes,
831   IN UINTN      DataSize,
832   IN VOID       *Data
833   )
834 {
835   EFI_STATUS                    Status;
836   UINTN                         Index;
837   VAR_CHECK_VARIABLE_PROPERTY   Property;
838   VAR_CHECK_VARIABLE_PROPERTY   *VarCheckProperty;
839   INTERNAL_VAR_CHECK_FUNCTION   VarCheckFunction;
840 
841   if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
842     //
843     // Do not check delete variable.
844     //
845     return EFI_SUCCESS;
846   }
847 
848   if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
849     if (!IsHwErrRecVariable (VariableName, VendorGuid)) {
850       return EFI_INVALID_PARAMETER;
851     }
852   }
853 
854   for (Index = 0; Index < sizeof (mUefiDefinedGuid)/sizeof (mUefiDefinedGuid[0]); Index++) {
855     if (CompareGuid (VendorGuid, mUefiDefinedGuid[Index])) {
856       if (VarCheckLibVariablePropertyGet (VariableName, VendorGuid, &Property) == EFI_NOT_FOUND) {
857         //
858         // To prevent name collisions with possible future globally defined variables,
859         // other internal firmware data variables that are not defined here must be
860         // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
861         // any other GUID defined by the UEFI Specification. Implementations must
862         // only permit the creation of variables with a UEFI Specification-defined
863         // VendorGuid when these variables are documented in the UEFI Specification.
864         //
865         DEBUG ((EFI_D_INFO, "UEFI Variable Check fail %r - %s not in %g namespace\n", EFI_INVALID_PARAMETER, VariableName, VendorGuid));
866         return EFI_INVALID_PARAMETER;
867       }
868     }
869   }
870 
871   if (DataSize == 0) {
872     return EFI_SUCCESS;
873   }
874 
875   VarCheckProperty = NULL;
876   VarCheckFunction = GetUefiDefinedVarCheckFunction (VariableName, VendorGuid, &VarCheckProperty);
877   if (VarCheckFunction != NULL) {
878     Status = VarCheckFunction (
879                VarCheckProperty,
880                DataSize,
881                Data
882                );
883     if (EFI_ERROR (Status)) {
884       DEBUG ((EFI_D_INFO, "UEFI Variable Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
885       return Status;
886     }
887   }
888 
889   return EFI_SUCCESS;
890 }
891 
892 /**
893   Variable property set for UEFI defined variables.
894 
895 **/
896 VOID
VariablePropertySetUefiDefined(VOID)897 VariablePropertySetUefiDefined (
898   VOID
899   )
900 {
901   UINTN     Index;
902 
903   //
904   // EFI_GLOBAL_VARIABLE
905   //
906   for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
907     VarCheckLibVariablePropertySet (
908       mGlobalVariableList[Index].Name,
909       &gEfiGlobalVariableGuid,
910       &mGlobalVariableList[Index].VariableProperty
911       );
912   }
913   for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
914     VarCheckLibVariablePropertySet (
915       mGlobalVariableList2[Index].Name,
916       &gEfiGlobalVariableGuid,
917       &mGlobalVariableList2[Index].VariableProperty
918       );
919   }
920 
921   //
922   // EFI_IMAGE_SECURITY_DATABASE_GUID
923   //
924   for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {
925     VarCheckLibVariablePropertySet (
926       mImageSecurityVariableList[Index].Name,
927       &gEfiImageSecurityDatabaseGuid,
928       &mImageSecurityVariableList[Index].VariableProperty
929       );
930   }
931 
932   //
933   // EFI_HARDWARE_ERROR_VARIABLE
934   //
935   VarCheckLibVariablePropertySet (
936     mHwErrRecVariable.Name,
937     &gEfiHardwareErrorVariableGuid,
938     &mHwErrRecVariable.VariableProperty
939     );
940 }
941 
942 /**
943   Constructor function of VarCheckUefiLib to set property and
944   register SetVariable check handler for UEFI defined variables.
945 
946   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
947   @param[in] SystemTable    A pointer to the EFI System Table.
948 
949   @retval EFI_SUCCESS       The constructor executed correctly.
950 
951 **/
952 EFI_STATUS
953 EFIAPI
VarCheckUefiLibNullClassConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)954 VarCheckUefiLibNullClassConstructor (
955   IN EFI_HANDLE             ImageHandle,
956   IN EFI_SYSTEM_TABLE       *SystemTable
957   )
958 {
959   VariablePropertySetUefiDefined ();
960   VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerUefiDefined);
961 
962   return EFI_SUCCESS;
963 }
964