2 Implementation functions and structures for var check protocol.
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
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.
16 #include "AuthService.h"
17 #include <Library/DevicePathLib.h>
19 extern LIST_ENTRY mLockedVariableList
;
20 extern BOOLEAN mEndOfDxe
;
21 extern BOOLEAN mEnableLocking
;
23 #define VAR_CHECK_HANDLER_TABLE_SIZE 0x8
25 UINT32 mNumberOfHandler
= 0;
26 UINT32 mMaxNumberOfHandler
= 0;
27 VAR_CHECK_SET_VARIABLE_CHECK_HANDLER
*mHandlerTable
= NULL
;
32 VAR_CHECK_VARIABLE_PROPERTY VariableProperty
;
34 } VAR_CHECK_VARIABLE_ENTRY
;
36 LIST_ENTRY mVarCheckVariableList
= INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckVariableList
);
40 (EFIAPI
*INTERNAL_VAR_CHECK_FUNCTION
) (
41 IN VAR_CHECK_VARIABLE_PROPERTY
*Propery
,
48 VAR_CHECK_VARIABLE_PROPERTY VariableProperty
;
49 INTERNAL_VAR_CHECK_FUNCTION CheckFunction
;
50 } UEFI_DEFINED_VARIABLE_ENTRY
;
53 Internal check for load option.
55 @param[in] VariablePropery Pointer to variable property.
56 @param[in] DataSize Data size.
57 @param[in] Data Pointer to data buffer.
59 @retval EFI_SUCCESS The SetVariable check result was success.
60 @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
65 InternalVarCheckLoadOption (
66 IN VAR_CHECK_VARIABLE_PROPERTY
*VariablePropery
,
71 UINT16 FilePathListLength
;
73 EFI_DEVICE_PATH_PROTOCOL
*FilePathList
;
75 FilePathListLength
= *((UINT16
*) ((UINTN
) Data
+ sizeof (UINT32
)));
80 Description
= (CHAR16
*) ((UINTN
) Data
+ sizeof (UINT32
) + sizeof (UINT16
));
81 while (Description
< (CHAR16
*) ((UINTN
) Data
+ DataSize
)) {
82 if (*Description
== L
'\0') {
87 if ((UINTN
) Description
>= ((UINTN
) Data
+ DataSize
)) {
88 return EFI_INVALID_PARAMETER
;
95 FilePathList
= (EFI_DEVICE_PATH_PROTOCOL
*) Description
;
96 if ((UINTN
) FilePathList
> (MAX_ADDRESS
- FilePathListLength
)) {
97 return EFI_INVALID_PARAMETER
;
99 if (((UINTN
) FilePathList
+ FilePathListLength
) > ((UINTN
) Data
+ DataSize
)) {
100 return EFI_INVALID_PARAMETER
;
102 if (FilePathListLength
< sizeof (EFI_DEVICE_PATH_PROTOCOL
)) {
103 return EFI_INVALID_PARAMETER
;
105 if (!IsDevicePathValid (FilePathList
, FilePathListLength
)) {
106 return EFI_INVALID_PARAMETER
;
113 Internal check for key option.
115 @param[in] VariablePropery Pointer to variable property.
116 @param[in] DataSize Data size.
117 @param[in] Data Pointer to data buffer.
119 @retval EFI_SUCCESS The SetVariable check result was success.
120 @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
125 InternalVarCheckKeyOption (
126 IN VAR_CHECK_VARIABLE_PROPERTY
*VariablePropery
,
131 if (((DataSize
- sizeof (EFI_KEY_OPTION
)) % sizeof (EFI_INPUT_KEY
)) != 0) {
132 return EFI_INVALID_PARAMETER
;
139 Internal check for device path.
141 @param[in] VariablePropery Pointer to variable property.
142 @param[in] DataSize Data size.
143 @param[in] Data Pointer to data buffer.
145 @retval EFI_SUCCESS The SetVariable check result was success.
146 @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
151 InternalVarCheckDevicePath (
152 IN VAR_CHECK_VARIABLE_PROPERTY
*VariablePropery
,
157 if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL
*) Data
, DataSize
)) {
158 return EFI_INVALID_PARAMETER
;
164 Internal check for ASCII string.
166 @param[in] VariablePropery Pointer to variable property.
167 @param[in] DataSize Data size.
168 @param[in] Data Pointer to data buffer.
170 @retval EFI_SUCCESS The SetVariable check result was success.
171 @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.
176 InternalVarCheckAsciiString (
177 IN VAR_CHECK_VARIABLE_PROPERTY
*VariablePropery
,
185 String
= (CHAR8
*) Data
;
186 if (String
[DataSize
- 1] == '\0') {
189 for (Index
= 1; Index
< DataSize
&& (String
[DataSize
- 1 - Index
] != '\0'); Index
++);
190 if (Index
== DataSize
) {
191 return EFI_INVALID_PARAMETER
;
198 Internal check for size array.
200 @param[in] VariablePropery Pointer to variable property.
201 @param[in] DataSize Data size.
202 @param[in] Data Pointer to data buffer.
204 @retval EFI_SUCCESS The SetVariable check result was success.
205 @retval EFI_INVALID_PARAMETER The DataSize is not size array.
210 InternalVarCheckSizeArray (
211 IN VAR_CHECK_VARIABLE_PROPERTY
*VariablePropery
,
216 if ((DataSize
% VariablePropery
->MinSize
) != 0) {
217 return EFI_INVALID_PARAMETER
;
223 // To prevent name collisions with possible future globally defined variables,
224 // other internal firmware data variables that are not defined here must be
225 // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
226 // any other GUID defined by the UEFI Specification. Implementations must
227 // only permit the creation of variables with a UEFI Specification-defined
228 // VendorGuid when these variables are documented in the UEFI Specification.
230 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList
[] = {
232 EFI_LANG_CODES_VARIABLE_NAME
,
234 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
236 VARIABLE_ATTRIBUTE_BS_RT
,
240 InternalVarCheckAsciiString
243 EFI_LANG_VARIABLE_NAME
,
245 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
247 VARIABLE_ATTRIBUTE_NV_BS_RT
,
251 InternalVarCheckAsciiString
254 EFI_TIME_OUT_VARIABLE_NAME
,
256 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
258 VARIABLE_ATTRIBUTE_NV_BS_RT
,
265 EFI_PLATFORM_LANG_CODES_VARIABLE_NAME
,
267 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
269 VARIABLE_ATTRIBUTE_BS_RT
,
273 InternalVarCheckAsciiString
276 EFI_PLATFORM_LANG_VARIABLE_NAME
,
278 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
280 VARIABLE_ATTRIBUTE_NV_BS_RT
,
284 InternalVarCheckAsciiString
287 EFI_CON_IN_VARIABLE_NAME
,
289 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
291 VARIABLE_ATTRIBUTE_NV_BS_RT
,
292 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
295 InternalVarCheckDevicePath
298 EFI_CON_OUT_VARIABLE_NAME
,
300 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
302 VARIABLE_ATTRIBUTE_NV_BS_RT
,
303 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
306 InternalVarCheckDevicePath
309 EFI_ERR_OUT_VARIABLE_NAME
,
311 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
313 VARIABLE_ATTRIBUTE_NV_BS_RT
,
314 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
317 InternalVarCheckDevicePath
320 EFI_CON_IN_DEV_VARIABLE_NAME
,
322 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
324 VARIABLE_ATTRIBUTE_BS_RT
,
325 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
328 InternalVarCheckDevicePath
331 EFI_CON_OUT_DEV_VARIABLE_NAME
,
333 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
335 VARIABLE_ATTRIBUTE_BS_RT
,
336 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
339 InternalVarCheckDevicePath
342 EFI_ERR_OUT_DEV_VARIABLE_NAME
,
344 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
346 VARIABLE_ATTRIBUTE_BS_RT
,
347 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
350 InternalVarCheckDevicePath
353 EFI_BOOT_ORDER_VARIABLE_NAME
,
355 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
357 VARIABLE_ATTRIBUTE_NV_BS_RT
,
361 InternalVarCheckSizeArray
364 EFI_BOOT_NEXT_VARIABLE_NAME
,
366 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
368 VARIABLE_ATTRIBUTE_NV_BS_RT
,
375 EFI_BOOT_CURRENT_VARIABLE_NAME
,
377 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
379 VARIABLE_ATTRIBUTE_BS_RT
,
386 EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME
,
388 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
390 VARIABLE_ATTRIBUTE_BS_RT
,
397 EFI_DRIVER_ORDER_VARIABLE_NAME
,
399 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
401 VARIABLE_ATTRIBUTE_NV_BS_RT
,
405 InternalVarCheckSizeArray
408 EFI_SYS_PREP_ORDER_VARIABLE_NAME
,
410 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
412 VARIABLE_ATTRIBUTE_NV_BS_RT
,
416 InternalVarCheckSizeArray
419 EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME
,
421 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
423 VARIABLE_ATTRIBUTE_NV_BS_RT
,
432 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
433 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
434 VARIABLE_ATTRIBUTE_BS_RT
,
441 EFI_KEY_EXCHANGE_KEY_NAME
,
443 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
445 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
452 EFI_PLATFORM_KEY_NAME
,
454 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
456 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
463 EFI_SIGNATURE_SUPPORT_NAME
,
465 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
466 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
467 VARIABLE_ATTRIBUTE_BS_RT
,
471 InternalVarCheckSizeArray
474 EFI_SECURE_BOOT_MODE_NAME
,
476 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
477 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
478 VARIABLE_ATTRIBUTE_BS_RT
,
485 EFI_KEK_DEFAULT_VARIABLE_NAME
,
487 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
488 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
489 VARIABLE_ATTRIBUTE_BS_RT
,
496 EFI_PK_DEFAULT_VARIABLE_NAME
,
498 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
499 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
500 VARIABLE_ATTRIBUTE_BS_RT
,
507 EFI_DB_DEFAULT_VARIABLE_NAME
,
509 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
510 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
511 VARIABLE_ATTRIBUTE_BS_RT
,
518 EFI_DBX_DEFAULT_VARIABLE_NAME
,
520 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
521 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
522 VARIABLE_ATTRIBUTE_BS_RT
,
529 EFI_DBT_DEFAULT_VARIABLE_NAME
,
531 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
532 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
533 VARIABLE_ATTRIBUTE_BS_RT
,
540 EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME
,
542 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
544 VARIABLE_ATTRIBUTE_BS_RT
,
551 EFI_OS_INDICATIONS_VARIABLE_NAME
,
553 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
555 VARIABLE_ATTRIBUTE_NV_BS_RT
,
562 EFI_VENDOR_KEYS_VARIABLE_NAME
,
564 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
565 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
566 VARIABLE_ATTRIBUTE_BS_RT
,
573 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2
[] = {
577 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
579 VARIABLE_ATTRIBUTE_NV_BS_RT
,
580 sizeof (UINT32
) + sizeof (UINT16
),
583 InternalVarCheckLoadOption
588 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
590 VARIABLE_ATTRIBUTE_NV_BS_RT
,
591 sizeof (UINT32
) + sizeof (UINT16
),
594 InternalVarCheckLoadOption
599 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
601 VARIABLE_ATTRIBUTE_NV_BS_RT
,
602 sizeof (UINT32
) + sizeof (UINT16
),
605 InternalVarCheckLoadOption
610 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
612 VARIABLE_ATTRIBUTE_NV_BS_RT
,
613 sizeof (EFI_KEY_OPTION
),
614 sizeof (EFI_KEY_OPTION
) + 3 * sizeof (EFI_INPUT_KEY
)
616 InternalVarCheckKeyOption
621 // EFI_IMAGE_SECURITY_DATABASE_GUID
623 UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList
[] = {
625 EFI_IMAGE_SECURITY_DATABASE
,
627 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
629 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
636 EFI_IMAGE_SECURITY_DATABASE1
,
638 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
640 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
647 EFI_IMAGE_SECURITY_DATABASE2
,
649 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
651 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
662 VAR_CHECK_VARIABLE_PROPERTY VariableProperty
;
663 INTERNAL_VAR_CHECK_FUNCTION CheckFunction
;
664 } VARIABLE_DRIVER_VARIABLE_ENTRY
;
666 VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList
[] = {
668 &gEfiSecureBootEnableDisableGuid
,
669 EFI_SECURE_BOOT_ENABLE_NAME
,
671 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
673 VARIABLE_ATTRIBUTE_NV_BS
,
679 &gEfiCustomModeEnableGuid
,
680 EFI_CUSTOM_MODE_NAME
,
682 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
684 VARIABLE_ATTRIBUTE_NV_BS
,
690 &gEfiVendorKeysNvGuid
,
691 EFI_VENDOR_KEYS_NV_VARIABLE_NAME
,
693 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
694 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
695 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
701 &gEfiAuthenticatedVariableGuid
,
704 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
705 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
706 VARIABLE_ATTRIBUTE_NV_BS_RT_AW
,
715 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
716 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
717 VARIABLE_ATTRIBUTE_NV_BS_RT_AT
,
723 &gEdkiiVarErrorFlagGuid
,
726 VAR_CHECK_VARIABLE_PROPERTY_REVISION
,
727 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
,
728 VARIABLE_ATTRIBUTE_NV_BS_RT
,
729 sizeof (VAR_ERROR_FLAG
),
730 sizeof (VAR_ERROR_FLAG
)
736 Get UEFI defined global variable or image security database variable property.
737 The code will check if variable guid is global variable or image security database guid first.
738 If yes, further check if variable name is in mGlobalVariableList, mGlobalVariableList2 or mImageSecurityVariableList.
740 @param[in] VariableName Pointer to variable name.
741 @param[in] VendorGuid Variable Vendor Guid.
742 @param[in] WildcardMatch Try wildcard match or not.
743 @param[out] VariableProperty Pointer to variable property.
744 @param[out] VarCheckFunction Pointer to check function.
746 @retval EFI_SUCCESS Variable is not global variable or image security database variable.
747 @retval EFI_INVALID_PARAMETER Variable is global variable or image security database variable, but variable name is not in the lists.
751 GetUefiDefinedVariableProperty (
752 IN CHAR16
*VariableName
,
753 IN EFI_GUID
*VendorGuid
,
754 IN BOOLEAN WildcardMatch
,
755 OUT VAR_CHECK_VARIABLE_PROPERTY
**VariableProperty
,
756 OUT INTERNAL_VAR_CHECK_FUNCTION
*VarCheckFunction OPTIONAL
762 if (CompareGuid (VendorGuid
, &gEfiGlobalVariableGuid
)) {
764 // Try list 1, exactly match.
766 for (Index
= 0; Index
< sizeof (mGlobalVariableList
)/sizeof (mGlobalVariableList
[0]); Index
++) {
767 if (StrCmp (mGlobalVariableList
[Index
].Name
, VariableName
) == 0) {
768 if (VarCheckFunction
!= NULL
) {
769 *VarCheckFunction
= mGlobalVariableList
[Index
].CheckFunction
;
771 *VariableProperty
= &mGlobalVariableList
[Index
].VariableProperty
;
779 NameLength
= StrLen (VariableName
) - 4;
780 for (Index
= 0; Index
< sizeof (mGlobalVariableList2
)/sizeof (mGlobalVariableList2
[0]); Index
++) {
782 if ((StrLen (VariableName
) == StrLen (mGlobalVariableList2
[Index
].Name
)) &&
783 (StrnCmp (mGlobalVariableList2
[Index
].Name
, VariableName
, NameLength
) == 0) &&
784 IsHexaDecimalDigitCharacter (VariableName
[NameLength
]) &&
785 IsHexaDecimalDigitCharacter (VariableName
[NameLength
+ 1]) &&
786 IsHexaDecimalDigitCharacter (VariableName
[NameLength
+ 2]) &&
787 IsHexaDecimalDigitCharacter (VariableName
[NameLength
+ 3])) {
788 if (VarCheckFunction
!= NULL
) {
789 *VarCheckFunction
= mGlobalVariableList2
[Index
].CheckFunction
;
791 *VariableProperty
= &mGlobalVariableList2
[Index
].VariableProperty
;
795 if (StrCmp (mGlobalVariableList2
[Index
].Name
, VariableName
) == 0) {
796 if (VarCheckFunction
!= NULL
) {
797 *VarCheckFunction
= mGlobalVariableList2
[Index
].CheckFunction
;
799 *VariableProperty
= &mGlobalVariableList2
[Index
].VariableProperty
;
805 // The variable name is not in the lists.
807 return EFI_INVALID_PARAMETER
;
810 if (CompareGuid (VendorGuid
, &gEfiImageSecurityDatabaseGuid
)){
811 for (Index
= 0; Index
< sizeof (mImageSecurityVariableList
)/sizeof (mImageSecurityVariableList
[0]); Index
++) {
812 if (StrCmp (mImageSecurityVariableList
[Index
].Name
, VariableName
) == 0) {
813 if (VarCheckFunction
!= NULL
) {
814 *VarCheckFunction
= mImageSecurityVariableList
[Index
].CheckFunction
;
816 *VariableProperty
= &mImageSecurityVariableList
[Index
].VariableProperty
;
821 return EFI_INVALID_PARAMETER
;
825 // It is not global variable or image security database variable.
831 Get variable property for variables managed by Varaible driver.
833 @param[in] VariableName Pointer to variable name.
834 @param[in] VendorGuid Variable Vendor Guid.
836 @return Pointer to variable property.
839 VAR_CHECK_VARIABLE_PROPERTY
*
840 GetVariableDriverVariableProperty (
841 IN CHAR16
*VariableName
,
842 IN EFI_GUID
*VendorGuid
847 for (Index
= 0; Index
< sizeof (mVariableDriverVariableList
)/sizeof (mVariableDriverVariableList
[0]); Index
++) {
848 if ((CompareGuid (mVariableDriverVariableList
[Index
].Guid
, VendorGuid
)) && (StrCmp (mVariableDriverVariableList
[Index
].Name
, VariableName
) == 0)) {
849 return &mVariableDriverVariableList
[Index
].VariableProperty
;
857 Internal SetVariable check.
859 @param[in] VariableName Name of Variable to set.
860 @param[in] VendorGuid Variable vendor GUID.
861 @param[in] Attributes Attribute value of the variable.
862 @param[in] DataSize Size of Data to set.
863 @param[in] Data Data pointer.
865 @retval EFI_SUCCESS The SetVariable check result was success.
866 @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied,
867 or the DataSize exceeds the minimum or maximum allowed,
868 or the Data value is not following UEFI spec for UEFI defined variables.
869 @retval EFI_WRITE_PROTECTED The variable in question is read-only.
870 @retval Others The return status from check handler.
875 InternalVarCheckSetVariableCheck (
876 IN CHAR16
*VariableName
,
877 IN EFI_GUID
*VendorGuid
,
878 IN UINT32 Attributes
,
886 VAR_CHECK_VARIABLE_ENTRY
*Entry
;
888 VAR_CHECK_VARIABLE_PROPERTY
*Property
;
889 INTERNAL_VAR_CHECK_FUNCTION VarCheckFunction
;
893 // Only do check after End Of Dxe.
899 VarCheckFunction
= NULL
;
901 for ( Link
= GetFirstNode (&mVarCheckVariableList
)
902 ; !IsNull (&mVarCheckVariableList
, Link
)
903 ; Link
= GetNextNode (&mVarCheckVariableList
, Link
)
905 Entry
= BASE_CR (Link
, VAR_CHECK_VARIABLE_ENTRY
, Link
);
906 Name
= (CHAR16
*) ((UINTN
) Entry
+ sizeof (*Entry
));
907 if (CompareGuid (&Entry
->Guid
, VendorGuid
) && (StrCmp (Name
, VariableName
) == 0)) {
908 Property
= &Entry
->VariableProperty
;
912 if (Property
== NULL
) {
913 Property
= GetVariableDriverVariableProperty (VariableName
, VendorGuid
);
915 if (Property
== NULL
) {
916 Status
= GetUefiDefinedVariableProperty (VariableName
, VendorGuid
, TRUE
, &Property
, &VarCheckFunction
);
917 if (EFI_ERROR (Status
)) {
918 DEBUG ((EFI_D_INFO
, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status
, VendorGuid
, VariableName
));
922 if (Property
!= NULL
) {
923 if (mEnableLocking
&& ((Property
->Property
& VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
) != 0)) {
924 DEBUG ((EFI_D_INFO
, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED
, VendorGuid
, VariableName
));
925 return EFI_WRITE_PROTECTED
;
927 if (!((((Attributes
& EFI_VARIABLE_APPEND_WRITE
) == 0) && (DataSize
== 0)) || (Attributes
== 0))) {
929 // Not to delete variable.
931 if ((Attributes
& (~EFI_VARIABLE_APPEND_WRITE
)) != Property
->Attributes
) {
932 DEBUG ((EFI_D_INFO
, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property
->Attributes
, Attributes
, EFI_INVALID_PARAMETER
, VendorGuid
, VariableName
));
933 return EFI_INVALID_PARAMETER
;
936 if ((DataSize
< Property
->MinSize
) || (DataSize
> Property
->MaxSize
)) {
937 DEBUG ((EFI_D_INFO
, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize
, Property
->MinSize
, Property
->MaxSize
, EFI_INVALID_PARAMETER
, VendorGuid
, VariableName
));
938 return EFI_INVALID_PARAMETER
;
940 if (VarCheckFunction
!= NULL
) {
941 Status
= VarCheckFunction (
946 if (EFI_ERROR (Status
)) {
947 DEBUG ((EFI_D_INFO
, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status
, VendorGuid
, VariableName
));
955 for (Index
= 0; Index
< mNumberOfHandler
; Index
++) {
956 Status
= mHandlerTable
[Index
] (
963 if (EFI_ERROR (Status
)) {
964 DEBUG ((EFI_D_INFO
, "[Variable]: Var Check handler fail %r - %g:%s\n", Status
, VendorGuid
, VariableName
));
972 Reallocates more global memory to store the registered handler list.
974 @retval RETURN_SUCCESS Reallocate memory successfully.
975 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocate.
980 ReallocateHandlerTable (
984 VAR_CHECK_SET_VARIABLE_CHECK_HANDLER
*HandlerTable
;
987 // Reallocate memory for check handler table.
989 HandlerTable
= ReallocateRuntimePool (
990 mMaxNumberOfHandler
* sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER
),
991 (mMaxNumberOfHandler
+ VAR_CHECK_HANDLER_TABLE_SIZE
) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER
),
996 // No enough resource to allocate.
998 if (HandlerTable
== NULL
) {
999 return RETURN_OUT_OF_RESOURCES
;
1002 mHandlerTable
= HandlerTable
;
1004 // Increase max handler number.
1006 mMaxNumberOfHandler
= mMaxNumberOfHandler
+ VAR_CHECK_HANDLER_TABLE_SIZE
;
1007 return RETURN_SUCCESS
;
1011 Register SetVariable check handler.
1013 @param[in] Handler Pointer to check handler.
1015 @retval EFI_SUCCESS The SetVariable check handler was registered successfully.
1016 @retval EFI_INVALID_PARAMETER Handler is NULL.
1017 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
1018 already been signaled.
1019 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the SetVariable check handler register request.
1020 @retval EFI_UNSUPPORTED This interface is not implemented.
1021 For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
1026 VarCheckRegisterSetVariableCheckHandler (
1027 IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
1032 if (Handler
== NULL
) {
1033 return EFI_INVALID_PARAMETER
;
1037 return EFI_ACCESS_DENIED
;
1040 DEBUG ((EFI_D_INFO
, "RegisterSetVariableCheckHandler - 0x%x\n", Handler
));
1043 // Check whether the handler list is enough to store new handler.
1045 if (mNumberOfHandler
== mMaxNumberOfHandler
) {
1047 // Allocate more resources for new handler.
1049 Status
= ReallocateHandlerTable();
1050 if (EFI_ERROR (Status
)) {
1056 // Register new handler into the handler list.
1058 mHandlerTable
[mNumberOfHandler
] = Handler
;
1059 mNumberOfHandler
++;
1065 Variable property get function.
1067 @param[in] Name Pointer to the variable name.
1068 @param[in] Guid Pointer to the vendor GUID.
1069 @param[in] WildcardMatch Try wildcard match or not.
1071 @return Pointer to the property of variable specified by the Name and Guid.
1074 VAR_CHECK_VARIABLE_PROPERTY
*
1075 VariablePropertyGetFunction (
1078 IN BOOLEAN WildcardMatch
1082 VAR_CHECK_VARIABLE_ENTRY
*Entry
;
1083 CHAR16
*VariableName
;
1084 VAR_CHECK_VARIABLE_PROPERTY
*Property
;
1086 for ( Link
= GetFirstNode (&mVarCheckVariableList
)
1087 ; !IsNull (&mVarCheckVariableList
, Link
)
1088 ; Link
= GetNextNode (&mVarCheckVariableList
, Link
)
1090 Entry
= BASE_CR (Link
, VAR_CHECK_VARIABLE_ENTRY
, Link
);
1091 VariableName
= (CHAR16
*) ((UINTN
) Entry
+ sizeof (*Entry
));
1092 if (CompareGuid (&Entry
->Guid
, Guid
) && (StrCmp (VariableName
, Name
) == 0)) {
1093 return &Entry
->VariableProperty
;
1097 Property
= GetVariableDriverVariableProperty (Name
, Guid
);
1098 if (Property
== NULL
) {
1099 GetUefiDefinedVariableProperty (Name
, Guid
, WildcardMatch
, &Property
, NULL
);
1106 Variable property set.
1108 @param[in] Name Pointer to the variable name.
1109 @param[in] Guid Pointer to the vendor GUID.
1110 @param[in] VariableProperty Pointer to the input variable property.
1112 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
1113 @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
1114 or the fields of VariableProperty are not valid.
1115 @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
1116 already been signaled.
1117 @retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
1122 VarCheckVariablePropertySet (
1125 IN VAR_CHECK_VARIABLE_PROPERTY
*VariableProperty
1129 VAR_CHECK_VARIABLE_ENTRY
*Entry
;
1130 CHAR16
*VariableName
;
1131 VAR_CHECK_VARIABLE_PROPERTY
*Property
;
1133 if (Name
== NULL
|| Name
[0] == 0 || Guid
== NULL
) {
1134 return EFI_INVALID_PARAMETER
;
1137 if (VariableProperty
== NULL
) {
1138 return EFI_INVALID_PARAMETER
;
1141 if (VariableProperty
->Revision
!= VAR_CHECK_VARIABLE_PROPERTY_REVISION
) {
1142 return EFI_INVALID_PARAMETER
;
1146 return EFI_ACCESS_DENIED
;
1149 Status
= EFI_SUCCESS
;
1151 AcquireLockOnlyAtBootTime (&mVariableModuleGlobal
->VariableGlobal
.VariableServicesLock
);
1153 Property
= VariablePropertyGetFunction (Name
, Guid
, FALSE
);
1154 if (Property
!= NULL
) {
1155 CopyMem (Property
, VariableProperty
, sizeof (*VariableProperty
));
1157 Entry
= AllocateRuntimeZeroPool (sizeof (*Entry
) + StrSize (Name
));
1158 if (Entry
== NULL
) {
1159 Status
= EFI_OUT_OF_RESOURCES
;
1162 VariableName
= (CHAR16
*) ((UINTN
) Entry
+ sizeof (*Entry
));
1163 StrnCpy (VariableName
, Name
, StrLen (Name
));
1164 CopyGuid (&Entry
->Guid
, Guid
);
1165 CopyMem (&Entry
->VariableProperty
, VariableProperty
, sizeof (*VariableProperty
));
1166 InsertTailList (&mVarCheckVariableList
, &Entry
->Link
);
1170 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal
->VariableGlobal
.VariableServicesLock
);
1176 Internal variable property get.
1178 @param[in] Name Pointer to the variable name.
1179 @param[in] Guid Pointer to the vendor GUID.
1180 @param[out] VariableProperty Pointer to the output variable property.
1182 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
1183 @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
1188 InternalVarCheckVariablePropertyGet (
1191 OUT VAR_CHECK_VARIABLE_PROPERTY
*VariableProperty
1195 VARIABLE_ENTRY
*Entry
;
1196 CHAR16
*VariableName
;
1198 VAR_CHECK_VARIABLE_PROPERTY
*Property
;
1202 Property
= VariablePropertyGetFunction (Name
, Guid
, TRUE
);
1203 if (Property
!= NULL
) {
1204 CopyMem (VariableProperty
, Property
, sizeof (*VariableProperty
));
1208 for ( Link
= GetFirstNode (&mLockedVariableList
)
1209 ; !IsNull (&mLockedVariableList
, Link
)
1210 ; Link
= GetNextNode (&mLockedVariableList
, Link
)
1212 Entry
= BASE_CR (Link
, VARIABLE_ENTRY
, Link
);
1213 VariableName
= (CHAR16
*) ((UINTN
) Entry
+ sizeof (*Entry
));
1214 if (CompareGuid (&Entry
->Guid
, Guid
) && (StrCmp (VariableName
, Name
) == 0)) {
1215 VariableProperty
->Property
|= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY
;
1217 VariableProperty
->Revision
= VAR_CHECK_VARIABLE_PROPERTY_REVISION
;
1223 return (Found
? EFI_SUCCESS
: EFI_NOT_FOUND
);
1227 Variable property get.
1229 @param[in] Name Pointer to the variable name.
1230 @param[in] Guid Pointer to the vendor GUID.
1231 @param[out] VariableProperty Pointer to the output variable property.
1233 @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
1234 @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
1235 @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
1240 VarCheckVariablePropertyGet (
1243 OUT VAR_CHECK_VARIABLE_PROPERTY
*VariableProperty
1248 if (Name
== NULL
|| Name
[0] == 0 || Guid
== NULL
) {
1249 return EFI_INVALID_PARAMETER
;
1252 if (VariableProperty
== NULL
) {
1253 return EFI_INVALID_PARAMETER
;
1256 AcquireLockOnlyAtBootTime (&mVariableModuleGlobal
->VariableGlobal
.VariableServicesLock
);
1258 Status
= InternalVarCheckVariablePropertyGet (Name
, Guid
, VariableProperty
);
1260 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal
->VariableGlobal
.VariableServicesLock
);