]>
Commit | Line | Data |
---|---|---|
221ef3ca GKH |
1 | From 0b3225ab9407f557a8e20f23f37aa7236c10a9b1 Mon Sep 17 00:00:00 2001 |
2 | From: Ard Biesheuvel <ard.biesheuvel@linaro.org> | |
3 | Date: Fri, 4 May 2018 07:59:58 +0200 | |
4 | Subject: efi: Avoid potential crashes, fix the 'struct efi_pci_io_protocol_32' definition for mixed mode | |
5 | ||
6 | From: Ard Biesheuvel <ard.biesheuvel@linaro.org> | |
7 | ||
8 | commit 0b3225ab9407f557a8e20f23f37aa7236c10a9b1 upstream. | |
9 | ||
10 | Mixed mode allows a kernel built for x86_64 to interact with 32-bit | |
11 | EFI firmware, but requires us to define all struct definitions carefully | |
12 | when it comes to pointer sizes. | |
13 | ||
14 | 'struct efi_pci_io_protocol_32' currently uses a 'void *' for the | |
15 | 'romimage' field, which will be interpreted as a 64-bit field | |
16 | on such kernels, potentially resulting in bogus memory references | |
17 | and subsequent crashes. | |
18 | ||
19 | Tested-by: Hans de Goede <hdegoede@redhat.com> | |
20 | Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> | |
21 | Cc: <stable@vger.kernel.org> | |
22 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
23 | Cc: Matt Fleming <matt@codeblueprint.co.uk> | |
24 | Cc: Peter Zijlstra <peterz@infradead.org> | |
25 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
26 | Cc: linux-efi@vger.kernel.org | |
27 | Link: http://lkml.kernel.org/r/20180504060003.19618-13-ard.biesheuvel@linaro.org | |
28 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
29 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
30 | ||
31 | --- | |
32 | arch/x86/boot/compressed/eboot.c | 6 ++++-- | |
33 | include/linux/efi.h | 8 ++++---- | |
34 | 2 files changed, 8 insertions(+), 6 deletions(-) | |
35 | ||
36 | --- a/arch/x86/boot/compressed/eboot.c | |
37 | +++ b/arch/x86/boot/compressed/eboot.c | |
38 | @@ -364,7 +364,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32 | |
39 | if (status != EFI_SUCCESS) | |
40 | goto free_struct; | |
41 | ||
42 | - memcpy(rom->romdata, pci->romimage, pci->romsize); | |
43 | + memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, | |
44 | + pci->romsize); | |
45 | return status; | |
46 | ||
47 | free_struct: | |
48 | @@ -470,7 +471,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64 | |
49 | if (status != EFI_SUCCESS) | |
50 | goto free_struct; | |
51 | ||
52 | - memcpy(rom->romdata, pci->romimage, pci->romsize); | |
53 | + memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, | |
54 | + pci->romsize); | |
55 | return status; | |
56 | ||
57 | free_struct: | |
58 | --- a/include/linux/efi.h | |
59 | +++ b/include/linux/efi.h | |
60 | @@ -364,8 +364,8 @@ typedef struct { | |
61 | u32 attributes; | |
62 | u32 get_bar_attributes; | |
63 | u32 set_bar_attributes; | |
64 | - uint64_t romsize; | |
65 | - void *romimage; | |
66 | + u64 romsize; | |
67 | + u32 romimage; | |
68 | } efi_pci_io_protocol_32; | |
69 | ||
70 | typedef struct { | |
71 | @@ -384,8 +384,8 @@ typedef struct { | |
72 | u64 attributes; | |
73 | u64 get_bar_attributes; | |
74 | u64 set_bar_attributes; | |
75 | - uint64_t romsize; | |
76 | - void *romimage; | |
77 | + u64 romsize; | |
78 | + u64 romimage; | |
79 | } efi_pci_io_protocol_64; | |
80 | ||
81 | typedef struct { |