Thread (26 messages) 26 messages, 4 authors, 2014-09-04

[PATCH v4 4/8] arm: use fixmap for text patching when text is RO

From: Kees Cook <hidden>
Date: 2014-09-04 14:00:35
Also in: lkml

On Thu, Sep 4, 2014 at 2:27 AM, Will Deacon [off-list ref] wrote:
On Wed, Sep 03, 2014 at 10:43:58PM +0100, Kees Cook wrote:
quoted
On Wed, Aug 20, 2014 at 5:28 AM, Kees Cook [off-list ref] wrote:
quoted
On Tue, Aug 19, 2014 at 7:29 AM, Will Deacon [off-list ref] wrote:
quoted
On Wed, Aug 13, 2014 at 06:06:29PM +0100, Kees Cook wrote:
quoted
+static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+     __acquires(&patch_lock)
+{
+     unsigned int uintaddr = (uintptr_t) addr;
+     bool module = !core_kernel_text(uintaddr);
+     struct page *page;
+
+     if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
+             page = vmalloc_to_page(addr);
+     else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA))
+             page = virt_to_page(addr);
+     else
+             return addr;
+
+     if (flags)
+             spin_lock_irqsave(&patch_lock, *flags);
+     else
+             __acquire(&patch_lock);
I don't understand the locking here. Why is it conditional, why do we need
to disable interrupts, and are you just racing against yourself?
AIUI, the locking is here to avoid multiple users of the text poking
fixmaps. It's conditional because there are two fixmaps
(FIX_TEXT_POKE0 and FIX_TEXT_POKE1). Locking happens around 0 so
locking around 1 is not needed since it is only ever used when 0 is in
use. (__patch_text_real locks patch_lock before setting 0 when it uses
remapping, and if it also needs 1, it doesn't have to lock since the
lock is already held.)
quoted
quoted
+     set_fixmap(fixmap, page_to_phys(page));
set_fixmap does TLB invalidation, right? I think that means it can block on
11MPCore and A15 w/ the TLBI erratum, so it's not safe to call this with
interrupts disabled anyway.
Oh right. Hrm.

In an earlier version of this series set_fixmap did not perform TLB
invalidation. I wonder if this is not needed at all? (Wouldn't that be
nice...)
As suspected, my tests fail spectacularly without the TLB flush.
Adding WARN_ON(!irqs_disabled()) doesn't warn, so I think we're safe
here. Should I leave the WARN_ON in place for clarity, or some other
comments?
I thought there was a potential call to spin_lock_irqsave right before
this TLB flush?
I'm not sure I understand what you mean. Should I change something
here? It looks like irqs are disabled, so isn't this a safe code path?

-Kees

-- 
Kees Cook
Chrome OS Security
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help