[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.5] memory: split and tighten maximum order permitted in memops
commit e0d450965b4c6aab28857f70ff1f78ba981bafbe Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Dec 8 14:08:41 2015 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Dec 8 14:08:41 2015 +0100 memory: split and tighten maximum order permitted in memops Introduce and enforce separate limits for ordinary DomU, DomU with pass-through device(s), control domain, and hardware domain. The DomU defaults were determined based on what so far was allowed by multipage_allocation_permitted(). The x86 hwdom default was chosen based on linux-2.6.18-xen.hg c/s 1102:82782f1361a9 indicating 2Mb is not enough, plus some slack. The ARM hwdom default was chosen to allow 2Mb (order-9) mappings, plus a little bit of slack. This is CVE-2015-8338 / XSA-158. Reported-by: Julien Grall <julien.grall@xxxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> master commit: 4a578b316eb98975374d88f28904acf13dbcfac2 master date: 2015-12-08 14:00:33 +0100 --- docs/misc/xen-command-line.markdown | 11 +++++ xen/common/memory.c | 72 ++++++++++++++++++++++++++-------- xen/include/asm-arm/config.h | 4 ++ xen/include/asm-arm/iocap.h | 4 -- xen/include/asm-x86/config.h | 5 ++- xen/include/asm-x86/iocap.h | 5 -- 6 files changed, 74 insertions(+), 27 deletions(-) diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index 13f03ad..84bca2a 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -948,6 +948,17 @@ with **crashinfo_maxaddr**. Specify the threshold below which Xen will inform dom0 that the quantity of free memory is getting low. Specifying `0` will disable this notification. +### memop-max-order +> `= [<domU>][,[<ctldom>][,[<hwdom>][,<ptdom>]]]` + +> x86 default: `9,18,12,12` +> ARM default: `9,18,10,10` + +Change the maximum order permitted for allocation (or allocation-like) +requests issued by the various kinds of domains (in this order: +ordinary DomU, control domain, hardware domain, and - when supported +by the platform - DomU with pass-through device assigned). + ### max\_cstate > `= <integer>` diff --git a/xen/common/memory.c b/xen/common/memory.c index 29986a6..2b5ba85 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -43,6 +43,50 @@ struct memop_args { int preempted; /* Was the hypercall preempted? */ }; +#ifndef CONFIG_CTLDOM_MAX_ORDER +#define CONFIG_CTLDOM_MAX_ORDER CONFIG_PAGEALLOC_MAX_ORDER +#endif +#ifndef CONFIG_PTDOM_MAX_ORDER +#define CONFIG_PTDOM_MAX_ORDER CONFIG_HWDOM_MAX_ORDER +#endif + +static unsigned int __read_mostly domu_max_order = CONFIG_DOMU_MAX_ORDER; +static unsigned int __read_mostly ctldom_max_order = CONFIG_CTLDOM_MAX_ORDER; +static unsigned int __read_mostly hwdom_max_order = CONFIG_HWDOM_MAX_ORDER; +#ifdef HAS_PASSTHROUGH +static unsigned int __read_mostly ptdom_max_order = CONFIG_PTDOM_MAX_ORDER; +#else +# define ptdom_max_order domu_max_order +#endif +static void __init parse_max_order(const char *s) +{ + if ( *s != ',' ) + domu_max_order = simple_strtoul(s, &s, 0); + if ( *s == ',' && *++s != ',' ) + ctldom_max_order = simple_strtoul(s, &s, 0); + if ( *s == ',' && *++s != ',' ) + hwdom_max_order = simple_strtoul(s, &s, 0); +#ifdef HAS_PASSTHROUGH + if ( *s == ',' && *++s != ',' ) + ptdom_max_order = simple_strtoul(s, &s, 0); +#endif +} +custom_param("memop-max-order", parse_max_order); + +static unsigned int max_order(const struct domain *d) +{ + unsigned int order = cache_flush_permitted(d) ? domu_max_order + : ptdom_max_order; + + if ( is_control_domain(d) && order < ctldom_max_order ) + order = ctldom_max_order; + + if ( is_hardware_domain(d) && order < hwdom_max_order ) + order = hwdom_max_order; + + return min(order, MAX_ORDER + 0U); +} + static void increase_reservation(struct memop_args *a) { struct page_info *page; @@ -55,7 +99,7 @@ static void increase_reservation(struct memop_args *a) a->nr_extents-1) ) return; - if ( !multipage_allocation_permitted(current->domain, a->extent_order) ) + if ( a->extent_order > max_order(current->domain) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -100,8 +144,8 @@ static void populate_physmap(struct memop_args *a) a->nr_extents-1) ) return; - if ( a->memflags & MEMF_populate_on_demand ? a->extent_order > MAX_ORDER : - !multipage_allocation_permitted(current->domain, a->extent_order) ) + if ( a->extent_order > (a->memflags & MEMF_populate_on_demand ? MAX_ORDER : + max_order(current->domain)) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -272,7 +316,7 @@ static void decrease_reservation(struct memop_args *a) if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done, a->nr_extents-1) || - a->extent_order > MAX_ORDER ) + a->extent_order > max_order(current->domain) ) return; for ( i = a->nr_done; i < a->nr_extents; i++ ) @@ -337,13 +381,17 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) if ( copy_from_guest(&exch, arg, 1) ) return -EFAULT; + if ( max(exch.in.extent_order, exch.out.extent_order) > + max_order(current->domain) ) + { + rc = -EPERM; + goto fail_early; + } + /* Various sanity checks. */ if ( (exch.nr_exchanged > exch.in.nr_extents) || /* Input and output domain identifiers match? */ (exch.in.domid != exch.out.domid) || - /* Extent orders are sensible? */ - (exch.in.extent_order > MAX_ORDER) || - (exch.out.extent_order > MAX_ORDER) || /* Sizes of input and output lists do not overflow a long? */ ((~0UL >> exch.in.extent_order) < exch.in.nr_extents) || ((~0UL >> exch.out.extent_order) < exch.out.nr_extents) || @@ -362,16 +410,6 @@ static long memory_exchange(XEN_GUEST_HANDLE_PARAM(xen_memory_exchange_t) arg) goto fail_early; } - /* Only privileged guests can allocate multi-page contiguous extents. */ - if ( !multipage_allocation_permitted(current->domain, - exch.in.extent_order) || - !multipage_allocation_permitted(current->domain, - exch.out.extent_order) ) - { - rc = -EPERM; - goto fail_early; - } - if ( exch.in.extent_order <= exch.out.extent_order ) { in_chunk_order = exch.out.extent_order - exch.in.extent_order; diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h index 264e2c1..82ea362 100644 --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -39,6 +39,10 @@ #define CONFIG_IRQ_HAS_MULTIPLE_ACTION 1 +#define CONFIG_PAGEALLOC_MAX_ORDER 18 +#define CONFIG_DOMU_MAX_ORDER 9 +#define CONFIG_HWDOM_MAX_ORDER 10 + #define OPT_CONSOLE_STR "dtuart" #ifdef MAX_PHYS_CPUS diff --git a/xen/include/asm-arm/iocap.h b/xen/include/asm-arm/iocap.h index 22cfa41..276fefb 100644 --- a/xen/include/asm-arm/iocap.h +++ b/xen/include/asm-arm/iocap.h @@ -4,10 +4,6 @@ #define cache_flush_permitted(d) \ (!rangeset_is_empty((d)->iomem_caps)) -#define multipage_allocation_permitted(d, order) \ - (((order) <= 9) || /* allow 2MB superpages */ \ - !rangeset_is_empty((d)->iomem_caps)) - #endif /* diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 3802721..2f835bf 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -28,9 +28,12 @@ #define CONFIG_NUMA 1 #define CONFIG_DISCONTIGMEM 1 #define CONFIG_NUMA_EMU 1 -#define CONFIG_PAGEALLOC_MAX_ORDER (2 * PAGETABLE_ORDER) #define CONFIG_DOMAIN_PAGE 1 +#define CONFIG_PAGEALLOC_MAX_ORDER (2 * PAGETABLE_ORDER) +#define CONFIG_DOMU_MAX_ORDER PAGETABLE_ORDER +#define CONFIG_HWDOM_MAX_ORDER 12 + /* Intel P4 currently has largest cache line (L2 line size is 128 bytes). */ #define CONFIG_X86_L1_CACHE_SHIFT 7 diff --git a/xen/include/asm-x86/iocap.h b/xen/include/asm-x86/iocap.h index 591ae17..eee4722 100644 --- a/xen/include/asm-x86/iocap.h +++ b/xen/include/asm-x86/iocap.h @@ -18,9 +18,4 @@ (!rangeset_is_empty((d)->iomem_caps) || \ !rangeset_is_empty((d)->arch.ioport_caps)) -#define multipage_allocation_permitted(d, order) \ - (((order) <= 9) || /* allow 2MB superpages */ \ - !rangeset_is_empty((d)->iomem_caps) || \ - !rangeset_is_empty((d)->arch.ioport_caps)) - #endif /* __X86_IOCAP_H__ */ -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.5 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |