[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] Xen Security Advisory 245 - ARM: Some memory not scrubbed at boot
From:       Xen.org security team <security () xen ! org>
Date:       2017-09-28 17:26:20
Message-ID: E1dxcZo-0000QF-6K () xenbits ! xenproject ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

                    Xen Security Advisory XSA-245

                 ARM: Some memory not scrubbed at boot

NOTE REGARDING LACK OF EMBARGO
==============================

This bug was discussed publicly before it was realised that it was a
security vulnerability.

ISSUE DESCRIPTION
=================

Data can remain readable in DRAM across soft and even hard reboots.
To ensure that sensitive data is not leaked from one domain to another
after a reboot, Xen must "scrub" all memory on boot (write it with
zeroes).

Unfortunately, it was discovered that when memory was in disjoint blocks,
or when the first block didn't begin at physical address 0, arithmetic
errors meant that some memory was not scrubbed.

IMPACT
======

Sensitive information from one domain before a reboot might be visible
to another domain after a reboot.

VULNERABLE SYSTEMS
==================

Only ARM systems are vulnerable.

All versions of Xen since 4.5 are vulnerable.

Only hardware with disjoint blocks, or physical addresses not starting at 0
are vulnerable; this includes the majority of ARM systems.

MITIGATION
==========

None.

RESOLUTION
==========

Applying the appropriate attached patches resolves this issue.

xsa245/*.patch         All versions of Xen

$ sha256sum xsa245* xsa245*/*
121829263b85fcb5eac8e38fb44e77d3aab1dd7ae6ef665bf84bb49e5e161d24  xsa245.meta
526f9e1b127fbb316762ce8e8f4563bc9de0c55a1db581456a3017d570d35bdd  \
xsa245/0001-xen-page_alloc-Cover-memory-unreserved-after-boot-in.patch \
7164010112fcccd9cd88e72ace2eeabdb364dd6f4d05c434686267d18067f420  \
xsa245/0002-xen-arm-Correctly-report-the-memory-region-in-the-du.patch $

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAEBCAAGBQJZzTANAAoJEIP+FMlX6CvZHk4IAJpF4ruPkFKdCgsQ/ljjrpxO
8CVQFVwxTLtLZGUB1ZP0nFntkT/FnhDo870EmDvjPZTq3MmQwlPwVhgPqmF+tsTC
aMecUftEJxHm6cSRLYiIGEphGbJZR6utjTKd7l0ddni5QtnzUED8mE5WFAq4aLrS
y8FHuyghE6nwBXEMhRiDYYZ2X0MeMeTisc/0s1Loe002zcpw0RUlmys21Uzzd1Xv
t4n5e4RDMLUNpfpY3o4UVWcJJi55Bpxw9ke4IMExlNSbYR5qQeNigDT0CcE1bv6n
mNwlADAUKT4t/K1fyk6XJLFIdzHt5NVmN2O9cYKt6voVMu1r1dh3TgiAffAJsxk=
=Pi1Y
-----END PGP SIGNATURE-----


["xsa245.meta" (application/octet-stream)]
["xsa245/0001-xen-page_alloc-Cover-memory-unreserved-after-boot-in.patch" (application/octet-stream)]

From a48d47febc1340f27d6c716545692641a09b414c Mon Sep 17 00:00:00 2001
From: Julien Grall <julien.grall@arm.com>
Date: Thu, 21 Sep 2017 14:13:08 +0100
Subject: [PATCH 1/2] xen/page_alloc: Cover memory unreserved after boot in
 first_valid_mfn

On Arm, some regions (e.g Initramfs, Dom0 Kernel...) are marked as
reserved until the hardware domain is built and they are copied into its
memory. Therefore, they will not be added in the boot allocator via
init_boot_pages.

Instead, init_xenheap_pages will be called once the region are not used
anymore.

Update first_valid_mfn in both init_heap_pages and init_boot_pages
(already exist) to cover all the cases.

Signed-off-by: Julien Grall <julien.grall@arm.com>
[Adjust comment, added locking around first_valid_mfn update]
Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
 xen/common/page_alloc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 0b9f6cc6df..fbe5a8af39 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -1700,6 +1700,16 @@ static void init_heap_pages(
 {
     unsigned long i;
 
+    /*
+     * Some pages may not go through the boot allocator (e.g reserved
+     * memory at boot but released just after --- kernel, initramfs,
+     * etc.).
+     * Update first_valid_mfn to ensure those regions are covered.
+     */
+    spin_lock(&heap_lock);
+    first_valid_mfn = min_t(unsigned long, page_to_mfn(pg), first_valid_mfn);
+    spin_unlock(&heap_lock);
+
     for ( i = 0; i < nr_pages; i++ )
     {
         unsigned int nid = phys_to_nid(page_to_maddr(pg+i));
-- 
2.11.0


["xsa245/0002-xen-arm-Correctly-report-the-memory-region-in-the-du.patch" (application/octet-stream)]

From cbfcf039d0e0b6f4c4cb3de612f7bf788a0c47cd Mon Sep 17 00:00:00 2001
From: Julien Grall <julien.grall@arm.com>
Date: Mon, 18 Sep 2017 14:24:08 +0100
Subject: [PATCH 2/2] xen/arm: Correctly report the memory region in the dummy
 NUMA helpers

NUMA is currently not supported on Arm. Because common code is
NUMA-aware, dummy helpers are instead provided to expose a single node.

Those helpers are for instance used to know the region to scrub.

However the memory region is not reported correctly. Indeed, the
frametable may not be at the beginning of the memory and there might be
multiple memory banks. This will lead to not scrub some part of the
memory.

The memory information can be found using:
    * first_valid_mfn as the start of the memory
    * max_page - first_valid_mfn as the spanned pages

Note that first_valid_mfn is now been exported. The prototype has been
added in asm-arm/numa.h and not in a common header because I would
expect the variable to become static once NUMA is fully supported on
Arm.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 xen/common/page_alloc.c    |  6 +++++-
 xen/include/asm-arm/numa.h | 10 ++++++++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index fbe5a8af39..472c6fe329 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -192,7 +192,11 @@ PAGE_LIST_HEAD(page_broken_list);
  * BOOT-TIME ALLOCATOR
  */
 
-static unsigned long __initdata first_valid_mfn = ~0UL;
+/*
+ * first_valid_mfn is exported because it is use in ARM specific NUMA
+ * helpers. See comment in asm-arm/numa.h.
+ */
+unsigned long first_valid_mfn = ~0UL;
 
 static struct bootmem_region {
     unsigned long s, e; /* MFNs @s through @e-1 inclusive are free */
diff --git a/xen/include/asm-arm/numa.h b/xen/include/asm-arm/numa.h
index a2c1a3476d..3e7384da9e 100644
--- a/xen/include/asm-arm/numa.h
+++ b/xen/include/asm-arm/numa.h
@@ -12,9 +12,15 @@ static inline __attribute__((pure)) nodeid_t phys_to_nid(paddr_t addr)
     return 0;
 }
 
+/*
+ * TODO: make first_valid_mfn static when NUMA is supported on Arm, this
+ * is required because the dummy helpers is using it.
+ */
+extern unsigned long first_valid_mfn;
+
 /* XXX: implement NUMA support */
-#define node_spanned_pages(nid) (total_pages)
-#define node_start_pfn(nid) (pdx_to_pfn(frametable_base_pdx))
+#define node_spanned_pages(nid) (max_page - first_valid_mfn)
+#define node_start_pfn(nid) (first_valid_mfn)
 #define __node_distance(a, b) (20)
 
 static inline unsigned int arch_get_dma_bitsize(void)
-- 
2.11.0



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic