Thread (14 messages) flat view 14 messages, 2 authors, 2017-02-14
STALE3506d

Revision v2 of 5 in this series.

Revisions (5)
  1. v2 [diff vs current]
  2. v2 [diff vs current]
  3. v2 current
  4. v2 [diff vs current]
  5. v3 [diff vs current]

[PATCH v2 4/5] arm64: mmu: map .text as read-only from the outset

From: Ard Biesheuvel <hidden>
Date: 2017-02-14 16:15:11
Also in: kvmarm

On 14 Feb 2017, at 15:57, Mark Rutland [off-list ref] wrote:
quoted
On Sat, Feb 11, 2017 at 08:23:05PM +0000, Ard Biesheuvel wrote:
Now that alternatives patching code no longer relies on the primary
mapping of .text being writable, we can remove the code that removes
the writable permissions post-init time, and map it read-only from
the outset.

Reviewed-by: Laura Abbott <redacted>
Reviewed-by: Kees Cook <redacted>
Signed-off-by: Ard Biesheuvel <redacted>
This generally looks good.

One effect of this is that even with rodata=off, external debuggers
can't install SW breakpoints via the executable mapping.
Interesting. For the sake of my education, could you elaborate on how that works under the hood?
We might want to allow that to be overridden. e.g. make rodata= an
early param, and switch the permissions based on that in map_kernel(),
e.g. have:

   pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX
                       : PAGE_KERNEL_EXEC);

... and use that for .text and .init.text by default.
Is there any way we could restrict this privilege to external debuggers? Having trivial 'off' switches for security features makes me feel uneasy (although this is orthogonal to this patch)
quoted
---
arch/arm64/mm/mmu.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 7ed981c7f4c0..e97f1ce967ec 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -442,9 +442,6 @@ void mark_rodata_ro(void)
{
   unsigned long section_size;

-    section_size = (unsigned long)_etext - (unsigned long)_text;
-    create_mapping_late(__pa_symbol(_text), (unsigned long)_text,
-                section_size, PAGE_KERNEL_ROX);
   /*
    * mark .rodata as read only. Use __init_begin rather than __end_rodata
    * to cover NOTES and EXCEPTION_TABLE.
@@ -484,7 +481,7 @@ static void __init map_kernel(pgd_t *pgd)
{
   static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data;

-    map_kernel_segment(pgd, _text, _etext, PAGE_KERNEL_EXEC, &vmlinux_text);
+    map_kernel_segment(pgd, _text, _etext, PAGE_KERNEL_ROX, &vmlinux_text);
   map_kernel_segment(pgd, __start_rodata, __init_begin, PAGE_KERNEL, &vmlinux_rodata);
   map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
              &vmlinux_init);
-- 
2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help