Messages in this thread Patch in this message | | | From | Ard Biesheuvel <> | Date | Fri, 23 Sep 2022 00:08:57 +0200 | Subject | Re: [PATCH] x86/mm+efi: Avoid creating W+X mappings |
| |
On Thu, 22 Sept 2022 at 21:32, Dave Hansen <dave.hansen@linux.intel.com> wrote: > > From: Peter Zijlstra <peterz@infradead.org> > > I'm planning on sticking this in x86/mm so that it goes upstream > along with the W+X detection code. > > -- > > A recent x86/mm change warns and refuses to create W+X mappings. > > The 32-bit EFI code tries to create such a mapping and trips over > the new W+X refusal. > > Make the EFI_RUNTIME_SERVICES_CODE mapping read-only to fix it. >
This is not safe. EFI_RUNTIME_SERVICES_CODE covers both .text and .data sections of the EFI runtime PE/COFF executables in memory, so you are essentially making .data and .bss read-only. (Whether those executables actually modify their .data and .bss at runtime is a different matter, but the point is that it used to be possible)
More recent firmwares may provide a 'memory attributes table' separately which describes the individual sections, but older 32-bit firmwares are not even built with 4k section alignment, so code and data may share a single page. Note that we haven't wired up this memory attributes table on i386 at the moment, and I seriously doubt that 32-bit firmware in the field exposes it.
Can we just turn off this feature for 32-bit?
> Reported-by: Guenter Roeck <linux@roeck-us.net> > Signed-off-by: Peter Zijlstra <peterz@infradead.org> > Tested-by: Guenter Roeck <linux@roeck-us.net> > Cc: Ard Biesheuvel <ardb@kernel.org> > Cc: Darren Hart <dvhart@infradead.org> > Cc: Andy Shevchenko <andy@infradead.org> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@redhat.com> > Cc: Borislav Petkov <bp@alien8.de> > Cc: x86@kernel.org > Cc: linux-efi@vger.kernel.org > Cc: "H. Peter Anvin" <hpa@zytor.com> > Link: https://lore.kernel.org/all/d8cd7c7e-24c1-7f70-24a9-91c77aa634af@roeck-us.net/ > --- > arch/x86/platform/efi/efi_32.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c > index e06a199423c0..d81e379fcd43 100644 > --- a/arch/x86/platform/efi/efi_32.c > +++ b/arch/x86/platform/efi/efi_32.c > @@ -136,6 +136,7 @@ void __init efi_runtime_update_mappings(void) > if (md->type != EFI_RUNTIME_SERVICES_CODE) > continue; > > + set_memory_ro(md->virt_addr, md->num_pages); > set_memory_x(md->virt_addr, md->num_pages); > } > }
| |