| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Fri, 4 May 2018 07:59:58 +0200 |
| Subject: efi: Avoid potential crashes, fix the 'struct efi_pci_io_protocol_32' |
| definition for mixed mode |
| |
| commit 0b3225ab9407f557a8e20f23f37aa7236c10a9b1 upstream. |
| |
| Mixed mode allows a kernel built for x86_64 to interact with 32-bit |
| EFI firmware, but requires us to define all struct definitions carefully |
| when it comes to pointer sizes. |
| |
| 'struct efi_pci_io_protocol_32' currently uses a 'void *' for the |
| 'romimage' field, which will be interpreted as a 64-bit field |
| on such kernels, potentially resulting in bogus memory references |
| and subsequent crashes. |
| |
| Tested-by: Hans de Goede <hdegoede@redhat.com> |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Matt Fleming <matt@codeblueprint.co.uk> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: linux-efi@vger.kernel.org |
| Link: http://lkml.kernel.org/r/20180504060003.19618-13-ard.biesheuvel@linaro.org |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| arch/x86/boot/compressed/eboot.c | 6 ++++-- |
| include/linux/efi.h | 8 ++++---- |
| 2 files changed, 8 insertions(+), 6 deletions(-) |
| |
| --- a/arch/x86/boot/compressed/eboot.c |
| +++ b/arch/x86/boot/compressed/eboot.c |
| @@ -358,7 +358,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32 |
| if (status != EFI_SUCCESS) |
| goto free_struct; |
| |
| - memcpy(rom->romdata, pci->romimage, pci->romsize); |
| + memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, |
| + pci->romsize); |
| return status; |
| |
| free_struct: |
| @@ -460,7 +461,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64 |
| if (status != EFI_SUCCESS) |
| goto free_struct; |
| |
| - memcpy(rom->romdata, pci->romimage, pci->romsize); |
| + memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, |
| + pci->romsize); |
| return status; |
| |
| free_struct: |
| --- a/include/linux/efi.h |
| +++ b/include/linux/efi.h |
| @@ -368,8 +368,8 @@ typedef struct { |
| u32 attributes; |
| u32 get_bar_attributes; |
| u32 set_bar_attributes; |
| - uint64_t romsize; |
| - void *romimage; |
| + u64 romsize; |
| + u32 romimage; |
| } efi_pci_io_protocol_32; |
| |
| typedef struct { |
| @@ -388,8 +388,8 @@ typedef struct { |
| u64 attributes; |
| u64 get_bar_attributes; |
| u64 set_bar_attributes; |
| - uint64_t romsize; |
| - void *romimage; |
| + u64 romsize; |
| + u64 romimage; |
| } efi_pci_io_protocol_64; |
| |
| typedef struct { |