[PATCH v3] arm64/efi: efistub: jump to 'stext' directly, not through the header

Ard Biesheuvel ard.biesheuvel at linaro.org
Thu Oct 9 12:03:52 PDT 2014


On 9 October 2014 19:23, Mark Rutland <mark.rutland at arm.com> wrote:
> Hi Ard,
>
> On Wed, Oct 08, 2014 at 03:11:27PM +0100, Ard Biesheuvel wrote:
>> After the EFI stub has done its business, it jumps into the kernel by
>> branching to offset #0 of the loaded Image, which is where it expects
>> to find the header containing a 'branch to stext' instruction.
>>
>> However, the UEFI spec 2.1.1 states the following regarding PE/COFF
>> image loading:
>> "A UEFI image is loaded into memory through the LoadImage() Boot
>> Service. This service loads an image with a PE32+ format into memory.
>> This PE32+ loader is required to load all sections of the PE32+ image
>> into memory."
>>
>> In other words, it is /not/ required to load parts of the image that are
>> not covered by a PE/COFF section, so it may not have loaded the header
>> at the expected offset, as it is not covered by any PE/COFF section.
>
> What does this mean for handle_kernel_image? Given we might not have
> _text through to _stext mapped, do we not need to take that into
> account?
>

Actually, handle_kernel_image() does not interpret the header, it just
copies it along with the rest of the image if it needs to be
relocated, so I don't see an issue there. However, I do remember Mark
Salter mentioning that there is at least one other location that needs
to be fixed up if this concern is valid. Mark?

> Also, have we seen problems on any systems yet?
>

No, I am not aware of any occurrences of this exact issue, this is
just one of the things I spotted while working on this code.
But I think we mostly agree that branching through the header relies
on behavior of the PE/COFF loader that is not covered by the spec.

-- 
Ard.


>> So instead, jump to 'stext' directly, which is at the base of the
>> PE/COFF .text section, by supplying a symbol 'stext_offset' to
>> efi-entry.o which contains the relative offset of stext into the Image.
>> Also replace other open coded calculations of the same value with a
>> reference to 'stext_offset'
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>> Changes since v2:
>> - rebased onto 3.17+
>> - added spec reference to commit message
>>
>> Changes since v1:
>> - drop :lo12: relocation against stext_offset in favor of using a literal
>>   '=stext_offset' which is safer
>>
>>  arch/arm64/kernel/efi-entry.S |  3 ++-
>>  arch/arm64/kernel/head.S      | 10 ++++++----
>>  2 files changed, 8 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S
>> index 619b1dd7bcde..a0016d3a17da 100644
>> --- a/arch/arm64/kernel/efi-entry.S
>> +++ b/arch/arm64/kernel/efi-entry.S
>> @@ -61,7 +61,8 @@ ENTRY(efi_stub_entry)
>>        */
>>       mov     x20, x0         // DTB address
>>       ldr     x0, [sp, #16]   // relocated _text address
>> -     mov     x21, x0
>> +     ldr     x21, =stext_offset
>> +     add     x21, x0, x21
>>
>>       /*
>>        * Flush dcache covering current runtime addresses
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index 0a6e4f924df8..8c06c9d269d2 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -132,6 +132,8 @@ efi_head:
>>  #endif
>>
>>  #ifdef CONFIG_EFI
>> +     .globl  stext_offset
>> +     .set    stext_offset, stext - efi_head
>>       .align 3
>>  pe_header:
>>       .ascii  "PE"
>> @@ -155,7 +157,7 @@ optional_header:
>>       .long   0                               // SizeOfInitializedData
>>       .long   0                               // SizeOfUninitializedData
>>       .long   efi_stub_entry - efi_head       // AddressOfEntryPoint
>> -     .long   stext - efi_head                // BaseOfCode
>> +     .long   stext_offset                    // BaseOfCode
>>
>>  extra_header_fields:
>>       .quad   0                               // ImageBase
>> @@ -172,7 +174,7 @@ extra_header_fields:
>>       .long   _end - efi_head                 // SizeOfImage
>>
>>       // Everything before the kernel image is considered part of the header
>> -     .long   stext - efi_head                // SizeOfHeaders
>> +     .long   stext_offset                    // SizeOfHeaders
>>       .long   0                               // CheckSum
>>       .short  0xa                             // Subsystem (EFI application)
>>       .short  0                               // DllCharacteristics
>> @@ -217,9 +219,9 @@ section_table:
>>       .byte   0
>>       .byte   0                       // end of 0 padding of section name
>>       .long   _end - stext            // VirtualSize
>> -     .long   stext - efi_head        // VirtualAddress
>> +     .long   stext_offset            // VirtualAddress
>>       .long   _edata - stext          // SizeOfRawData
>> -     .long   stext - efi_head        // PointerToRawData
>> +     .long   stext_offset            // PointerToRawData
>>
>>       .long   0               // PointerToRelocations (0 for executables)
>>       .long   0               // PointerToLineNumbers (0 for executables)
>> --
>> 1.8.3.2
>>
>>



More information about the linux-arm-kernel mailing list