[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] arm: poison initmem when it is freed.



commit 3ac7ca1c9dafd734ccccba456e37024f80b78675
Author:     Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
AuthorDate: Fri Sep 9 14:41:05 2016 -0400
Commit:     Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
CommitDate: Fri Sep 23 12:39:45 2016 -0400

    arm: poison initmem when it is freed.
    
    The current byte sequence is '0xcc' which makes sense on x86,
    but on ARM it is:
    
    cccccccc        stclgt  12, cr12, [ip], {204}   ; 0xcc
    
    Picking something more ARM applicable such as:
    
    efefefef        svc     0x00efefef
    
    Creates a nice crash if one executes that code:
    (XEN) CPU1: Unexpected Trap: Supervisor Call
    
    But unfortunately that may not be a good choice either as in the future
    we may want to implement support for it.
    
    Julien suggested that we use a 4-byte insn instruction instead
    of trying to work with one byte. To make sure nothing goes bad
    we also require that the __init_[begin|end] be aligned properly.
    
    As such on ARM 32 we use the udf instruction (see A8.8.247
    in ARM DDI 0406C.c) and on ARM 64 use the AARCH64_BREAK_FAULT
    instruction (aka brk instruction).
    
    We don't have to worry about Thumb code so this instruction
    is a safe to execute.
    
    Reviewed-by: Julien Grall <julien.grall@xxxxxxx>
    Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
 xen/arch/arm/mm.c      | 15 ++++++++++++++-
 xen/arch/arm/xen.lds.S |  6 ++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 07e2037..99588a3 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -994,8 +994,21 @@ void free_init_memory(void)
 {
     paddr_t pa = virt_to_maddr(__init_begin);
     unsigned long len = __init_end - __init_begin;
+    uint32_t insn;
+    unsigned int i, nr = len / sizeof(insn);
+    uint32_t *p;
+
     set_pte_flags_on_range(__init_begin, len, mg_rw);
-    memset(__init_begin, 0xcc, len);
+#ifdef CONFIG_ARM_32
+    /* udf instruction i.e (see A8.8.247 in ARM DDI 0406C.c) */
+    insn = 0xe7f000f0;
+#else
+    insn = AARCH64_BREAK_FAULT;
+#endif
+    p = (uint32_t *)__init_begin;
+    for ( i = 0; i < nr; i++ )
+        *(p + i) = insn;
+
     set_pte_flags_on_range(__init_begin, len, mg_clear);
     init_domheap_pages(pa, pa + len);
     printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10);
diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
index 47b910d..ddef595 100644
--- a/xen/arch/arm/xen.lds.S
+++ b/xen/arch/arm/xen.lds.S
@@ -221,3 +221,9 @@ SECTIONS
  * code running on the boot time identity map cannot cross a section boundary.
  */
 ASSERT( _end_boot - start <= PAGE_SIZE, "Boot code is larger than 4K")
+/*
+ * __init_[begin|end] MUST be at word size boundary otherwise we cannot
+ * write fault instructions in the space properly.
+ */
+ASSERT(IS_ALIGNED(__init_begin,     4), "__init_begin is misaligned")
+ASSERT(IS_ALIGNED(__init_end,       4), "__init_end is misaligned")
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.