Changeset 58459 in vbox for trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib
- Timestamp:
- Oct 28, 2015 8:17:18 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/Firmware
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/Firmware
-
Property svn:mergeinfo
set to (toggle deleted branches)
/vendor/edk2/current 103735-103757
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
r48674 r58459 3 3 only supports relocating IA32, x64, IPF, and EBC images. 4 4 5 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> 5 Caution: This file requires additional review when modified. 6 This library will have external input - PE/COFF image. 7 This external input must be validated carefully to avoid security issue like 8 buffer overflow, integer overflow. 9 10 The basic guideline is that caller need provide ImageContext->ImageRead () with the 11 necessary data range check, to make sure when this library reads PE/COFF image, the 12 PE image buffer is always in valid range. 13 This library will also do some additional check for PE header fields. 14 15 PeCoffLoaderGetPeHeader() routine will do basic check for PE/COFF header. 16 PeCoffLoaderGetImageInfo() routine will do basic check for whole PE/COFF image. 17 18 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 6 19 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 7 20 This program and the accompanying materials … … 16 29 17 30 #include "BasePeCoffLibInternals.h" 31 32 /** 33 Adjust some fields in section header for TE image. 34 35 @param SectionHeader Pointer to the section header. 36 @param TeStrippedOffset Size adjust for the TE image. 37 38 **/ 39 VOID 40 PeCoffLoaderAdjustOffsetForTeImage ( 41 EFI_IMAGE_SECTION_HEADER *SectionHeader, 42 UINT32 TeStrippedOffset 43 ) 44 { 45 SectionHeader->VirtualAddress -= TeStrippedOffset; 46 SectionHeader->PointerToRawData -= TeStrippedOffset; 47 } 18 48 19 49 /** … … 49 79 /** 50 80 Retrieves the PE or TE Header from a PE/COFF or TE image. 51 Also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader, 81 82 Caution: This function may receive untrusted input. 83 PE/COFF image is external input, so this routine will 84 also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader, 52 85 SizeOfHeader, Section Data Region and Security Data Region be in PE image range. 53 86 … … 68 101 EFI_IMAGE_DOS_HEADER DosHdr; 69 102 UINTN Size; 103 UINTN ReadSize; 70 104 UINT16 Magic; 71 105 UINT32 SectionHeaderOffset; 72 106 UINT32 Index; 107 UINT32 HeaderWithoutDataDir; 73 108 CHAR8 BufferData; 74 109 UINTN NumberOfSections; … … 79 114 // 80 115 Size = sizeof (EFI_IMAGE_DOS_HEADER); 116 ReadSize = Size; 81 117 Status = ImageContext->ImageRead ( 82 118 ImageContext->Handle, … … 85 121 &DosHdr 86 122 ); 87 if (RETURN_ERROR (Status) ) {123 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 88 124 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 125 if (Size != ReadSize) { 126 Status = RETURN_UNSUPPORTED; 127 } 89 128 return Status; 90 129 } … … 106 145 // 107 146 Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); 147 ReadSize = Size; 108 148 Status = ImageContext->ImageRead ( 109 149 ImageContext->Handle, … … 112 152 Hdr.Pe32 113 153 ); 114 if (RETURN_ERROR (Status) ) {154 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 115 155 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 156 if (Size != ReadSize) { 157 Status = RETURN_UNSUPPORTED; 158 } 116 159 return Status; 117 160 } … … 132 175 ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; 133 176 177 // 178 // Check the StrippedSize. 179 // 180 if (sizeof (EFI_TE_IMAGE_HEADER) >= (UINT32)Hdr.Te->StrippedSize) { 181 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 182 return RETURN_UNSUPPORTED; 183 } 184 185 // 186 // Check the SizeOfHeaders field. 187 // 188 if (Hdr.Te->BaseOfCode <= Hdr.Te->StrippedSize) { 189 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 190 return RETURN_UNSUPPORTED; 191 } 192 193 // 194 // Read last byte of Hdr.Te->SizeOfHeaders from the file. 195 // 196 Size = 1; 197 ReadSize = Size; 198 Status = ImageContext->ImageRead ( 199 ImageContext->Handle, 200 ImageContext->SizeOfHeaders - 1, 201 &Size, 202 &BufferData 203 ); 204 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 205 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 206 if (Size != ReadSize) { 207 Status = RETURN_UNSUPPORTED; 208 } 209 return Status; 210 } 211 212 // 213 // TE Image Data Directory Entry size is non-zero, but the Data Directory Virtual Address is zero. 214 // This case is not a valid TE image. 215 // 216 if ((Hdr.Te->DataDirectory[0].Size != 0 && Hdr.Te->DataDirectory[0].VirtualAddress == 0) || 217 (Hdr.Te->DataDirectory[1].Size != 0 && Hdr.Te->DataDirectory[1].VirtualAddress == 0)) { 218 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 219 return RETURN_UNSUPPORTED; 220 } 134 221 } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { 135 222 ImageContext->IsTeImage = FALSE; … … 140 227 if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 141 228 // 142 // 1. Check FileHeader.SizeOfOptionalHeaderfiled.229 // 1. Check OptionalHeader.NumberOfRvaAndSizes filed. 143 230 // 144 231 if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) { 232 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 145 233 return RETURN_UNSUPPORTED; 146 234 } 147 235 148 236 // 149 // 2. Check the OptionalHeader.SizeOfHeaders field. 150 // This field will be use like the following mode, so just compare the result. 151 // The DataDirectory array begin with 1, not 0, so here use < to compare not <=. 152 // 153 if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes) { 154 if (Hdr.Pe32->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) { 155 return RETURN_UNSUPPORTED; 156 } 157 } 158 159 // 160 // Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file 237 // 2. Check the FileHeader.SizeOfOptionalHeader field. 238 // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so 239 // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow. 240 // 241 HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER32) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; 242 if (((UINT32)Hdr.Pe32->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) != 243 Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) { 244 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 245 return RETURN_UNSUPPORTED; 246 } 247 248 SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32->FileHeader.SizeOfOptionalHeader; 249 // 250 // 3. Check the FileHeader.NumberOfSections field. 251 // 252 if (Hdr.Pe32->OptionalHeader.SizeOfImage <= SectionHeaderOffset) { 253 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 254 return RETURN_UNSUPPORTED; 255 } 256 if ((Hdr.Pe32->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32->FileHeader.NumberOfSections) { 257 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 258 return RETURN_UNSUPPORTED; 259 } 260 261 // 262 // 4. Check the OptionalHeader.SizeOfHeaders field. 263 // 264 if (Hdr.Pe32->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) { 265 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 266 return RETURN_UNSUPPORTED; 267 } 268 if (Hdr.Pe32->OptionalHeader.SizeOfHeaders >= Hdr.Pe32->OptionalHeader.SizeOfImage) { 269 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 270 return RETURN_UNSUPPORTED; 271 } 272 if ((Hdr.Pe32->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32->FileHeader.NumberOfSections) { 273 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 274 return RETURN_UNSUPPORTED; 275 } 276 277 // 278 // 4.2 Read last byte of Hdr.Pe32.OptionalHeader.SizeOfHeaders from the file. 161 279 // 162 280 Size = 1; 281 ReadSize = Size; 163 282 Status = ImageContext->ImageRead ( 164 283 ImageContext->Handle, … … 167 286 &BufferData 168 287 ); 169 if (RETURN_ERROR (Status)) { 288 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 289 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 290 if (Size != ReadSize) { 291 Status = RETURN_UNSUPPORTED; 292 } 170 293 return Status; 171 294 } … … 183 306 if ((UINT32) (~0) - Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress < 184 307 Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) { 185 return RETURN_INVALID_PARAMETER; 308 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 309 return RETURN_UNSUPPORTED; 186 310 } 187 311 188 312 // 189 // Read section header from file313 // Read last byte of section header from file 190 314 // 191 315 Size = 1; 316 ReadSize = Size; 192 317 Status = ImageContext->ImageRead ( 193 318 ImageContext->Handle, … … 197 322 &BufferData 198 323 ); 199 if (RETURN_ERROR (Status)) { 324 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 325 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 326 if (Size != ReadSize) { 327 Status = RETURN_UNSUPPORTED; 328 } 200 329 return Status; 201 330 } … … 213 342 } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 214 343 // 215 // 1. Check FileHeader. SizeOfOptionalHeaderfiled.344 // 1. Check FileHeader.NumberOfRvaAndSizes filed. 216 345 // 217 346 if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) { 347 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 218 348 return RETURN_UNSUPPORTED; 219 349 } 220 221 // 222 // 2. Check the OptionalHeader.SizeOfHeaders field. 223 // This field will be use like the following mode, so just compare the result. 224 // The DataDirectory array begin with 1, not 0, so here use < to compare not <=. 225 // 226 if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1 < Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes) { 227 if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders < (UINT32)((UINT8 *)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *) &Hdr)) { 228 return RETURN_UNSUPPORTED; 229 } 230 } 231 232 // 233 // Read Hdr.Pe32.OptionalHeader.SizeOfHeaders data from file 350 // 351 // 2. Check the FileHeader.SizeOfOptionalHeader field. 352 // OptionalHeader.NumberOfRvaAndSizes is not bigger than 16, so 353 // OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) will not overflow. 354 // 355 HeaderWithoutDataDir = sizeof (EFI_IMAGE_OPTIONAL_HEADER64) - sizeof (EFI_IMAGE_DATA_DIRECTORY) * EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; 356 if (((UINT32)Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader - HeaderWithoutDataDir) != 357 Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY)) { 358 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 359 return RETURN_UNSUPPORTED; 360 } 361 362 SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader; 363 // 364 // 3. Check the FileHeader.NumberOfSections field. 365 // 366 if (Hdr.Pe32Plus->OptionalHeader.SizeOfImage <= SectionHeaderOffset) { 367 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 368 return RETURN_UNSUPPORTED; 369 } 370 if ((Hdr.Pe32Plus->OptionalHeader.SizeOfImage - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER <= Hdr.Pe32Plus->FileHeader.NumberOfSections) { 371 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 372 return RETURN_UNSUPPORTED; 373 } 374 375 // 376 // 4. Check the OptionalHeader.SizeOfHeaders field. 377 // 378 if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders <= SectionHeaderOffset) { 379 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 380 return RETURN_UNSUPPORTED; 381 } 382 if (Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders >= Hdr.Pe32Plus->OptionalHeader.SizeOfImage) { 383 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 384 return RETURN_UNSUPPORTED; 385 } 386 if ((Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - SectionHeaderOffset) / EFI_IMAGE_SIZEOF_SECTION_HEADER < (UINT32)Hdr.Pe32Plus->FileHeader.NumberOfSections) { 387 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 388 return RETURN_UNSUPPORTED; 389 } 390 391 // 392 // 4.2 Read last byte of Hdr.Pe32Plus.OptionalHeader.SizeOfHeaders from the file. 234 393 // 235 394 Size = 1; 395 ReadSize = Size; 236 396 Status = ImageContext->ImageRead ( 237 397 ImageContext->Handle, … … 240 400 &BufferData 241 401 ); 242 if (RETURN_ERROR (Status)) { 402 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 403 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 404 if (Size != ReadSize) { 405 Status = RETURN_UNSUPPORTED; 406 } 243 407 return Status; 244 408 } … … 256 420 if ((UINT32) (~0) - Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress < 257 421 Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size) { 258 return RETURN_INVALID_PARAMETER; 422 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 423 return RETURN_UNSUPPORTED; 259 424 } 260 425 261 426 // 262 // Read section header from file427 // Read last byte of section header from file 263 428 // 264 429 Size = 1; 430 ReadSize = Size; 265 431 Status = ImageContext->ImageRead ( 266 432 ImageContext->Handle, … … 270 436 &BufferData 271 437 ); 272 if (RETURN_ERROR (Status)) { 438 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 439 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 440 if (Size != ReadSize) { 441 Status = RETURN_UNSUPPORTED; 442 } 273 443 return Status; 274 444 } … … 318 488 // 319 489 Size = sizeof (EFI_IMAGE_SECTION_HEADER); 490 ReadSize = Size; 320 491 Status = ImageContext->ImageRead ( 321 492 ImageContext->Handle, … … 324 495 &SectionHeader 325 496 ); 326 if (RETURN_ERROR (Status)) { 497 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 498 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 499 if (Size != ReadSize) { 500 Status = RETURN_UNSUPPORTED; 501 } 327 502 return Status; 328 503 } 329 504 505 // 506 // Adjust some field in Section Header for TE image. 507 // 508 if (ImageContext->IsTeImage) { 509 PeCoffLoaderAdjustOffsetForTeImage (&SectionHeader, (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); 510 } 511 330 512 if (SectionHeader.SizeOfRawData > 0) { 331 513 // 514 // Section data should bigger than the Pe header. 515 // 516 if (SectionHeader.VirtualAddress < ImageContext->SizeOfHeaders || 517 SectionHeader.PointerToRawData < ImageContext->SizeOfHeaders) { 518 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 519 return RETURN_UNSUPPORTED; 520 } 521 522 // 332 523 // Check the member data to avoid overflow. 333 524 // 334 525 if ((UINT32) (~0) - SectionHeader.PointerToRawData < SectionHeader.SizeOfRawData) { 335 return RETURN_INVALID_PARAMETER; 526 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 527 return RETURN_UNSUPPORTED; 336 528 } 337 529 … … 341 533 // 342 534 Size = 1; 535 ReadSize = Size; 343 536 Status = ImageContext->ImageRead ( 344 537 ImageContext->Handle, … … 347 540 &BufferData 348 541 ); 349 if (RETURN_ERROR (Status)) { 542 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 543 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 544 if (Size != ReadSize) { 545 Status = RETURN_UNSUPPORTED; 546 } 350 547 return Status; 351 548 } … … 377 574 to invoking this service. 378 575 379 Also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader, 576 Caution: This function may receive untrusted input. 577 PE/COFF image is external input, so this routine will 578 also done many checks in PE image to make sure PE image DosHeader, PeOptionHeader, 380 579 SizeOfHeader, Section Data Region and Security Data Region be in PE image range. 381 580 … … 399 598 EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry; 400 599 UINTN Size; 600 UINTN ReadSize; 401 601 UINTN Index; 402 602 UINTN DebugDirectoryEntryRva; … … 407 607 UINT32 NumberOfRvaAndSizes; 408 608 UINT16 Magic; 609 UINT32 TeStrippedOffset; 409 610 410 611 if (ImageContext == NULL) { … … 428 629 // 429 630 if (!(ImageContext->IsTeImage)) { 631 TeStrippedOffset = 0; 430 632 if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 431 633 // … … 440 642 } 441 643 } else { 442 ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); 644 TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); 645 ImageContext->ImageAddress = (PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + TeStrippedOffset); 443 646 } 444 647 … … 474 677 ImageContext->RelocationsStripped = FALSE; 475 678 } 476 477 //478 // TE Image Relocation Data Directory Entry size is non-zero, but the Relocation Data Directory Virtual Address is zero.479 // This case is not a valid TE image.480 //481 if ((ImageContext->IsTeImage) && (Hdr.Te->DataDirectory[0].Size != 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) {482 return RETURN_INVALID_PARAMETER;483 }484 679 485 680 if (!(ImageContext->IsTeImage)) { … … 521 716 // 522 717 Size = sizeof (EFI_IMAGE_SECTION_HEADER); 718 ReadSize = Size; 523 719 Status = ImageContext->ImageRead ( 524 720 ImageContext->Handle, … … 527 723 &SectionHeader 528 724 ); 529 if (RETURN_ERROR (Status) ) {725 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 530 726 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 727 if (Size != ReadSize) { 728 Status = RETURN_UNSUPPORTED; 729 } 531 730 return Status; 532 731 } … … 548 747 // 549 748 Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); 749 ReadSize = Size; 550 750 Status = ImageContext->ImageRead ( 551 751 ImageContext->Handle, … … 554 754 &DebugEntry 555 755 ); 556 if (RETURN_ERROR (Status) ) {756 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 557 757 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 758 if (Size != ReadSize) { 759 Status = RETURN_UNSUPPORTED; 760 } 558 761 return Status; 559 762 } 763 764 // 765 // From PeCoff spec, when DebugEntry.RVA == 0 means this debug info will not load into memory. 766 // Here we will always load EFI_IMAGE_DEBUG_TYPE_CODEVIEW type debug info. so need adjust the 767 // ImageContext->ImageSize when DebugEntry.RVA == 0. 768 // 560 769 if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { 561 770 ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index); … … 582 791 // 583 792 Size = sizeof (EFI_IMAGE_SECTION_HEADER); 793 ReadSize = Size; 584 794 Status = ImageContext->ImageRead ( 585 795 ImageContext->Handle, … … 588 798 &SectionHeader 589 799 ); 590 if (RETURN_ERROR (Status) ) {800 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 591 801 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 802 if (Size != ReadSize) { 803 Status = RETURN_UNSUPPORTED; 804 } 592 805 return Status; 593 806 } … … 597 810 DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - 598 811 SectionHeader.VirtualAddress + 599 SectionHeader.PointerToRawData + 600 sizeof (EFI_TE_IMAGE_HEADER) - 601 Hdr.Te->StrippedSize; 812 SectionHeader.PointerToRawData - 813 TeStrippedOffset; 602 814 603 815 // … … 623 835 // 624 836 if ((++Index) == (UINTN)Hdr.Te->NumberOfSections) { 625 ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) ;837 ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) - TeStrippedOffset; 626 838 } 627 839 … … 635 847 // 636 848 Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); 849 ReadSize = Size; 637 850 Status = ImageContext->ImageRead ( 638 851 ImageContext->Handle, … … 641 854 &DebugEntry 642 855 ); 643 if (RETURN_ERROR (Status) ) {856 if (RETURN_ERROR (Status) || (Size != ReadSize)) { 644 857 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 858 if (Size != ReadSize) { 859 Status = RETURN_UNSUPPORTED; 860 } 645 861 return Status; 646 862 } … … 661 877 Converts an image address to the loaded address. 662 878 663 @param ImageContext The context of the image being loaded. 664 @param Address The relative virtual address to be converted to the loaded address. 879 @param ImageContext The context of the image being loaded. 880 @param Address The address to be converted to the loaded address. 881 @param TeStrippedOffset Stripped offset for TE image. 665 882 666 883 @return The converted address or NULL if the address can not be converted. … … 670 887 PeCoffLoaderImageAddress ( 671 888 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, 672 IN UINTN Address 889 IN UINTN Address, 890 IN UINTN TeStrippedOffset 673 891 ) 674 892 { … … 676 894 // Make sure that Address and ImageSize is correct for the loaded image. 677 895 // 678 if (Address >= ImageContext->ImageSize ) {896 if (Address >= ImageContext->ImageSize + TeStrippedOffset) { 679 897 ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; 680 898 return NULL; 681 899 } 682 900 683 return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address );901 return (CHAR8 *)((UINTN) ImageContext->ImageAddress + Address - TeStrippedOffset); 684 902 } 685 903 … … 724 942 EFI_IMAGE_DATA_DIRECTORY *RelocDir; 725 943 UINT64 Adjust; 944 EFI_IMAGE_BASE_RELOCATION *RelocBaseOrg; 726 945 EFI_IMAGE_BASE_RELOCATION *RelocBase; 727 946 EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; … … 737 956 UINT32 NumberOfRvaAndSizes; 738 957 UINT16 Magic; 958 UINT32 TeStrippedOffset; 739 959 740 960 ASSERT (ImageContext != NULL); … … 767 987 if (!(ImageContext->IsTeImage)) { 768 988 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset); 769 989 TeStrippedOffset = 0; 770 990 Magic = PeCoffLoaderGetPeHeaderMagicValue (Hdr); 771 991 … … 800 1020 // the optional header to verify a desired directory entry is there. 801 1021 // 802 803 if ((NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) && (RelocDir->Size > 0)) { 804 RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); 805 RelocBaseEnd = PeCoffLoaderImageAddress ( 806 ImageContext, 807 RelocDir->VirtualAddress + RelocDir->Size - 1 808 ); 809 if (RelocBase == NULL || RelocBaseEnd == NULL) { 810 return RETURN_LOAD_ERROR; 811 } 812 } else { 813 // 814 // Set base and end to bypass processing below. 815 // 816 RelocBase = RelocBaseEnd = NULL; 1022 if ((NumberOfRvaAndSizes < EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC)) { 1023 RelocDir = NULL; 817 1024 } 818 1025 } else { 819 1026 Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress); 820 Adjust = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->ImageBase); 1027 TeStrippedOffset = (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); 1028 Adjust = (UINT64) (BaseAddress - (Hdr.Te->ImageBase + TeStrippedOffset)); 821 1029 if (Adjust != 0) { 822 Hdr.Te->ImageBase = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));1030 Hdr.Te->ImageBase = (UINT64) (BaseAddress - TeStrippedOffset); 823 1031 } 824 1032 … … 827 1035 // 828 1036 RelocDir = &Hdr.Te->DataDirectory[0]; 829 if (RelocDir->Size > 0) { 830 RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)( 831 ImageContext->ImageAddress + 832 RelocDir->VirtualAddress + 833 sizeof(EFI_TE_IMAGE_HEADER) - 834 Hdr.Te->StrippedSize 835 ); 836 RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1); 837 } else { 838 // 839 // Set base and end to bypass processing below. 840 // 841 RelocBase = RelocBaseEnd = NULL; 842 } 843 } 1037 } 1038 1039 if ((RelocDir != NULL) && (RelocDir->Size > 0)) { 1040 RelocBase = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress, TeStrippedOffset); 1041 RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) PeCoffLoaderImageAddress (ImageContext, 1042 RelocDir->VirtualAddress + RelocDir->Size - 1, 1043 TeStrippedOffset 1044 ); 1045 if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) { 1046 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 1047 return RETURN_LOAD_ERROR; 1048 } 1049 } else { 1050 // 1051 // Set base and end to bypass processing below. 1052 // 1053 RelocBase = RelocBaseEnd = NULL; 1054 } 1055 RelocBaseOrg = RelocBase; 844 1056 845 1057 // … … 854 1066 855 1067 Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); 856 RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock); 857 858 // 859 // Make sure RelocEnd is in the Image range. 860 // 861 if ((CHAR8 *) RelocEnd < (CHAR8 *)((UINTN) ImageContext->ImageAddress) || 862 (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + (UINTN)ImageContext->ImageSize)) { 1068 // 1069 // Add check for RelocBase->SizeOfBlock field. 1070 // 1071 if (RelocBase->SizeOfBlock == 0) { 863 1072 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 864 1073 return RETURN_LOAD_ERROR; 865 1074 } 866 867 if (!(ImageContext->IsTeImage)) { 868 FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress); 869 if (FixupBase == NULL) { 1075 if ((UINTN)RelocBase > MAX_ADDRESS - RelocBase->SizeOfBlock) { 1076 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 1077 return RETURN_LOAD_ERROR; 1078 } 1079 1080 RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock); 1081 if ((UINTN)RelocEnd > (UINTN)RelocBaseOrg + RelocDir->Size) { 1082 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 1083 return RETURN_LOAD_ERROR; 1084 } 1085 FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress, TeStrippedOffset); 1086 if (FixupBase == NULL) { 1087 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 1088 return RETURN_LOAD_ERROR; 1089 } 1090 1091 // 1092 // Run this relocation record 1093 // 1094 while (Reloc < RelocEnd) { 1095 Fixup = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress + (*Reloc & 0xFFF), TeStrippedOffset); 1096 if (Fixup == NULL) { 1097 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 870 1098 return RETURN_LOAD_ERROR; 871 1099 } 872 } else {873 FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +874 RelocBase->VirtualAddress +875 sizeof(EFI_TE_IMAGE_HEADER) -876 Hdr.Te->StrippedSize877 );878 }879 880 //881 // Run this relocation record882 //883 while (Reloc < RelocEnd) {884 885 Fixup = FixupBase + (*Reloc & 0xFFF);886 1100 switch ((*Reloc) >> 12) { 887 1101 case EFI_IMAGE_REL_BASED_ABSOLUTE: … … 950 1164 RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; 951 1165 } 1166 ASSERT ((UINTN)FixupData <= (UINTN)ImageContext->FixupData + ImageContext->FixupDataSize); 952 1167 953 1168 // … … 1013 1228 CHAR8 *Base; 1014 1229 CHAR8 *End; 1015 CHAR8 *MaxEnd;1016 1230 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; 1017 1231 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; … … 1025 1239 EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; 1026 1240 CHAR16 *String; 1027 1241 UINT32 Offset; 1242 UINT32 TeStrippedOffset; 1028 1243 1029 1244 ASSERT (ImageContext != NULL); … … 1112 1327 ); 1113 1328 NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections); 1329 TeStrippedOffset = 0; 1114 1330 } else { 1115 1331 Status = ImageContext->ImageRead ( … … 1121 1337 1122 1338 Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress); 1123 1124 1339 FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( 1125 1340 (UINTN)ImageContext->ImageAddress + … … 1127 1342 ); 1128 1343 NumberOfSections = (UINTN) (Hdr.Te->NumberOfSections); 1129 1344 TeStrippedOffset = (UINT32) Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); 1130 1345 } 1131 1346 … … 1139 1354 // 1140 1355 Section = FirstSection; 1141 for (Index = 0 , MaxEnd = NULL; Index < NumberOfSections; Index++) {1356 for (Index = 0; Index < NumberOfSections; Index++) { 1142 1357 // 1143 1358 // Read the section … … 1151 1366 // Compute sections address 1152 1367 // 1153 Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress); 1154 End = PeCoffLoaderImageAddress ( 1155 ImageContext, 1156 Section->VirtualAddress + Section->Misc.VirtualSize - 1 1157 ); 1368 Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress, TeStrippedOffset); 1369 End = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress + Section->Misc.VirtualSize - 1, TeStrippedOffset); 1158 1370 1159 1371 // … … 1165 1377 } 1166 1378 1167 if (ImageContext->IsTeImage) {1168 Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);1169 End = (CHAR8 *)((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);1170 }1171 1172 if (End > MaxEnd) {1173 MaxEnd = End;1174 }1175 1176 1379 if (Section->SizeOfRawData > 0) { 1177 if (!(ImageContext->IsTeImage)) { 1178 Status = ImageContext->ImageRead ( 1179 ImageContext->Handle, 1180 Section->PointerToRawData, 1181 &Size, 1182 Base 1183 ); 1184 } else { 1185 Status = ImageContext->ImageRead ( 1186 ImageContext->Handle, 1187 Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize, 1188 &Size, 1189 Base 1190 ); 1191 } 1192 1380 Status = ImageContext->ImageRead ( 1381 ImageContext->Handle, 1382 Section->PointerToRawData - TeStrippedOffset, 1383 &Size, 1384 Base 1385 ); 1193 1386 if (RETURN_ERROR (Status)) { 1194 1387 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; … … 1225 1418 ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress ( 1226 1419 ImageContext, 1227 (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint 1420 (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint, 1421 0 1228 1422 ); 1229 1423 } else { … … 1233 1427 ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress ( 1234 1428 ImageContext, 1235 (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint 1429 (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint, 1430 0 1236 1431 ); 1237 1432 } 1238 1433 } else { 1239 ImageContext->EntryPoint = (PHYSICAL_ADDRESS) ( 1240 (UINTN)ImageContext->ImageAddress + 1241 (UINTN)Hdr.Te->AddressOfEntryPoint + 1242 (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - 1243 (UINTN)Hdr.Te->StrippedSize 1244 ); 1434 ImageContext->EntryPoint = (PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress ( 1435 ImageContext, 1436 (UINTN)Hdr.Te->AddressOfEntryPoint, 1437 TeStrippedOffset 1438 ); 1245 1439 } 1246 1440 … … 1267 1461 } 1268 1462 1463 // 1464 // Must use UINT64 here, because there might a case that 32bit loader to load 64bit image. 1465 // 1269 1466 if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { 1270 ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT N);1467 ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64); 1271 1468 } else { 1272 1469 ImageContext->FixupDataSize = 0; … … 1274 1471 } else { 1275 1472 DirectoryEntry = &Hdr.Te->DataDirectory[0]; 1276 ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT N);1473 ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINT64); 1277 1474 } 1278 1475 // … … 1286 1483 // 1287 1484 if (ImageContext->DebugDirectoryEntryRva != 0) { 1288 if (!(ImageContext->IsTeImage)) { 1289 DebugEntry = PeCoffLoaderImageAddress ( 1290 ImageContext, 1291 ImageContext->DebugDirectoryEntryRva 1292 ); 1293 } else { 1294 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)( 1295 ImageContext->ImageAddress + 1296 ImageContext->DebugDirectoryEntryRva + 1297 sizeof(EFI_TE_IMAGE_HEADER) - 1298 Hdr.Te->StrippedSize 1299 ); 1300 } 1301 1302 if (DebugEntry != NULL) { 1303 TempDebugEntryRva = DebugEntry->RVA; 1304 if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) { 1305 Section--; 1306 if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) { 1307 TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize; 1308 } else { 1309 TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData; 1310 } 1311 } 1312 1313 if (TempDebugEntryRva != 0) { 1314 if (!(ImageContext->IsTeImage)) { 1315 ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva); 1316 } else { 1317 ImageContext->CodeView = (VOID *)( 1318 (UINTN)ImageContext->ImageAddress + 1319 (UINTN)TempDebugEntryRva + 1320 (UINTN)sizeof (EFI_TE_IMAGE_HEADER) - 1321 (UINTN) Hdr.Te->StrippedSize 1322 ); 1323 } 1324 1325 if (ImageContext->CodeView == NULL) { 1485 DebugEntry = PeCoffLoaderImageAddress ( 1486 ImageContext, 1487 ImageContext->DebugDirectoryEntryRva, 1488 TeStrippedOffset 1489 ); 1490 if (DebugEntry == NULL) { 1491 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 1492 return RETURN_LOAD_ERROR; 1493 } 1494 1495 TempDebugEntryRva = DebugEntry->RVA; 1496 if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) { 1497 Section--; 1498 if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) { 1499 TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize; 1500 } else { 1501 TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData; 1502 } 1503 } 1504 1505 if (TempDebugEntryRva != 0) { 1506 ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva, TeStrippedOffset); 1507 if (ImageContext->CodeView == NULL) { 1508 ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; 1509 return RETURN_LOAD_ERROR; 1510 } 1511 1512 if (DebugEntry->RVA == 0) { 1513 Size = DebugEntry->SizeOfData; 1514 Status = ImageContext->ImageRead ( 1515 ImageContext->Handle, 1516 DebugEntry->FileOffset - TeStrippedOffset, 1517 &Size, 1518 ImageContext->CodeView 1519 ); 1520 // 1521 // Should we apply fix up to this field according to the size difference between PE and TE? 1522 // Because now we maintain TE header fields unfixed, this field will also remain as they are 1523 // in original PE image. 1524 // 1525 1526 if (RETURN_ERROR (Status)) { 1326 1527 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 1327 1528 return RETURN_LOAD_ERROR; 1328 1529 } 1329 1530 1330 if (DebugEntry->RVA == 0) { 1331 Size = DebugEntry->SizeOfData; 1332 if (!(ImageContext->IsTeImage)) { 1333 Status = ImageContext->ImageRead ( 1334 ImageContext->Handle, 1335 DebugEntry->FileOffset, 1336 &Size, 1337 ImageContext->CodeView 1338 ); 1339 } else { 1340 Status = ImageContext->ImageRead ( 1341 ImageContext->Handle, 1342 DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize, 1343 &Size, 1344 ImageContext->CodeView 1345 ); 1346 // 1347 // Should we apply fix up to this field according to the size difference between PE and TE? 1348 // Because now we maintain TE header fields unfixed, this field will also remain as they are 1349 // in original PE image. 1350 // 1351 } 1352 1353 if (RETURN_ERROR (Status)) { 1354 ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; 1355 return RETURN_LOAD_ERROR; 1356 } 1357 1358 DebugEntry->RVA = TempDebugEntryRva; 1359 } 1360 1361 switch (*(UINT32 *) ImageContext->CodeView) { 1362 case CODEVIEW_SIGNATURE_NB10: 1363 ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); 1364 break; 1365 1366 case CODEVIEW_SIGNATURE_RSDS: 1367 ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); 1368 break; 1369 1370 case CODEVIEW_SIGNATURE_MTOC: 1371 ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY); 1372 break; 1373 1374 default: 1375 break; 1376 } 1531 DebugEntry->RVA = TempDebugEntryRva; 1532 } 1533 1534 switch (*(UINT32 *) ImageContext->CodeView) { 1535 case CODEVIEW_SIGNATURE_NB10: 1536 if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)) { 1537 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1538 return RETURN_UNSUPPORTED; 1539 } 1540 ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); 1541 break; 1542 1543 case CODEVIEW_SIGNATURE_RSDS: 1544 if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)) { 1545 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1546 return RETURN_UNSUPPORTED; 1547 } 1548 ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); 1549 break; 1550 1551 case CODEVIEW_SIGNATURE_MTOC: 1552 if (DebugEntry->SizeOfData < sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)) { 1553 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1554 return RETURN_UNSUPPORTED; 1555 } 1556 ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY); 1557 break; 1558 1559 default: 1560 break; 1377 1561 } 1378 1562 } … … 1388 1572 // Use PE32 offset 1389 1573 // 1574 NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; 1390 1575 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE]; 1391 1576 } else { … … 1393 1578 // Use PE32+ offset 1394 1579 // 1580 NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; 1395 1581 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE]; 1396 1582 } 1397 1583 1398 if ( DirectoryEntry->Size != 0) {1399 Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress );1584 if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && DirectoryEntry->Size != 0) { 1585 Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress, 0); 1400 1586 if (Base != NULL) { 1401 1587 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base; 1588 Offset = sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * 1589 (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries); 1590 if (Offset > DirectoryEntry->Size) { 1591 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1592 return RETURN_UNSUPPORTED; 1593 } 1402 1594 ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1); 1403 1595 1404 1596 for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) { 1405 1597 if (ResourceDirectoryEntry->u1.s.NameIsString) { 1598 // 1599 // Check the ResourceDirectoryEntry->u1.s.NameOffset before use it. 1600 // 1601 if (ResourceDirectoryEntry->u1.s.NameOffset >= DirectoryEntry->Size) { 1602 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1603 return RETURN_UNSUPPORTED; 1604 } 1406 1605 ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset); 1407 1606 String = &ResourceDirectoryString->String[0]; … … 1418 1617 // Move to next level - resource Name 1419 1618 // 1619 if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >= DirectoryEntry->Size) { 1620 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1621 return RETURN_UNSUPPORTED; 1622 } 1420 1623 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory); 1624 Offset = ResourceDirectoryEntry->u2.s.OffsetToDirectory + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + 1625 sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries); 1626 if (Offset > DirectoryEntry->Size) { 1627 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1628 return RETURN_UNSUPPORTED; 1629 } 1421 1630 ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1); 1422 1631 … … 1425 1634 // Move to next level - resource Language 1426 1635 // 1636 if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >= DirectoryEntry->Size) { 1637 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1638 return RETURN_UNSUPPORTED; 1639 } 1427 1640 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory); 1641 Offset = ResourceDirectoryEntry->u2.s.OffsetToDirectory + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + 1642 sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (ResourceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries); 1643 if (Offset > DirectoryEntry->Size) { 1644 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1645 return RETURN_UNSUPPORTED; 1646 } 1428 1647 ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1); 1429 1648 } … … 1434 1653 // 1435 1654 if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) { 1655 if (ResourceDirectoryEntry->u2.OffsetToData >= DirectoryEntry->Size) { 1656 ImageContext->ImageError = IMAGE_ERROR_UNSUPPORTED; 1657 return RETURN_UNSUPPORTED; 1658 } 1436 1659 ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData); 1437 ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData );1660 ImageContext->HiiResourceData = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData, 0); 1438 1661 break; 1439 1662 } … … 1579 1802 FixupData = RelocationData; 1580 1803 while (RelocBase < RelocBaseEnd) { 1804 // 1805 // Add check for RelocBase->SizeOfBlock field. 1806 // 1807 if ((RelocBase->SizeOfBlock == 0) || (RelocBase->SizeOfBlock > RelocDir->Size)) { 1808 // 1809 // Data invalid, cannot continue to relocate the image, just return. 1810 // 1811 return; 1812 } 1581 1813 1582 1814 Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); … … 1631 1863 1632 1864 FixupData = FixupData + sizeof (UINT64); 1633 break;1634 1635 case EFI_IMAGE_REL_BASED_HIGHADJ:1636 //1637 // Not valid Relocation type for UEFI image, ASSERT1638 //1639 ASSERT (FALSE);1640 1865 break; 1641 1866 … … 1672 1897 The size of the buffer actually read is returned in ReadSize. 1673 1898 1899 The caller must make sure the FileOffset and ReadSize within the file scope. 1900 1674 1901 If FileHandle is NULL, then ASSERT(). 1675 1902 If ReadSize is NULL, then ASSERT(). -
trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
r48674 r58459 5 5 # The X64 version library support loading IA32, X64 and EBC PE/COFF images. 6 6 # 7 # Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> 7 # Caution: This module requires additional review when modified. 8 # This library will have external input - PE/COFF image. 9 # This external input must be validated carefully to avoid security issue like 10 # buffer overflow, integer overflow. 11 # 12 # Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 8 13 # Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 9 14 # … … 21 26 INF_VERSION = 0x00010005 22 27 BASE_NAME = BasePeCoffLib 28 MODULE_UNI_FILE = BasePeCoffLib.uni 23 29 FILE_GUID = 556f5d10-7309-4af4-b80a-8196bd60946f 24 30 MODULE_TYPE = BASE … … 28 34 29 35 # 30 # VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM 36 # VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 31 37 # 32 38 … … 44 50 Arm/PeCoffLoaderEx.c 45 51 52 [Sources.AARCH64] 53 AArch64/PeCoffLoaderEx.c 54 46 55 [Packages] 47 56 MdePkg/MdePkg.dec -
trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h
r48674 r58459 117 117 Converts an image address to the loaded address. 118 118 119 @param ImageContext The context of the image being loaded. 120 @param Address The address to be converted to the loaded address. 119 @param ImageContext The context of the image being loaded. 120 @param Address The address to be converted to the loaded address. 121 @param TeStrippedOffset Stripped offset for TE image. 121 122 122 123 @return The converted address or NULL if the address can not be converted. … … 126 127 PeCoffLoaderImageAddress ( 127 128 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, 128 IN UINTN Address 129 IN UINTN Address, 130 IN UINTN TeStrippedOffset 129 131 ); 130 132
Note:
See TracChangeset
for help on using the changeset viewer.