Message ID | 1531308586-29340-31-git-send-email-joro@8bytes.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jul 11, 2018 at 4:29 AM, Joerg Roedel <joro@8bytes.org> wrote: > From: Joerg Roedel <jroedel@suse.de> > > The mapping for entry-text might have changed in the kernel > after it was cloned to the user page-table. Clone again > to update the user page-table to bring the mapping in sync > with the kernel again. Can't we just defer pti_init() until after mark_readonly()? What am I missing?
On Fri, Jul 13, 2018 at 04:21:45PM -0700, Andy Lutomirski wrote: > On Wed, Jul 11, 2018 at 4:29 AM, Joerg Roedel <joro@8bytes.org> wrote: > > From: Joerg Roedel <jroedel@suse.de> > > > > The mapping for entry-text might have changed in the kernel > > after it was cloned to the user page-table. Clone again > > to update the user page-table to bring the mapping in sync > > with the kernel again. > > Can't we just defer pti_init() until after mark_readonly()? What am I missing? I tried that: https://lore.kernel.org/lkml/1530618746-23116-1-git-send-email-joro@8bytes.org/ But while testing it turned out that the kernel potentially executes user-space code already before mark_readonly() has ran. This happens when some initcall requests a module and the initrd is already populated. Then usermode-helper kicks in and runs a userspace binary already. When pti_init() has not run yet the user-space page-table is completly empty, causing a triple fault when we switch to the user cr3 on the way to user-space. Regards, Joerg
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c index 1825f30..b879ccd 100644 --- a/arch/x86/mm/pti.c +++ b/arch/x86/mm/pti.c @@ -404,7 +404,7 @@ static void __init pti_setup_espfix64(void) /* * Clone the populated PMDs of the entry and irqentry text and force it RO. */ -static void __init pti_clone_entry_text(void) +static void pti_clone_entry_text(void) { pti_clone_pmds((unsigned long) __entry_text_start, (unsigned long) __irqentry_text_end, @@ -528,13 +528,18 @@ void __init pti_init(void) } /* - * Finalize the kernel mappings in the userspace page-table. + * Finalize the kernel mappings in the userspace page-table. Some of the + * mappings for the kernel image might have changed since pti_init() + * cloned them. This is because parts of the kernel image have been + * mapped RO and/or NX. These changes need to be cloned again to the + * userspace page-table. */ void pti_finalize(void) { /* - * Do this after all of the manipulation of the - * kernel text page tables are complete. + * We need to clone everything (again) that maps parts of the + * kernel image. */ + pti_clone_entry_text(); pti_clone_kernel_text(); }