From: sboyd@codeaurora.org (Stephen Boyd)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 3/7] arm: use fixmap for text patching when text is RO
Date: Tue, 12 Aug 2014 17:27:48 -0700 [thread overview]
Message-ID: <53EAB104.1050208@codeaurora.org> (raw)
In-Reply-To: <CAGXu5j+TPBs9h9YvVDt=g4WFykHgzcde9Ujuef=cRQAou8hZoA@mail.gmail.com>
On 08/12/14 14:47, Kees Cook wrote:
> On Tue, Aug 12, 2014 at 2:39 PM, Stephen Boyd <sboyd@codeaurora.org> wrote:
>> On 08/12/14 11:24, Kees Cook wrote:
>>> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
>>> index 07314af47733..03dd4e39c833 100644
>>> --- a/arch/arm/kernel/patch.c
>>> +++ b/arch/arm/kernel/patch.c
>>> @@ -13,21 +16,69 @@ struct patch {
>>> unsigned int insn;
>>> };
>>>
>>> -void __kprobes __patch_text(void *addr, unsigned int insn)
>>> +static DEFINE_SPINLOCK(patch_lock);
>>> +
>>> +static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
>>> +{
>>> + 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);
>>> +
>>> + set_fixmap(fixmap, page_to_phys(page));
>>> +
>>> + return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
>>> +}
>>> +
>>> +static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
>>> +{
>>> + clear_fixmap(fixmap);
>>> +
>>> + if (flags)
>>> + spin_unlock_irqrestore(&patch_lock, *flags);
>>> +}
>> Has the kbuildbot complained about this one yet?
>>
>> CHECK arch/arm/kernel/patch.c
>> arch/arm/kernel/patch.c:47:39: warning: context imbalance in
>> 'patch_unmap' - unexpected unlock
>>
>> I guess we're going to ignore it.
> No, nothing yet from buildbot, let me do a sparse run -- I think we
> can just add annotation and we'll be okay.
>
>
Ok. I tried to move code around but sparse still complains because of
conditional locking.
---8<---
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 03dd4e39c833..f6d4de3826a0 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -18,33 +18,17 @@ struct patch {
static DEFINE_SPINLOCK(patch_lock);
-static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+static struct page __kprobes *patch_page(void *addr)
{
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);
+ return vmalloc_to_page(addr);
else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA))
- page = virt_to_page(addr);
- else
- return addr;
+ return virt_to_page(addr);
- if (flags)
- spin_lock_irqsave(&patch_lock, *flags);
-
- set_fixmap(fixmap, page_to_phys(page));
-
- return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
-}
-
-static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
-{
- clear_fixmap(fixmap);
-
- if (flags)
- spin_unlock_irqrestore(&patch_lock, *flags);
+ return NULL;
}
void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
@@ -54,10 +38,18 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
bool twopage = false;
unsigned long flags;
void *waddr = addr;
+ struct page *page = NULL;
int size;
- if (remap)
- waddr = patch_map(addr, FIX_TEXT_POKE0, &flags);
+ if (remap) {
+ page = patch_page(addr);
+ if (page) {
+ spin_lock_irqsave(&patch_lock, flags);
+ set_fixmap(FIX_TEXT_POKE0, page_to_phys(page));
+ waddr = (void *)(__fix_to_virt(FIX_TEXT_POKE0) +
+ (uintaddr & ~PAGE_MASK));
+ }
+ }
if (thumb2 && __opcode_is_thumb16(insn)) {
*(u16 *)waddr = __opcode_to_mem_thumb16(insn);
@@ -69,15 +61,25 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
u16 *addrh1 = waddr + 2;
twopage = (uintaddr & ~PAGE_MASK) == PAGE_SIZE - 2;
- if (twopage && remap)
- addrh1 = patch_map(addr + 2, FIX_TEXT_POKE1, NULL);
+ if (twopage && remap) {
+ struct page *page2;
+
+ page2 = patch_page(addr + 2);
+ if (page2) {
+ set_fixmap(FIX_TEXT_POKE1, page_to_phys(page));
+ addrh1 = (u16 *)(__fix_to_virt(FIX_TEXT_POKE1) +
+ (uintaddr & ~PAGE_MASK));
+ } else {
+ addrh1 = addr + 2;
+ }
+ }
*addrh0 = __opcode_to_mem_thumb16(first);
*addrh1 = __opcode_to_mem_thumb16(second);
if (twopage && addrh1 != addr + 2) {
flush_kernel_vmap_range(addrh1, 2);
- patch_unmap(FIX_TEXT_POKE1, NULL);
+ clear_fixmap(FIX_TEXT_POKE1);
}
size = sizeof(u32);
@@ -91,9 +93,10 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
size = sizeof(u32);
}
- if (waddr != addr) {
+ if (page) {
flush_kernel_vmap_range(waddr, twopage ? size / 2 : size);
- patch_unmap(FIX_TEXT_POKE0, &flags);
+ clear_fixmap(FIX_TEXT_POKE0);
+ spin_unlock_irqrestore(&patch_lock, flags);
}
flush_icache_range((uintptr_t)(addr),
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
next prev parent reply other threads:[~2014-08-13 0:27 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-12 18:24 [PATCH v3 0/7] arm: support CONFIG_RODATA Kees Cook
2014-08-12 18:24 ` [PATCH v3 1/7] arm: use generic fixmap.h Kees Cook
2014-08-12 19:38 ` Kees Cook
2014-08-12 18:24 ` [PATCH v3 2/7] arm: fixmap: implement __set_fixmap() Kees Cook
2014-08-12 18:24 ` [PATCH v3 3/7] arm: use fixmap for text patching when text is RO Kees Cook
2014-08-12 21:39 ` Stephen Boyd
2014-08-12 21:47 ` Kees Cook
2014-08-13 0:27 ` Stephen Boyd [this message]
2014-08-13 2:39 ` Kees Cook
2014-08-12 18:24 ` [PATCH v3 4/7] ARM: kexec: Make .text R/W in machine_kexec Kees Cook
2014-08-12 18:24 ` [PATCH v3 5/7] arm: kgdb: Handle read-only text / modules Kees Cook
2014-08-12 19:38 ` Stephen Boyd
2014-08-12 19:40 ` Kees Cook
2014-08-12 18:24 ` [PATCH v3 6/7] ARM: mm: allow non-text sections to be non-executable Kees Cook
2014-08-12 18:24 ` [PATCH v3 7/7] ARM: mm: allow text and rodata sections to be read-only Kees Cook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53EAB104.1050208@codeaurora.org \
--to=sboyd@codeaurora.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).