From: Ard Biesheuvel <ardb@xxxxxxxxxx> Sent: Saturday, March 28, 2020 1:58 PM > > Commit 9f9223778ef3 ("efi/libstub/arm: Make efi_entry() an ordinary > PE/COFF entrypoint") did some code refactoring to get rid of the > EFI entry point assembler code, and in the process, it got rid of the > assignment of image_addr to the value of _text. Instead, it switched > to using the image_base field of the efi_loaded_image struct provided > by UEFI, which should contain the same value. > > However, Michael reports that this is not the case: older GRUB builds > corrupt this value in some way, and since we can easily switch back to > referring to _text to discover this value, let's simply do that. > > While at it, fix another issue in commit 9f9223778ef3, which may result > in the unassigned image_addr to be misidentified as the preferred load > offset of the kernel, which is unlikely but will cause a boot crash if > it does occur. > > Finally, let's add a warning if the _text vs. image_base discrepancy is > detected, so we can tell more easily how widespread this issue actually > is. > > Reported-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> > Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> > --- > drivers/firmware/efi/libstub/arm64-stub.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) Tested in a Hyper-V VM. With the 2.02~beta2 version of grub, the FIRMWARE BUG message is output and then Linux correctly boots. With the 2.04-4 version of grub, Linux correctly boots with no error messages. Tested-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> > > diff --git a/drivers/firmware/efi/libstub/arm64-stub.c > b/drivers/firmware/efi/libstub/arm64-stub.c > index 9254cd8ab2d3..db0c1a9c1699 100644 > --- a/drivers/firmware/efi/libstub/arm64-stub.c > +++ b/drivers/firmware/efi/libstub/arm64-stub.c > @@ -116,6 +116,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, > * Mustang), we can still place the kernel at the address > * 'dram_base + TEXT_OFFSET'. > */ > + *image_addr = (unsigned long)_text; > if (*image_addr == preferred_offset) > return EFI_SUCCESS; > > @@ -140,7 +141,11 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, > } > *image_addr = *reserve_addr + TEXT_OFFSET; > } > - memcpy((void *)*image_addr, image->image_base, kernel_size); > + > + if (image->image_base != _text) > + pr_efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus > value\n"); > + > + memcpy((void *)*image_addr, _text, kernel_size); > > return EFI_SUCCESS; > } > -- > 2.17.1