1/** @file 2 Implementation functions and structures for var check uefi library. 3 4Copyright (c) 2015, 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/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 26typedef 27EFI_STATUS 28(EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) ( 29 IN VAR_CHECK_VARIABLE_PROPERTY *Propery, 30 IN UINTN DataSize, 31 IN VOID *Data 32 ); 33 34typedef 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**/ 51EFI_STATUS 52EFIAPI 53InternalVarCheckLoadOption ( 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**/ 111EFI_STATUS 112EFIAPI 113InternalVarCheckKeyOption ( 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**/ 137EFI_STATUS 138EFIAPI 139InternalVarCheckDevicePath ( 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**/ 162EFI_STATUS 163EFIAPI 164InternalVarCheckAsciiString ( 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**/ 196EFI_STATUS 197EFIAPI 198InternalVarCheckSizeArray ( 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// 218UEFI_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 584UEFI_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// 645UEFI_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// 684UEFI_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 696EFI_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**/ 716BOOLEAN 717EFIAPI 718VarCheckUefiIsHexaDecimalDigitCharacter ( 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**/ 739BOOLEAN 740EFIAPI 741IsHwErrRecVariable ( 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**/ 769INTERNAL_VAR_CHECK_FUNCTION 770GetUefiDefinedVarCheckFunction ( 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**/ 825EFI_STATUS 826EFIAPI 827SetVariableCheckHandlerUefiDefined ( 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**/ 896VOID 897VariablePropertySetUefiDefined ( 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**/ 952EFI_STATUS 953EFIAPI 954VarCheckUefiLibNullClassConstructor ( 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