|
|
Message-ID: <CAGXu5jJrB89-egt6n5qC88Hj5Oi4UOQO=cBO6vD7MZwgdjwHyA@mail.gmail.com>
Date: Wed, 8 Aug 2018 15:02:26 -0700
From: Kees Cook <keescook@...omium.org>
To: Mark Brand <markbrand@...gle.com>
Cc: Ard Biesheuvel <ard.biesheuvel@...aro.org>, Catalin Marinas <catalin.marinas@....com>,
Christoffer Dall <christoffer.dall@....com>, Julien Thierry <julien.thierry@....com>,
Kernel Hardening <kernel-hardening@...ts.openwall.com>,
Laura Abbott <labbott@...oraproject.org>, Mark Rutland <mark.rutland@....com>,
Robin Murphy <robin.murphy@....com>, Will Deacon <will.deacon@....com>,
linux-arm-kernel <linux-arm-kernel@...ts.infradead.org>
Subject: Re: [RFC/PoC PATCH 0/3] arm64: basic ROP mitigation
On Wed, Aug 8, 2018 at 9:09 AM, Mark Brand <markbrand@...gle.com> wrote:
> (1) chaining through the mempool_free function, I found this really
> quickly when searching for useful gadgets based off x0
>
> void mempool_free(void *element, mempool_t *pool)
> {
> unsigned long flags;
>
> if (unlikely(element == NULL))
> return;
>
> /* snip */
> smp_rmb();
>
> /* snip */
> if (unlikely(pool->curr_nr < pool->min_nr)) {
> spin_lock_irqsave(&pool->lock, flags);
> if (likely(pool->curr_nr < pool->min_nr)) {
> add_element(pool, element);
> spin_unlock_irqrestore(&pool->lock, flags);
> wake_up(&pool->wait);
> return;
> }
> spin_unlock_irqrestore(&pool->lock, flags);
> }
>
> pool->free(element, pool->pool_data);
> }
>
> Since the callsites for this function usually load the arguments
> through some registers, and the function to call gets pulled out of
> one of those arguments, it's easy to get a couple of registers loaded
> here and then the chain continue.
>
> (2) loading complete register state using kernel_exit macro.
>
> Since the kernel_exit macro actually loads spsr_el1 and elr_el1 from
> registers, I think that you can let the eret return to anywhere in el1
> without dropping to el0, since the same handler is used for "exiting
> the kernel" when a hardware interrupt interrupts the kernel itself. I
> didn't fill out the necessary register values in the chain below,
> since I don't anyway have a device around to test this on right now.
>
> I'm not sure that you could really robustly protect this eret; I
> suppose that you could try and somehow validate the saved register
> state, but given that it would be happening on every exception return,
> I suspect it would be expensive.
This is a wonderful example, thanks! Yeah, Call-Oriented Programming?
:P mempool_free() is quite a nice gadget.
-Kees
--
Kees Cook
Pixel Security
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.