]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c
SecurityPkg Variable: Add SysPrepOrder and SysPrep#### to global list.
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / RuntimeDxe / VarCheck.c
1 /** @file
2 Implementation functions and structures for var check protocol.
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 "Variable.h"
16 #include "AuthService.h"
17 #include <Library/DevicePathLib.h>
18
19 extern LIST_ENTRY mLockedVariableList;
20 extern BOOLEAN mEndOfDxe;
21 extern BOOLEAN mEnableLocking;
22
23 #define VAR_CHECK_HANDLER_TABLE_SIZE 0x8
24
25 UINT32 mNumberOfHandler = 0;
26 UINT32 mMaxNumberOfHandler = 0;
27 VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *mHandlerTable = NULL;
28
29 typedef struct {
30 LIST_ENTRY Link;
31 EFI_GUID Guid;
32 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
33 //CHAR16 *Name;
34 } VAR_CHECK_VARIABLE_ENTRY;
35
36 LIST_ENTRY mVarCheckVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckVariableList);
37
38 typedef
39 EFI_STATUS
40 (EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
41 IN VAR_CHECK_VARIABLE_PROPERTY *Propery,
42 IN UINTN DataSize,
43 IN VOID *Data
44 );
45
46 typedef struct {
47 CHAR16 *Name;
48 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
49 INTERNAL_VAR_CHECK_FUNCTION CheckFunction;
50 } UEFI_DEFINED_VARIABLE_ENTRY;
51
52 /**
53 Internal check for load option.
54
55 @param[in] VariablePropery Pointer to variable property.
56 @param[in] DataSize Data size.
57 @param[in] Data Pointer to data buffer.
58
59 @retval EFI_SUCCESS The SetVariable check result was success.
60 @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
61
62 **/
63 EFI_STATUS
64 EFIAPI
65 InternalVarCheckLoadOption (
66 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
67 IN UINTN DataSize,
68 IN VOID *Data
69 )
70 {
71 UINT16 FilePathListLength;
72 CHAR16 *Description;
73 EFI_DEVICE_PATH_PROTOCOL *FilePathList;
74
75 FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));
76
77 //
78 // Check Description
79 //
80 Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));
81 while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
82 if (*Description == L'\0') {
83 break;
84 }
85 Description++;
86 }
87 if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
88 return EFI_INVALID_PARAMETER;
89 }
90 Description++;
91
92 //
93 // Check FilePathList
94 //
95 FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
96 if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {
97 return EFI_INVALID_PARAMETER;
98 }
99 if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {
100 return EFI_INVALID_PARAMETER;
101 }
102 if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
103 return EFI_INVALID_PARAMETER;
104 }
105 if (!IsDevicePathValid (FilePathList, FilePathListLength)) {
106 return EFI_INVALID_PARAMETER;
107 }
108
109 return EFI_SUCCESS;
110 }
111
112 /**
113 Internal check for key option.
114
115 @param[in] VariablePropery Pointer to variable property.
116 @param[in] DataSize Data size.
117 @param[in] Data Pointer to data buffer.
118
119 @retval EFI_SUCCESS The SetVariable check result was success.
120 @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
121
122 **/
123 EFI_STATUS
124 EFIAPI
125 InternalVarCheckKeyOption (
126 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
127 IN UINTN DataSize,
128 IN VOID *Data
129 )
130 {
131 if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
132 return EFI_INVALID_PARAMETER;
133 }
134
135 return EFI_SUCCESS;
136 }
137
138 /**
139 Internal check for device path.
140
141 @param[in] VariablePropery Pointer to variable property.
142 @param[in] DataSize Data size.
143 @param[in] Data Pointer to data buffer.
144
145 @retval EFI_SUCCESS The SetVariable check result was success.
146 @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
147
148 **/
149 EFI_STATUS
150 EFIAPI
151 InternalVarCheckDevicePath (
152 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
153 IN UINTN DataSize,
154 IN VOID *Data
155 )
156 {
157 if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
158 return EFI_INVALID_PARAMETER;
159 }
160 return EFI_SUCCESS;
161 }
162
163 /**
164 Internal check for ASCII string.
165
166 @param[in] VariablePropery Pointer to variable property.
167 @param[in] DataSize Data size.
168 @param[in] Data Pointer to data buffer.
169
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.
172
173 **/
174 EFI_STATUS
175 EFIAPI
176 InternalVarCheckAsciiString (
177 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
178 IN UINTN DataSize,
179 IN VOID *Data
180 )
181 {
182 CHAR8 *String;
183 UINTN Index;
184
185 String = (CHAR8 *) Data;
186 if (String[DataSize - 1] == '\0') {
187 return EFI_SUCCESS;
188 } else {
189 for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
190 if (Index == DataSize) {
191 return EFI_INVALID_PARAMETER;
192 }
193 }
194 return EFI_SUCCESS;
195 }
196
197 /**
198 Internal check for size array.
199
200 @param[in] VariablePropery Pointer to variable property.
201 @param[in] DataSize Data size.
202 @param[in] Data Pointer to data buffer.
203
204 @retval EFI_SUCCESS The SetVariable check result was success.
205 @retval EFI_INVALID_PARAMETER The DataSize is not size array.
206
207 **/
208 EFI_STATUS
209 EFIAPI
210 InternalVarCheckSizeArray (
211 IN VAR_CHECK_VARIABLE_PROPERTY *VariablePropery,
212 IN UINTN DataSize,
213 IN VOID *Data
214 )
215 {
216 if ((DataSize % VariablePropery->MinSize) != 0) {
217 return EFI_INVALID_PARAMETER;
218 }
219 return EFI_SUCCESS;
220 }
221
222 //
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.
229 //
230 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
231 {
232 EFI_LANG_CODES_VARIABLE_NAME,
233 {
234 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
235 0,
236 VARIABLE_ATTRIBUTE_BS_RT,
237 1,
238 MAX_UINTN
239 },
240 InternalVarCheckAsciiString
241 },
242 {
243 EFI_LANG_VARIABLE_NAME,
244 {
245 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
246 0,
247 VARIABLE_ATTRIBUTE_NV_BS_RT,
248 1,
249 MAX_UINTN
250 },
251 InternalVarCheckAsciiString
252 },
253 {
254 EFI_TIME_OUT_VARIABLE_NAME,
255 {
256 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
257 0,
258 VARIABLE_ATTRIBUTE_NV_BS_RT,
259 sizeof (UINT16),
260 sizeof (UINT16)
261 },
262 NULL
263 },
264 {
265 EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
266 {
267 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
268 0,
269 VARIABLE_ATTRIBUTE_BS_RT,
270 1,
271 MAX_UINTN
272 },
273 InternalVarCheckAsciiString
274 },
275 {
276 EFI_PLATFORM_LANG_VARIABLE_NAME,
277 {
278 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
279 0,
280 VARIABLE_ATTRIBUTE_NV_BS_RT,
281 1,
282 MAX_UINTN
283 },
284 InternalVarCheckAsciiString
285 },
286 {
287 EFI_CON_IN_VARIABLE_NAME,
288 {
289 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
290 0,
291 VARIABLE_ATTRIBUTE_NV_BS_RT,
292 sizeof (EFI_DEVICE_PATH_PROTOCOL),
293 MAX_UINTN
294 },
295 InternalVarCheckDevicePath
296 },
297 {
298 EFI_CON_OUT_VARIABLE_NAME,
299 {
300 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
301 0,
302 VARIABLE_ATTRIBUTE_NV_BS_RT,
303 sizeof (EFI_DEVICE_PATH_PROTOCOL),
304 MAX_UINTN
305 },
306 InternalVarCheckDevicePath
307 },
308 {
309 EFI_ERR_OUT_VARIABLE_NAME,
310 {
311 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
312 0,
313 VARIABLE_ATTRIBUTE_NV_BS_RT,
314 sizeof (EFI_DEVICE_PATH_PROTOCOL),
315 MAX_UINTN
316 },
317 InternalVarCheckDevicePath
318 },
319 {
320 EFI_CON_IN_DEV_VARIABLE_NAME,
321 {
322 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
323 0,
324 VARIABLE_ATTRIBUTE_BS_RT,
325 sizeof (EFI_DEVICE_PATH_PROTOCOL),
326 MAX_UINTN
327 },
328 InternalVarCheckDevicePath
329 },
330 {
331 EFI_CON_OUT_DEV_VARIABLE_NAME,
332 {
333 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
334 0,
335 VARIABLE_ATTRIBUTE_BS_RT,
336 sizeof (EFI_DEVICE_PATH_PROTOCOL),
337 MAX_UINTN
338 },
339 InternalVarCheckDevicePath
340 },
341 {
342 EFI_ERR_OUT_DEV_VARIABLE_NAME,
343 {
344 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
345 0,
346 VARIABLE_ATTRIBUTE_BS_RT,
347 sizeof (EFI_DEVICE_PATH_PROTOCOL),
348 MAX_UINTN
349 },
350 InternalVarCheckDevicePath
351 },
352 {
353 EFI_BOOT_ORDER_VARIABLE_NAME,
354 {
355 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
356 0,
357 VARIABLE_ATTRIBUTE_NV_BS_RT,
358 sizeof (UINT16),
359 MAX_UINTN
360 },
361 InternalVarCheckSizeArray
362 },
363 {
364 EFI_BOOT_NEXT_VARIABLE_NAME,
365 {
366 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
367 0,
368 VARIABLE_ATTRIBUTE_NV_BS_RT,
369 sizeof (UINT16),
370 sizeof (UINT16)
371 },
372 NULL
373 },
374 {
375 EFI_BOOT_CURRENT_VARIABLE_NAME,
376 {
377 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
378 0,
379 VARIABLE_ATTRIBUTE_BS_RT,
380 sizeof (UINT16),
381 sizeof (UINT16)
382 },
383 NULL
384 },
385 {
386 EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
387 {
388 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
389 0,
390 VARIABLE_ATTRIBUTE_BS_RT,
391 sizeof (UINT32),
392 sizeof (UINT32)
393 },
394 NULL
395 },
396 {
397 EFI_DRIVER_ORDER_VARIABLE_NAME,
398 {
399 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
400 0,
401 VARIABLE_ATTRIBUTE_NV_BS_RT,
402 sizeof (UINT16),
403 MAX_UINTN
404 },
405 InternalVarCheckSizeArray
406 },
407 {
408 EFI_SYS_PREP_ORDER_VARIABLE_NAME,
409 {
410 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
411 0,
412 VARIABLE_ATTRIBUTE_NV_BS_RT,
413 sizeof (UINT16),
414 MAX_UINTN
415 },
416 InternalVarCheckSizeArray
417 },
418 {
419 EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
420 {
421 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
422 0,
423 VARIABLE_ATTRIBUTE_NV_BS_RT,
424 sizeof (UINT16),
425 sizeof (UINT16)
426 },
427 NULL
428 },
429 {
430 EFI_SETUP_MODE_NAME,
431 {
432 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
433 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
434 VARIABLE_ATTRIBUTE_BS_RT,
435 sizeof (UINT8),
436 sizeof (UINT8)
437 },
438 NULL
439 },
440 {
441 EFI_KEY_EXCHANGE_KEY_NAME,
442 {
443 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
444 0,
445 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
446 1,
447 MAX_UINTN
448 },
449 NULL
450 },
451 {
452 EFI_PLATFORM_KEY_NAME,
453 {
454 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
455 0,
456 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
457 1,
458 MAX_UINTN
459 },
460 NULL
461 },
462 {
463 EFI_SIGNATURE_SUPPORT_NAME,
464 {
465 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
466 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
467 VARIABLE_ATTRIBUTE_BS_RT,
468 sizeof (EFI_GUID),
469 MAX_UINTN
470 },
471 InternalVarCheckSizeArray
472 },
473 {
474 EFI_SECURE_BOOT_MODE_NAME,
475 {
476 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
477 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
478 VARIABLE_ATTRIBUTE_BS_RT,
479 sizeof (UINT8),
480 sizeof (UINT8)
481 },
482 NULL
483 },
484 {
485 EFI_KEK_DEFAULT_VARIABLE_NAME,
486 {
487 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
488 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
489 VARIABLE_ATTRIBUTE_BS_RT,
490 1,
491 MAX_UINTN
492 },
493 NULL
494 },
495 {
496 EFI_PK_DEFAULT_VARIABLE_NAME,
497 {
498 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
499 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
500 VARIABLE_ATTRIBUTE_BS_RT,
501 1,
502 MAX_UINTN
503 },
504 NULL
505 },
506 {
507 EFI_DB_DEFAULT_VARIABLE_NAME,
508 {
509 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
510 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
511 VARIABLE_ATTRIBUTE_BS_RT,
512 1,
513 MAX_UINTN
514 },
515 NULL
516 },
517 {
518 EFI_DBX_DEFAULT_VARIABLE_NAME,
519 {
520 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
521 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
522 VARIABLE_ATTRIBUTE_BS_RT,
523 1,
524 MAX_UINTN
525 },
526 NULL
527 },
528 {
529 EFI_DBT_DEFAULT_VARIABLE_NAME,
530 {
531 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
532 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
533 VARIABLE_ATTRIBUTE_BS_RT,
534 1,
535 MAX_UINTN
536 },
537 NULL
538 },
539 {
540 EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
541 {
542 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
543 0,
544 VARIABLE_ATTRIBUTE_BS_RT,
545 sizeof (UINT64),
546 sizeof (UINT64)
547 },
548 NULL
549 },
550 {
551 EFI_OS_INDICATIONS_VARIABLE_NAME,
552 {
553 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
554 0,
555 VARIABLE_ATTRIBUTE_NV_BS_RT,
556 sizeof (UINT64),
557 sizeof (UINT64)
558 },
559 NULL
560 },
561 {
562 EFI_VENDOR_KEYS_VARIABLE_NAME,
563 {
564 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
565 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
566 VARIABLE_ATTRIBUTE_BS_RT,
567 sizeof (UINT8),
568 sizeof (UINT8)
569 },
570 NULL
571 },
572 };
573 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
574 {
575 L"Boot####",
576 {
577 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
578 0,
579 VARIABLE_ATTRIBUTE_NV_BS_RT,
580 sizeof (UINT32) + sizeof (UINT16),
581 MAX_UINTN
582 },
583 InternalVarCheckLoadOption
584 },
585 {
586 L"Driver####",
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"SysPrep####",
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"Key####",
609 {
610 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
611 0,
612 VARIABLE_ATTRIBUTE_NV_BS_RT,
613 sizeof (EFI_KEY_OPTION),
614 sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
615 },
616 InternalVarCheckKeyOption
617 },
618 };
619
620 //
621 // EFI_IMAGE_SECURITY_DATABASE_GUID
622 //
623 UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {
624 {
625 EFI_IMAGE_SECURITY_DATABASE,
626 {
627 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
628 0,
629 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
630 1,
631 MAX_UINTN
632 },
633 NULL
634 },
635 {
636 EFI_IMAGE_SECURITY_DATABASE1,
637 {
638 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
639 0,
640 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
641 1,
642 MAX_UINTN
643 },
644 NULL
645 },
646 {
647 EFI_IMAGE_SECURITY_DATABASE2,
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
659 typedef struct {
660 EFI_GUID *Guid;
661 CHAR16 *Name;
662 VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
663 INTERNAL_VAR_CHECK_FUNCTION CheckFunction;
664 } VARIABLE_DRIVER_VARIABLE_ENTRY;
665
666 VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
667 {
668 &gEfiSecureBootEnableDisableGuid,
669 EFI_SECURE_BOOT_ENABLE_NAME,
670 {
671 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
672 0,
673 VARIABLE_ATTRIBUTE_NV_BS,
674 sizeof (UINT8),
675 sizeof (UINT8)
676 }
677 },
678 {
679 &gEfiCustomModeEnableGuid,
680 EFI_CUSTOM_MODE_NAME,
681 {
682 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
683 0,
684 VARIABLE_ATTRIBUTE_NV_BS,
685 sizeof (UINT8),
686 sizeof (UINT8)
687 }
688 },
689 {
690 &gEfiVendorKeysNvGuid,
691 EFI_VENDOR_KEYS_NV_VARIABLE_NAME,
692 {
693 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
694 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
695 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
696 sizeof (UINT8),
697 sizeof (UINT8)
698 }
699 },
700 {
701 &gEfiAuthenticatedVariableGuid,
702 AUTHVAR_KEYDB_NAME,
703 {
704 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
705 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
706 VARIABLE_ATTRIBUTE_NV_BS_RT_AW,
707 sizeof (UINT8),
708 MAX_UINTN
709 }
710 },
711 {
712 &gEfiCertDbGuid,
713 EFI_CERT_DB_NAME,
714 {
715 VAR_CHECK_VARIABLE_PROPERTY_REVISION,
716 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
717 VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
718 sizeof (UINT32),
719 MAX_UINTN
720 }
721 },
722 {
723 &gEdkiiVarErrorFlagGuid,
724 VAR_ERROR_FLAG_NAME,
725 {
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)
731 }
732 },
733 };
734
735 /**
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.
739
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.
745
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.
748
749 **/
750 EFI_STATUS
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
757 )
758 {
759 UINTN Index;
760 UINTN NameLength;
761
762 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
763 //
764 // Try list 1, exactly match.
765 //
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;
770 }
771 *VariableProperty = &mGlobalVariableList[Index].VariableProperty;
772 return EFI_SUCCESS;
773 }
774 }
775
776 //
777 // Try list 2.
778 //
779 NameLength = StrLen (VariableName) - 4;
780 for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
781 if (WildcardMatch) {
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;
790 }
791 *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
792 return EFI_SUCCESS;
793 }
794 }
795 if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {
796 if (VarCheckFunction != NULL) {
797 *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
798 }
799 *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
800 return EFI_SUCCESS;
801 }
802 }
803
804 //
805 // The variable name is not in the lists.
806 //
807 return EFI_INVALID_PARAMETER;
808 }
809
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;
815 }
816 *VariableProperty = &mImageSecurityVariableList[Index].VariableProperty;
817 return EFI_SUCCESS;
818 }
819 }
820
821 return EFI_INVALID_PARAMETER;
822 }
823
824 //
825 // It is not global variable or image security database variable.
826 //
827 return EFI_SUCCESS;
828 }
829
830 /**
831 Get variable property for variables managed by Varaible driver.
832
833 @param[in] VariableName Pointer to variable name.
834 @param[in] VendorGuid Variable Vendor Guid.
835
836 @return Pointer to variable property.
837
838 **/
839 VAR_CHECK_VARIABLE_PROPERTY *
840 GetVariableDriverVariableProperty (
841 IN CHAR16 *VariableName,
842 IN EFI_GUID *VendorGuid
843 )
844 {
845 UINTN Index;
846
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;
850 }
851 }
852
853 return NULL;
854 }
855
856 /**
857 Internal SetVariable check.
858
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.
864
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.
871
872 **/
873 EFI_STATUS
874 EFIAPI
875 InternalVarCheckSetVariableCheck (
876 IN CHAR16 *VariableName,
877 IN EFI_GUID *VendorGuid,
878 IN UINT32 Attributes,
879 IN UINTN DataSize,
880 IN VOID *Data
881 )
882 {
883 EFI_STATUS Status;
884 UINTN Index;
885 LIST_ENTRY *Link;
886 VAR_CHECK_VARIABLE_ENTRY *Entry;
887 CHAR16 *Name;
888 VAR_CHECK_VARIABLE_PROPERTY *Property;
889 INTERNAL_VAR_CHECK_FUNCTION VarCheckFunction;
890
891 if (!mEndOfDxe) {
892 //
893 // Only do check after End Of Dxe.
894 //
895 return EFI_SUCCESS;
896 }
897
898 Property = NULL;
899 VarCheckFunction = NULL;
900
901 for ( Link = GetFirstNode (&mVarCheckVariableList)
902 ; !IsNull (&mVarCheckVariableList, Link)
903 ; Link = GetNextNode (&mVarCheckVariableList, Link)
904 ) {
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;
909 break;
910 }
911 }
912 if (Property == NULL) {
913 Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);
914 }
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));
919 return Status;
920 }
921 }
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;
926 }
927 if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {
928 //
929 // Not to delete variable.
930 //
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;
934 }
935 if (DataSize != 0) {
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;
939 }
940 if (VarCheckFunction != NULL) {
941 Status = VarCheckFunction (
942 Property,
943 DataSize,
944 Data
945 );
946 if (EFI_ERROR (Status)) {
947 DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
948 return Status;
949 }
950 }
951 }
952 }
953 }
954
955 for (Index = 0; Index < mNumberOfHandler; Index ++) {
956 Status = mHandlerTable[Index] (
957 VariableName,
958 VendorGuid,
959 Attributes,
960 DataSize,
961 Data
962 );
963 if (EFI_ERROR (Status)) {
964 DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
965 return Status;
966 }
967 }
968 return EFI_SUCCESS;
969 }
970
971 /**
972 Reallocates more global memory to store the registered handler list.
973
974 @retval RETURN_SUCCESS Reallocate memory successfully.
975 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocate.
976
977 **/
978 RETURN_STATUS
979 EFIAPI
980 ReallocateHandlerTable (
981 VOID
982 )
983 {
984 VAR_CHECK_SET_VARIABLE_CHECK_HANDLER *HandlerTable;
985
986 //
987 // Reallocate memory for check handler table.
988 //
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),
992 mHandlerTable
993 );
994
995 //
996 // No enough resource to allocate.
997 //
998 if (HandlerTable == NULL) {
999 return RETURN_OUT_OF_RESOURCES;
1000 }
1001
1002 mHandlerTable = HandlerTable;
1003 //
1004 // Increase max handler number.
1005 //
1006 mMaxNumberOfHandler = mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE;
1007 return RETURN_SUCCESS;
1008 }
1009
1010 /**
1011 Register SetVariable check handler.
1012
1013 @param[in] Handler Pointer to check handler.
1014
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.
1022
1023 **/
1024 EFI_STATUS
1025 EFIAPI
1026 VarCheckRegisterSetVariableCheckHandler (
1027 IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
1028 )
1029 {
1030 EFI_STATUS Status;
1031
1032 if (Handler == NULL) {
1033 return EFI_INVALID_PARAMETER;
1034 }
1035
1036 if (mEndOfDxe) {
1037 return EFI_ACCESS_DENIED;
1038 }
1039
1040 DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));
1041
1042 //
1043 // Check whether the handler list is enough to store new handler.
1044 //
1045 if (mNumberOfHandler == mMaxNumberOfHandler) {
1046 //
1047 // Allocate more resources for new handler.
1048 //
1049 Status = ReallocateHandlerTable();
1050 if (EFI_ERROR (Status)) {
1051 return Status;
1052 }
1053 }
1054
1055 //
1056 // Register new handler into the handler list.
1057 //
1058 mHandlerTable[mNumberOfHandler] = Handler;
1059 mNumberOfHandler ++;
1060
1061 return EFI_SUCCESS;
1062 }
1063
1064 /**
1065 Variable property get function.
1066
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.
1070
1071 @return Pointer to the property of variable specified by the Name and Guid.
1072
1073 **/
1074 VAR_CHECK_VARIABLE_PROPERTY *
1075 VariablePropertyGetFunction (
1076 IN CHAR16 *Name,
1077 IN EFI_GUID *Guid,
1078 IN BOOLEAN WildcardMatch
1079 )
1080 {
1081 LIST_ENTRY *Link;
1082 VAR_CHECK_VARIABLE_ENTRY *Entry;
1083 CHAR16 *VariableName;
1084 VAR_CHECK_VARIABLE_PROPERTY *Property;
1085
1086 for ( Link = GetFirstNode (&mVarCheckVariableList)
1087 ; !IsNull (&mVarCheckVariableList, Link)
1088 ; Link = GetNextNode (&mVarCheckVariableList, Link)
1089 ) {
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;
1094 }
1095 }
1096
1097 Property = GetVariableDriverVariableProperty (Name, Guid);
1098 if (Property == NULL) {
1099 GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);
1100 }
1101
1102 return Property;
1103 }
1104
1105 /**
1106 Variable property set.
1107
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.
1111
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.
1118
1119 **/
1120 EFI_STATUS
1121 EFIAPI
1122 VarCheckVariablePropertySet (
1123 IN CHAR16 *Name,
1124 IN EFI_GUID *Guid,
1125 IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
1126 )
1127 {
1128 EFI_STATUS Status;
1129 VAR_CHECK_VARIABLE_ENTRY *Entry;
1130 CHAR16 *VariableName;
1131 VAR_CHECK_VARIABLE_PROPERTY *Property;
1132
1133 if (Name == NULL || Name[0] == 0 || Guid == NULL) {
1134 return EFI_INVALID_PARAMETER;
1135 }
1136
1137 if (VariableProperty == NULL) {
1138 return EFI_INVALID_PARAMETER;
1139 }
1140
1141 if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
1142 return EFI_INVALID_PARAMETER;
1143 }
1144
1145 if (mEndOfDxe) {
1146 return EFI_ACCESS_DENIED;
1147 }
1148
1149 Status = EFI_SUCCESS;
1150
1151 AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
1152
1153 Property = VariablePropertyGetFunction (Name, Guid, FALSE);
1154 if (Property != NULL) {
1155 CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
1156 } else {
1157 Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
1158 if (Entry == NULL) {
1159 Status = EFI_OUT_OF_RESOURCES;
1160 goto Done;
1161 }
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);
1167 }
1168
1169 Done:
1170 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
1171
1172 return Status;
1173 }
1174
1175 /**
1176 Internal variable property get.
1177
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.
1181
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.
1184
1185 **/
1186 EFI_STATUS
1187 EFIAPI
1188 InternalVarCheckVariablePropertyGet (
1189 IN CHAR16 *Name,
1190 IN EFI_GUID *Guid,
1191 OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
1192 )
1193 {
1194 LIST_ENTRY *Link;
1195 VARIABLE_ENTRY *Entry;
1196 CHAR16 *VariableName;
1197 BOOLEAN Found;
1198 VAR_CHECK_VARIABLE_PROPERTY *Property;
1199
1200 Found = FALSE;
1201
1202 Property = VariablePropertyGetFunction (Name, Guid, TRUE);
1203 if (Property != NULL) {
1204 CopyMem (VariableProperty, Property, sizeof (*VariableProperty));
1205 Found = TRUE;
1206 }
1207
1208 for ( Link = GetFirstNode (&mLockedVariableList)
1209 ; !IsNull (&mLockedVariableList, Link)
1210 ; Link = GetNextNode (&mLockedVariableList, Link)
1211 ) {
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;
1216 if (!Found) {
1217 VariableProperty->Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
1218 Found = TRUE;
1219 }
1220 }
1221 }
1222
1223 return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
1224 }
1225
1226 /**
1227 Variable property get.
1228
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.
1232
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.
1236
1237 **/
1238 EFI_STATUS
1239 EFIAPI
1240 VarCheckVariablePropertyGet (
1241 IN CHAR16 *Name,
1242 IN EFI_GUID *Guid,
1243 OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
1244 )
1245 {
1246 EFI_STATUS Status;
1247
1248 if (Name == NULL || Name[0] == 0 || Guid == NULL) {
1249 return EFI_INVALID_PARAMETER;
1250 }
1251
1252 if (VariableProperty == NULL) {
1253 return EFI_INVALID_PARAMETER;
1254 }
1255
1256 AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
1257
1258 Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty);
1259
1260 ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
1261
1262 return Status;
1263 }
1264