* [PATCH] efi/x86-mixed: move unmitigated RET into .rodata
@ 2022-08-15 13:20 Ard Biesheuvel
2022-08-15 19:46 ` Borislav Petkov
0 siblings, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2022-08-15 13:20 UTC (permalink / raw)
To: linux-efi; +Cc: bp, Ard Biesheuvel
Move the EFI mixed mode return trampoline RET into .rodata, so it is
normally mapped without executable permissions. And given that this
snippet of code is really the only kernel code that we ever execute via
this 1:1 mapping, let's unmap the 1:1 mapping of the kernel .text, and
only map the page that covers the return trampoline with executable
permissions.
Note that the remainder of .rodata needs to remain mapped into the 1:1
mapping with RO/NX permissions, as literal GUIDs and strings may be
passed to the variable routines.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/platform/efi/efi_64.c | 18 +++++++++++++-----
arch/x86/platform/efi/efi_thunk_64.S | 8 +++++---
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 1f3675453a57..b36596bf0fc3 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -176,7 +176,8 @@ virt_to_phys_or_null_size(void *va, unsigned long size)
int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
{
- unsigned long pfn, text, pf, rodata;
+ extern const u8 __efi64_thunk_ret_tramp[];
+ unsigned long pfn, text, pf, rodata, tramp;
struct page *page;
unsigned npages;
pgd_t *pgd = efi_mm.pgd;
@@ -238,11 +239,9 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
npages = (_etext - _text) >> PAGE_SHIFT;
text = __pa(_text);
- pfn = text >> PAGE_SHIFT;
- pf = _PAGE_ENC;
- if (kernel_map_pages_in_pgd(pgd, pfn, text, npages, pf)) {
- pr_err("Failed to map kernel text 1:1\n");
+ if (kernel_unmap_pages_in_pgd(pgd, text, npages)) {
+ pr_err("Failed to unmap kernel text 1:1 mapping\n");
return 1;
}
@@ -256,6 +255,15 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
return 1;
}
+ tramp = __pa(__efi64_thunk_ret_tramp);
+ pfn = tramp >> PAGE_SHIFT;
+
+ pf = _PAGE_ENC;
+ if (kernel_map_pages_in_pgd(pgd, pfn, tramp, 1, pf)) {
+ pr_err("Failed to map mixed mode return trampoline\n");
+ return 1;
+ }
+
return 0;
}
diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/efi_thunk_64.S
index 4e5257a4811b..e436ce03741e 100644
--- a/arch/x86/platform/efi/efi_thunk_64.S
+++ b/arch/x86/platform/efi/efi_thunk_64.S
@@ -23,7 +23,6 @@
#include <linux/objtool.h>
#include <asm/page_types.h>
#include <asm/segment.h>
-#include <asm/nospec-branch.h>
.text
.code64
@@ -72,11 +71,14 @@ STACK_FRAME_NON_STANDARD __efi64_thunk
pushq $__KERNEL32_CS
pushq %rdi /* EFI runtime service address */
lretq
+SYM_FUNC_END(__efi64_thunk)
+ .section ".rodata", "a", @progbits
+ .balign 16
+SYM_DATA_START(__efi64_thunk_ret_tramp)
1: movq 0x20(%rsp), %rsp
pop %rbx
pop %rbp
- ANNOTATE_UNRET_SAFE
ret
int3
@@ -84,7 +86,7 @@ STACK_FRAME_NON_STANDARD __efi64_thunk
2: pushl $__KERNEL_CS
pushl %ebp
lret
-SYM_FUNC_END(__efi64_thunk)
+SYM_DATA_END(__efi64_thunk_ret_tramp)
.bss
.balign 8
--
2.35.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] efi/x86-mixed: move unmitigated RET into .rodata
2022-08-15 13:20 [PATCH] efi/x86-mixed: move unmitigated RET into .rodata Ard Biesheuvel
@ 2022-08-15 19:46 ` Borislav Petkov
2022-08-15 19:57 ` Ard Biesheuvel
0 siblings, 1 reply; 5+ messages in thread
From: Borislav Petkov @ 2022-08-15 19:46 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-efi
On Mon, Aug 15, 2022 at 03:20:28PM +0200, Ard Biesheuvel wrote:
> Move the EFI mixed mode return trampoline RET into .rodata, so it is
> normally mapped without executable permissions. And given that this
> snippet of code is really the only kernel code that we ever execute via
> this 1:1 mapping, let's unmap the 1:1 mapping of the kernel .text, and
> only map the page that covers the return trampoline with executable
> permissions.
>
> Note that the remainder of .rodata needs to remain mapped into the 1:1
> mapping with RO/NX permissions, as literal GUIDs and strings may be
> passed to the variable routines.
>
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> arch/x86/platform/efi/efi_64.c | 18 +++++++++++++-----
> arch/x86/platform/efi/efi_thunk_64.S | 8 +++++---
> 2 files changed, 18 insertions(+), 8 deletions(-)
Acked-by: Borislav Petkov <bp@suse.de>
For some reason, objtool is not happy here:
vmlinux.o: warning: objtool: efi_thunk_query_variable_info_nonblocking+0x1ba: unreachable instruction
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] efi/x86-mixed: move unmitigated RET into .rodata
2022-08-15 19:46 ` Borislav Petkov
@ 2022-08-15 19:57 ` Ard Biesheuvel
[not found] ` <YvqqGD0IrqutH20a@zn.tnic>
0 siblings, 1 reply; 5+ messages in thread
From: Ard Biesheuvel @ 2022-08-15 19:57 UTC (permalink / raw)
To: Borislav Petkov; +Cc: linux-efi
On Mon, 15 Aug 2022 at 21:46, Borislav Petkov <bp@alien8.de> wrote:
>
> On Mon, Aug 15, 2022 at 03:20:28PM +0200, Ard Biesheuvel wrote:
> > Move the EFI mixed mode return trampoline RET into .rodata, so it is
> > normally mapped without executable permissions. And given that this
> > snippet of code is really the only kernel code that we ever execute via
> > this 1:1 mapping, let's unmap the 1:1 mapping of the kernel .text, and
> > only map the page that covers the return trampoline with executable
> > permissions.
> >
> > Note that the remainder of .rodata needs to remain mapped into the 1:1
> > mapping with RO/NX permissions, as literal GUIDs and strings may be
> > passed to the variable routines.
> >
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > ---
> > arch/x86/platform/efi/efi_64.c | 18 +++++++++++++-----
> > arch/x86/platform/efi/efi_thunk_64.S | 8 +++++---
> > 2 files changed, 18 insertions(+), 8 deletions(-)
>
> Acked-by: Borislav Petkov <bp@suse.de>
>
> For some reason, objtool is not happy here:
>
> vmlinux.o: warning: objtool: efi_thunk_query_variable_info_nonblocking+0x1ba: unreachable instruction
>
I'm not seeing that warning. Any config in particular beyond
x86_64_defconfig that you have enabled?
I'm using Debian GCC 12.1.0 btw
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-08-16 11:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-15 13:20 [PATCH] efi/x86-mixed: move unmitigated RET into .rodata Ard Biesheuvel
2022-08-15 19:46 ` Borislav Petkov
2022-08-15 19:57 ` Ard Biesheuvel
[not found] ` <YvqqGD0IrqutH20a@zn.tnic>
[not found] ` <CAMj1kXHUyAZQqLbT8uqKJTb9QHq1A4ZUbVnx+J0yQfZihJGjbg@mail.gmail.com>
2022-08-16 10:17 ` Peter Zijlstra
2022-08-16 10:28 ` Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox