|
Message-ID: <CALCETrUruKRCnHAEVg6pXe+43WQx7K6LCOHg5zVEjLfzw8nQUA@mail.gmail.com> Date: Tue, 28 Feb 2017 11:33:38 -0800 From: Andy Lutomirski <luto@...capital.net> To: Kees Cook <keescook@...omium.org> Cc: "kernel-hardening@...ts.openwall.com" <kernel-hardening@...ts.openwall.com>, Mark Rutland <mark.rutland@....com>, Andy Lutomirski <luto@...nel.org>, Hoeun Ryu <hoeun.ryu@...il.com>, PaX Team <pageexec@...email.hu>, Emese Revfy <re.emese@...il.com>, Russell King <linux@...linux.org.uk>, X86 ML <x86@...nel.org> Subject: Re: [RFC][PATCH 4/8] x86: Implement __arch_rare_write_map/unmap() On Mon, Feb 27, 2017 at 12:43 PM, Kees Cook <keescook@...omium.org> wrote: > Based on PaX's x86 pax_{open,close}_kernel() implementation, this > allows HAVE_ARCH_RARE_WRITE to work on x86. > > There is missing work to sort out some header file issues where preempt.h > is missing, though it can't be included in pg_table.h unconditionally... > some other solution will be needed, perhaps an entirely separate header > file for rare_write()-related defines... > > This patch is also missing paravirt support. > > Signed-off-by: Kees Cook <keescook@...omium.org> > --- > arch/x86/Kconfig | 1 + > arch/x86/include/asm/pgtable.h | 31 +++++++++++++++++++++++++++++++ > 2 files changed, 32 insertions(+) > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index e487493bbd47..6d4d6f73d4b8 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -102,6 +102,7 @@ config X86 > select HAVE_ARCH_KMEMCHECK > select HAVE_ARCH_MMAP_RND_BITS if MMU > select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT > + select HAVE_ARCH_RARE_WRITE > select HAVE_ARCH_SECCOMP_FILTER > select HAVE_ARCH_TRACEHOOK > select HAVE_ARCH_TRANSPARENT_HUGEPAGE > diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h > index 437feb436efa..86e78e97738f 100644 > --- a/arch/x86/include/asm/pgtable.h > +++ b/arch/x86/include/asm/pgtable.h > @@ -90,6 +90,37 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); > > #endif /* CONFIG_PARAVIRT */ > > +/* TODO: Bad hack to deal with preempt macros being missing sometimes. */ > +#ifndef preempt_disable > +#include <linux/preempt.h> > +#endif > + > +static inline unsigned long __arch_rare_write_map(void) > +{ > + unsigned long cr0; > + > + preempt_disable(); > + barrier(); > + cr0 = read_cr0() ^ X86_CR0_WP; > + BUG_ON(cr0 & X86_CR0_WP); > + write_cr0(cr0); > + barrier(); > + return cr0 ^ X86_CR0_WP; > +} > + > +static inline unsigned long __arch_rare_write_unmap(void) > +{ > + unsigned long cr0; > + > + barrier(); > + cr0 = read_cr0() ^ X86_CR0_WP; > + BUG_ON(!(cr0 & X86_CR0_WP)); > + write_cr0(cr0); > + barrier(); > + preempt_enable_no_resched(); > + return cr0 ^ X86_CR0_WP; > +} This seems like a wonderful ROP target. Off-hand, I'd guess the reason it's never been a problem (that I've heard of) in grsecurity is that grsecurity isn't quite popular enough to be a big publicly discussed target. Can't we at least make this: struct rare_write_mapping { void *addr; struct arch_rare_write_state arch_state; }; static inline struct rare_write_mapping __arch_rare_write_map(void *addr, size_t len); static inline void __arch_rare_write_unmap(struct rare_write_mapping mapping); or similar, this allowing a non-terrifying implementation (e.g. switch CR3 to a specialized pagetable) down the road? I realize that if you get exactly the code generation you want, the CR0.WP approach *might* be okay, but that seems quite fragile.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.