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

Re: [Xen-devel] Bug#852324: x86/mm: Found insecure W+X mapping





On 03/16/2017 08:18 PM, Ben Hutchings wrote:
On Thu, 2017-03-16 at 21:49 +0000, Andrew Cooper wrote:
On 16/03/2017 21:05, Ben Hutchings wrote:
On Thu, 2017-03-16 at 00:50 +0000, Ben Hutchings wrote:
On Wed, 2017-03-15 at 22:24 +0000, Ben Hutchings wrote:
Control: retitle -1 [xen] x86/mm: Found insecure W+X mapping
Control: tag -1 upstream confirmed
Control: found -1 4.9.13-1

I can reproduce this with a current Debian kernel on top of Xen 4.4.
It doesn't happen with the same hardware booting the kernel directly.

With CONFIG_X86_PTDUMP enabled, I can see that the first 16 MiB of the
low kernel mapping is mapped with W+X permissions, with a few
exceptions:

0xffff880000000000-0xffff880000099000         612K USR RW                     x 
 pte
0xffff880000099000-0xffff88000009a000           4K USR ro                     
NX pte
0xffff88000009a000-0xffff88000009b000           4K USR ro                     x 
 pte
0xffff88000009b000-0xffff88000009f000          16K USR RW                     
NX pte
0xffff88000009f000-0xffff880000100000         388K USR RW PWT PCD             x 
 pte
0xffff880000100000-0xffff880000102000           8K USR RW                     x 
 pte
0xffff880000102000-0xffff880001000000       15352K USR RW                     x 
 pte

This accounts for all the 4090 pages reported at boot.

I see this same mapping when running Linux 4.9 under either Xen 4.4 or
4.8 (from Debian stable or unstable).

I don't really understand how the PV MMU page tables are set up.  I did
try setting the NX flag in make_lowmem_page_readwrite() and that didn't
make any difference to the number of W+X pages.

64bit PV guests have some rather special pagetable set up.  For one, the
USR bit will be unconditionally set and Xen doesn't tolerate some
mappings being writeable,

I understood that much.

but these RWX areas are clearly ok in Xens eyes.

So that proves these pages aren't mapped to native page tables or other
sensitive structures, right?

Everything from 0xffff880000000000 upwards belongs to the guest kernel
per the PV ABI.  The initial layout will be constructed by the domain
builder on behalf of the kernel, but it is Linux's to arbitrarily alter
later on.

But it seems to avoid doing that in generic code - see phys_pte_init()
in arch/x86/mm/init_64.c.


I believe that's because we are reusing pre-built tables which don't have NX bit set, see xen_setup_kernel_pagetable().

-boris


Can you boot a debug hypervisor and look at `xl dmesg` starting at the
"*** LOADING DOMAIN 0 ***" line?  This should dump the state that the
domain builder leaves dom0 in, which would help identify whether those
regions are leftovers from the domain builder, or something constructed
by the Linux PV early boot code.

This is from a hypervisor built with CONFIG_DEBUG=y and everything else
set to defaults (I think):

(XEN) *** LOADING DOMAIN 0 ***
(XEN) ELF: phdr: paddr=0x1000000 memsz=0xac7000
(XEN) ELF: phdr: paddr=0x1c00000 memsz=0x11c000
(XEN) ELF: phdr: paddr=0x1d1c000 memsz=0x193d8
(XEN) ELF: phdr: paddr=0x1d36000 memsz=0x221000
(XEN) ELF: memory: 0x1000000 -> 0x1f57000
(XEN) ELF: note: GUEST_OS = "linux"
(XEN) ELF: note: GUEST_VERSION = "2.6"
(XEN) ELF: note: XEN_VERSION = "xen-3.0"
(XEN) ELF: note: VIRT_BASE = 0xffffffff80000000
(XEN) ELF: note: INIT_P2M = 0x8000000000
(XEN) ELF: note: ENTRY = 0xffffffff81d36180
(XEN) ELF: note: HYPERCALL_PAGE = 0xffffffff81001000
(XEN) ELF: note: FEATURES = 
"!writable_page_tables|pae_pgdir_above_4gb|writable_descriptor_tables|auto_translated_physmap|supervisor_mode_kernel"
(XEN) ELF: note: SUPPORTED_FEATURES = 0x90d
(XEN) ELF: note: PAE_MODE = "yes"
(XEN) ELF: note: LOADER = "generic"
(XEN) ELF: note: unknown (0xd)
(XEN) ELF: note: SUSPEND_CANCEL = 0x1
(XEN) ELF: note: MOD_START_PFN = 0x1
(XEN) ELF: note: HV_START_LOW = 0xffff800000000000
(XEN) ELF: note: PADDR_OFFSET = 0
(XEN) ELF: addresses:
(XEN)     virt_base        = 0xffffffff80000000
(XEN)     elf_paddr_offset = 0x0
(XEN)     virt_offset      = 0xffffffff80000000
(XEN)     virt_kstart      = 0xffffffff81000000
(XEN)     virt_kend        = 0xffffffff81f57000
(XEN)     virt_entry       = 0xffffffff81d36180
(XEN)     p2m_base         = 0x8000000000
(XEN)  Xen  kernel: 64-bit, lsb, compat32
(XEN)  Dom0 kernel: 64-bit, PAE, lsb, paddr 0x1000000 -> 0x1f57000
(XEN) PHYSICAL MEMORY ARRANGEMENT:
(XEN)  Dom0 alloc.:   0000000214000000->0000000216000000 (1947334 pages to be 
allocated)
(XEN)  Init. ramdisk: 000000021e45a000->000000021f5ff530
(XEN) VIRTUAL MEMORY ARRANGEMENT:
(XEN)  Loaded kernel: ffffffff81000000->ffffffff81f57000
(XEN)  Init. ramdisk: 0000000000000000->0000000000000000
(XEN)  Phys-Mach map: 0000008000000000->0000008000ef4360
(XEN)  Start info:    ffffffff81f57000->ffffffff81f574b4
(XEN)  Page tables:   ffffffff81f58000->ffffffff81f6b000
(XEN)  Boot stack:    ffffffff81f6b000->ffffffff81f6c000
(XEN)  TOTAL:         ffffffff80000000->ffffffff82000000
(XEN)  ENTRY ADDRESS: ffffffff81d36180
(XEN) Dom0 has maximum 4 VCPUs
(XEN) ELF: phdr 0 at 0xffffffff81000000 -> 0xffffffff81ac7000
(XEN) ELF: phdr 1 at 0xffffffff81c00000 -> 0xffffffff81d1c000
(XEN) ELF: phdr 2 at 0xffffffff81d1c000 -> 0xffffffff81d353d8
(XEN) ELF: phdr 3 at 0xffffffff81d36000 -> 0xffffffff81e7f000
(XEN) Bogus DMIBAR 0xfed18001 on 0000:00:00.0
(XEN) Scrubbing Free RAM on 1 nodes using 4 CPUs
(XEN) .................done.
(XEN) Initial low memory virq threshold set at 0x4000 pages.

Ben.



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


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

 


Rackspace

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