From: Ian Campbell <ian.campbell@citrix.com>
To: xen-devel@lists.xen.org
Cc: Tim Deegan <tim@xen.org>, Ian Campbell <ian.campbell@citrix.com>,
Jan Beulich <JBeulich@suse.com>
Subject: [PATCH 4.0-testing 03/10] hvm: Limit the size of large HVM op batches
Date: Mon, 11 Feb 2013 13:12:46 +0000 [thread overview]
Message-ID: <1360588373-779-3-git-send-email-ian.campbell@citrix.com> (raw)
In-Reply-To: <1360588355.20449.34.camel@zakaz.uk.xensource.com>
From: Tim Deegan <tim@xen.org>
Doing large p2m updates for HVMOP_track_dirty_vram without preemption
ties up the physical processor. Integrating preemption into the p2m
updates is hard so simply limit to 1GB which is sufficient for a 15000
* 15000 * 32bpp framebuffer.
For HVMOP_modified_memory and HVMOP_set_mem_type preemptible add the
necessary machinery to handle preemption.
This is CVE-2012-5511 / XSA-27.
Signed-off-by: Tim Deegan <tim@xen.org>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
x86/paging: Don't allocate user-controlled amounts of stack memory.
This is XSA-27 / CVE-2012-5511.
Signed-off-by: Tim Deegan <tim@xen.org>
Acked-by: Jan Beulich <jbeulich@suse.com>
v2: Provide definition of GB to fix x86-32 compile.
Signed-off-by: Jan Beulich <JBeulich@suse.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
xen/arch/x86/hvm/hvm.c | 37 +++++++++++++++++++++++++++++++++----
xen/arch/x86/mm/paging.c | 17 +++++++++++------
xen/include/asm-x86/config.h | 4 +++-
3 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 640969b..1ab0ec6 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -2943,6 +2943,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
if ( !is_hvm_domain(d) )
goto param_fail2;
+ if ( a.nr > GB(1) >> PAGE_SHIFT )
+ goto param_fail2;
+
rc = xsm_hvm_param(d, op);
if ( rc )
goto param_fail2;
@@ -2969,7 +2972,6 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
{
struct xen_hvm_modified_memory a;
struct domain *d;
- unsigned long pfn;
if ( copy_from_guest(&a, arg, 1) )
return -EFAULT;
@@ -2996,8 +2998,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
if ( !paging_mode_log_dirty(d) )
goto param_fail3;
- for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
+ while ( a.nr > 0 )
{
+ unsigned long pfn = a.first_pfn;
p2m_type_t t;
mfn_t mfn = gfn_to_mfn(d, pfn, &t);
if ( p2m_is_paging(t) )
@@ -3018,6 +3021,19 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
/* don't take a long time and don't die either */
sh_remove_shadows(d->vcpu[0], mfn, 1, 0);
}
+
+ a.first_pfn++;
+ a.nr--;
+
+ /* Check for continuation if it's not the last interation */
+ if ( a.nr > 0 && hypercall_preempt_check() )
+ {
+ if ( copy_to_guest(arg, &a, 1) )
+ rc = -EFAULT;
+ else
+ rc = -EAGAIN;
+ break;
+ }
}
param_fail3:
@@ -3029,7 +3045,6 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
{
struct xen_hvm_set_mem_type a;
struct domain *d;
- unsigned long pfn;
/* Interface types to internal p2m types */
p2m_type_t memtype[] = {
@@ -3062,8 +3077,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
if ( a.hvmmem_type >= ARRAY_SIZE(memtype) )
goto param_fail4;
- for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
+ while ( a.nr > 0 )
{
+ unsigned long pfn = a.first_pfn;
p2m_type_t t;
p2m_type_t nt;
mfn_t mfn;
@@ -3099,6 +3115,19 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
goto param_fail4;
}
}
+
+ a.first_pfn++;
+ a.nr--;
+
+ /* Check for continuation if it's not the last interation */
+ if ( a.nr > 0 && hypercall_preempt_check() )
+ {
+ if ( copy_to_guest(arg, &a, 1) )
+ rc = -EFAULT;
+ else
+ rc = -EAGAIN;
+ goto param_fail4;
+ }
}
rc = 0;
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
index b11577a..bba747e 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -486,13 +486,18 @@ int paging_log_dirty_range(struct domain *d,
if ( !d->arch.paging.log_dirty.fault_count &&
!d->arch.paging.log_dirty.dirty_count ) {
- int size = (nr + BITS_PER_LONG - 1) / BITS_PER_LONG;
- unsigned long zeroes[size];
- memset(zeroes, 0x00, size * BYTES_PER_LONG);
+ static uint8_t zeroes[PAGE_SIZE];
+ int off, size;
+
+ size = ((nr + BITS_PER_LONG - 1) / BITS_PER_LONG) * sizeof (long);
rv = 0;
- if ( copy_to_guest_offset(dirty_bitmap, 0, (uint8_t *) zeroes,
- size * BYTES_PER_LONG) != 0 )
- rv = -EFAULT;
+ for ( off = 0; !rv && off < size; off += sizeof zeroes )
+ {
+ int todo = min(size - off, (int) PAGE_SIZE);
+ if ( copy_to_guest_offset(dirty_bitmap, off, zeroes, todo) )
+ rv = -EFAULT;
+ off += todo;
+ }
goto out;
}
d->arch.paging.log_dirty.fault_count = 0;
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index c9e6057..462df51 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -108,6 +108,9 @@ extern unsigned int trampoline_xen_phys_start;
extern unsigned char trampoline_cpu_started;
extern char wakeup_start[];
extern unsigned int video_mode, video_flags;
+
+#define GB(_gb) (_gb ## UL << 30)
+
#endif
#define asmlinkage
@@ -123,7 +126,6 @@ extern unsigned int video_mode, video_flags;
#define PML4_ADDR(_slot) \
((((_slot ## UL) >> 8) * 0xffff000000000000UL) | \
(_slot ## UL << PML4_ENTRY_BITS))
-#define GB(_gb) (_gb ## UL << 30)
#else
#define PML4_ENTRY_BYTES (1 << PML4_ENTRY_BITS)
#define PML4_ADDR(_slot) \
--
1.7.2.5
next prev parent reply other threads:[~2013-02-11 13:12 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-11 13:12 [PATCH 4.0-testing 00/10] XSA-{25, 27, 33, 36}: Backports for 4.0 (for Debian update) Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 01/10] libxc: Do not use dom0 physmem as parameter to lzma decoder Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 02/10] libxc: builder: limit maximum size of kernel/ramdisk Ian Campbell
2013-02-11 13:12 ` Ian Campbell [this message]
2013-02-11 13:12 ` [PATCH 4.0-testing 04/10] x86/mm: Fix loop increment in paging_log_dirty_range() Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 05/10] VT-d: fix interrupt remapping source validation for devices behind legacy bridges Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 06/10] AMD IOMMU: Fix an interrupt remapping issue Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 07/10] ACPI: acpi_table_parse() should return handler's error code Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 08/10] AMD, IOMMU: Clean up old entries in remapping tables when creating new one Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 09/10] AMD, IOMMU: Disable IOMMU if SATA Combined mode is on Ian Campbell
2013-02-11 13:12 ` [PATCH 4.0-testing 10/10] AMD, IOMMU: Make per-device interrupt remapping table default Ian Campbell
2013-02-12 9:44 ` [PATCH 4.0-testing 00/10] XSA-{25, 27, 33, 36}: Backports for 4.0 (for Debian update) Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1360588373-779-3-git-send-email-ian.campbell@citrix.com \
--to=ian.campbell@citrix.com \
--cc=JBeulich@suse.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).