|
|
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.