1 /** @file 2 Implementation functions and structures for var check uefi library. 3 4 Copyright (c) 2015 - 2016, 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 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 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 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 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 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_KEY_EXCHANGE_KEY_NAME, 430 { 431 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 432 0, 433 VARIABLE_ATTRIBUTE_NV_BS_RT_AT, 434 1, 435 MAX_UINTN 436 }, 437 NULL 438 }, 439 { 440 EFI_PLATFORM_KEY_NAME, 441 { 442 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 443 0, 444 VARIABLE_ATTRIBUTE_NV_BS_RT_AT, 445 1, 446 MAX_UINTN 447 }, 448 NULL 449 }, 450 { 451 EFI_SIGNATURE_SUPPORT_NAME, 452 { 453 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 454 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, 455 VARIABLE_ATTRIBUTE_BS_RT, 456 sizeof (EFI_GUID), 457 MAX_UINTN 458 }, 459 InternalVarCheckSizeArray 460 }, 461 { 462 EFI_SECURE_BOOT_MODE_NAME, 463 { 464 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 465 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, 466 VARIABLE_ATTRIBUTE_BS_RT, 467 sizeof (UINT8), 468 sizeof (UINT8) 469 }, 470 NULL 471 }, 472 { 473 EFI_KEK_DEFAULT_VARIABLE_NAME, 474 { 475 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 476 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, 477 VARIABLE_ATTRIBUTE_BS_RT, 478 1, 479 MAX_UINTN 480 }, 481 NULL 482 }, 483 { 484 EFI_PK_DEFAULT_VARIABLE_NAME, 485 { 486 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 487 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, 488 VARIABLE_ATTRIBUTE_BS_RT, 489 1, 490 MAX_UINTN 491 }, 492 NULL 493 }, 494 { 495 EFI_DB_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_DBX_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_DBT_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_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, 529 { 530 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 531 0, 532 VARIABLE_ATTRIBUTE_BS_RT, 533 sizeof (UINT64), 534 sizeof (UINT64) 535 }, 536 NULL 537 }, 538 { 539 EFI_OS_INDICATIONS_VARIABLE_NAME, 540 { 541 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 542 0, 543 VARIABLE_ATTRIBUTE_NV_BS_RT, 544 sizeof (UINT64), 545 sizeof (UINT64) 546 }, 547 NULL 548 }, 549 { 550 EFI_VENDOR_KEYS_VARIABLE_NAME, 551 { 552 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 553 VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, 554 VARIABLE_ATTRIBUTE_BS_RT, 555 sizeof (UINT8), 556 sizeof (UINT8) 557 }, 558 NULL 559 }, 560 }; 561 562 UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = { 563 { 564 L"Boot####", 565 { 566 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 567 0, 568 VARIABLE_ATTRIBUTE_NV_BS_RT, 569 sizeof (UINT32) + sizeof (UINT16), 570 MAX_UINTN 571 }, 572 InternalVarCheckLoadOption 573 }, 574 { 575 L"Driver####", 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"SysPrep####", 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"Key####", 598 { 599 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 600 0, 601 VARIABLE_ATTRIBUTE_NV_BS_RT, 602 sizeof (EFI_KEY_OPTION), 603 sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY) 604 }, 605 InternalVarCheckKeyOption 606 }, 607 { 608 L"PlatformRecovery####", 609 { 610 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 611 0, 612 VARIABLE_ATTRIBUTE_BS_RT, 613 sizeof (UINT32) + sizeof (UINT16), 614 MAX_UINTN 615 }, 616 InternalVarCheckLoadOption 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 // 660 // EFI_HARDWARE_ERROR_VARIABLE 661 // 662 UEFI_DEFINED_VARIABLE_ENTRY mHwErrRecVariable = { 663 L"HwErrRec####", 664 { 665 VAR_CHECK_VARIABLE_PROPERTY_REVISION, 666 0, 667 VARIABLE_ATTRIBUTE_NV_BS_RT_HR, 668 1, 669 MAX_UINTN 670 }, 671 NULL 672 }; 673 674 EFI_GUID *mUefiDefinedGuid[] = { 675 &gEfiGlobalVariableGuid, 676 &gEfiImageSecurityDatabaseGuid, 677 &gEfiHardwareErrorVariableGuid 678 }; 679 680 /** 681 Check if a Unicode character is an upper case hexadecimal character. 682 683 This function checks if a Unicode character is an upper case 684 hexadecimal character. The valid upper case hexadecimal character is 685 L'0' to L'9', or L'A' to L'F'. 686 687 688 @param[in] Char The character to check against. 689 690 @retval TRUE If the Char is an upper case hexadecmial character. 691 @retval FALSE If the Char is not an upper case hexadecmial character. 692 693 **/ 694 BOOLEAN 695 EFIAPI 696 VarCheckUefiIsHexaDecimalDigitCharacter ( 697 IN CHAR16 Char 698 ) 699 { 700 return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F')); 701 } 702 703 /** 704 705 This code checks if variable is hardware error record variable or not. 706 707 According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid 708 and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value. 709 710 @param[in] VariableName Pointer to variable name. 711 @param[in] VendorGuid Variable Vendor Guid. 712 713 @retval TRUE Variable is hardware error record variable. 714 @retval FALSE Variable is not hardware error record variable. 715 716 **/ 717 BOOLEAN 718 EFIAPI 719 IsHwErrRecVariable ( 720 IN CHAR16 *VariableName, 721 IN EFI_GUID *VendorGuid 722 ) 723 { 724 if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) || 725 (StrLen (VariableName) != StrLen (L"HwErrRec####")) || 726 (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) || 727 !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x8]) || 728 !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x9]) || 729 !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xA]) || 730 !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xB])) { 731 return FALSE; 732 } 733 734 return TRUE; 735 } 736 737 /** 738 Get UEFI defined var check function. 739 740 @param[in] VariableName Pointer to variable name. 741 @param[in] VendorGuid Pointer to variable vendor GUID. 742 @param[out] VariableProperty Pointer to variable property. 743 744 @return Internal var check function, NULL if no specific check function. 745 746 **/ 747 INTERNAL_VAR_CHECK_FUNCTION 748 GetUefiDefinedVarCheckFunction ( 749 IN CHAR16 *VariableName, 750 IN EFI_GUID *VendorGuid, 751 OUT VAR_CHECK_VARIABLE_PROPERTY **VariableProperty 752 ) 753 { 754 UINTN Index; 755 UINTN NameLength; 756 757 if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) { 758 // 759 // Try list 1, exactly match. 760 // 761 for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) { 762 if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) { 763 *VariableProperty = &(mGlobalVariableList[Index].VariableProperty); 764 return mGlobalVariableList[Index].CheckFunction; 765 } 766 } 767 768 // 769 // Try list 2. 770 // 771 NameLength = StrLen (VariableName) - 4; 772 for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) { 773 if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) && 774 (StrnCmp (VariableName, mGlobalVariableList2[Index].Name, NameLength) == 0) && 775 VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength]) && 776 VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) && 777 VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) && 778 VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) { 779 *VariableProperty = &(mGlobalVariableList2[Index].VariableProperty); 780 return mGlobalVariableList2[Index].CheckFunction; 781 } 782 } 783 } 784 785 return NULL; 786 } 787 788 /** 789 SetVariable check handler UEFI defined. 790 791 @param[in] VariableName Name of Variable to set. 792 @param[in] VendorGuid Variable vendor GUID. 793 @param[in] Attributes Attribute value of the variable. 794 @param[in] DataSize Size of Data to set. 795 @param[in] Data Data pointer. 796 797 @retval EFI_SUCCESS The SetVariable check result was success. 798 @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, GUID, 799 DataSize and Data value was supplied. 800 @retval EFI_WRITE_PROTECTED The variable in question is read-only. 801 802 **/ 803 EFI_STATUS 804 EFIAPI 805 SetVariableCheckHandlerUefiDefined ( 806 IN CHAR16 *VariableName, 807 IN EFI_GUID *VendorGuid, 808 IN UINT32 Attributes, 809 IN UINTN DataSize, 810 IN VOID *Data 811 ) 812 { 813 EFI_STATUS Status; 814 UINTN Index; 815 VAR_CHECK_VARIABLE_PROPERTY Property; 816 VAR_CHECK_VARIABLE_PROPERTY *VarCheckProperty; 817 INTERNAL_VAR_CHECK_FUNCTION VarCheckFunction; 818 819 if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) { 820 // 821 // Do not check delete variable. 822 // 823 return EFI_SUCCESS; 824 } 825 826 if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { 827 if (!IsHwErrRecVariable (VariableName, VendorGuid)) { 828 return EFI_INVALID_PARAMETER; 829 } 830 } 831 832 for (Index = 0; Index < sizeof (mUefiDefinedGuid)/sizeof (mUefiDefinedGuid[0]); Index++) { 833 if (CompareGuid (VendorGuid, mUefiDefinedGuid[Index])) { 834 if (VarCheckLibVariablePropertyGet (VariableName, VendorGuid, &Property) == EFI_NOT_FOUND) { 835 // 836 // To prevent name collisions with possible future globally defined variables, 837 // other internal firmware data variables that are not defined here must be 838 // saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or 839 // any other GUID defined by the UEFI Specification. Implementations must 840 // only permit the creation of variables with a UEFI Specification-defined 841 // VendorGuid when these variables are documented in the UEFI Specification. 842 // 843 DEBUG ((EFI_D_INFO, "UEFI Variable Check fail %r - %s not in %g namespace\n", EFI_INVALID_PARAMETER, VariableName, VendorGuid)); 844 return EFI_INVALID_PARAMETER; 845 } 846 } 847 } 848 849 if (DataSize == 0) { 850 return EFI_SUCCESS; 851 } 852 853 VarCheckProperty = NULL; 854 VarCheckFunction = GetUefiDefinedVarCheckFunction (VariableName, VendorGuid, &VarCheckProperty); 855 if (VarCheckFunction != NULL) { 856 Status = VarCheckFunction ( 857 VarCheckProperty, 858 DataSize, 859 Data 860 ); 861 if (EFI_ERROR (Status)) { 862 DEBUG ((EFI_D_INFO, "UEFI Variable Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName)); 863 return Status; 864 } 865 } 866 867 return EFI_SUCCESS; 868 } 869 870 /** 871 Variable property set for UEFI defined variables. 872 873 **/ 874 VOID 875 VariablePropertySetUefiDefined ( 876 VOID 877 ) 878 { 879 UINTN Index; 880 881 // 882 // EFI_GLOBAL_VARIABLE 883 // 884 for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) { 885 VarCheckLibVariablePropertySet ( 886 mGlobalVariableList[Index].Name, 887 &gEfiGlobalVariableGuid, 888 &mGlobalVariableList[Index].VariableProperty 889 ); 890 } 891 for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) { 892 VarCheckLibVariablePropertySet ( 893 mGlobalVariableList2[Index].Name, 894 &gEfiGlobalVariableGuid, 895 &mGlobalVariableList2[Index].VariableProperty 896 ); 897 } 898 899 // 900 // EFI_IMAGE_SECURITY_DATABASE_GUID 901 // 902 for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) { 903 VarCheckLibVariablePropertySet ( 904 mImageSecurityVariableList[Index].Name, 905 &gEfiImageSecurityDatabaseGuid, 906 &mImageSecurityVariableList[Index].VariableProperty 907 ); 908 } 909 910 // 911 // EFI_HARDWARE_ERROR_VARIABLE 912 // 913 VarCheckLibVariablePropertySet ( 914 mHwErrRecVariable.Name, 915 &gEfiHardwareErrorVariableGuid, 916 &mHwErrRecVariable.VariableProperty 917 ); 918 } 919 920 /** 921 Constructor function of VarCheckUefiLib to set property and 922 register SetVariable check handler for UEFI defined variables. 923 924 @param[in] ImageHandle The firmware allocated handle for the EFI image. 925 @param[in] SystemTable A pointer to the EFI System Table. 926 927 @retval EFI_SUCCESS The constructor executed correctly. 928 929 **/ 930 EFI_STATUS 931 EFIAPI 932 VarCheckUefiLibNullClassConstructor ( 933 IN EFI_HANDLE ImageHandle, 934 IN EFI_SYSTEM_TABLE *SystemTable 935 ) 936 { 937 VariablePropertySetUefiDefined (); 938 VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerUefiDefined); 939 940 return EFI_SUCCESS; 941 } 942