Import of pkgsrc-2014Q1
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
# $NetBSD: Makefile,v 1.23 2013/06/19 14:03:41 gdt Exp $
|
||||
#
|
||||
# $NetBSD: Makefile,v 1.35 2014/03/28 16:07:08 drochner Exp $
|
||||
|
||||
VERSION= 4.1.5
|
||||
VERSION= 4.1.6.1
|
||||
DISTNAME= xen-${VERSION}
|
||||
PKGNAME= xenkernel41-${VERSION}
|
||||
PKGREVISION= 1
|
||||
PKGREVISION= 8
|
||||
CATEGORIES= sysutils
|
||||
MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/
|
||||
|
||||
@@ -22,6 +21,7 @@ USE_TOOLS+= gmake
|
||||
|
||||
PYTHON_FOR_BUILD_ONLY= yes
|
||||
PY_PATCHPLIST= NO
|
||||
PYTHON_VERSIONS_INCOMPATIBLE= 33 # not yet ported as of 4.1.6.1
|
||||
|
||||
# XXX Why does this not work?
|
||||
# See work/xen-4.1.2/Config.mk:41 why PYTHON must be set and what for
|
||||
@@ -36,7 +36,9 @@ MESSAGE_SUBST+= XENKERNELDIR=${XENKERNELDIR:Q}
|
||||
.include "../../mk/compiler.mk"
|
||||
.if !empty(PKGSRC_COMPILER:Mclang)
|
||||
EXTRA_CFLAGS+= -Qunused-arguments -no-integrated-as -Wno-error=format \
|
||||
-Wno-error=parentheses-equality -Wno-error=enum-conversion
|
||||
-Wno-error=parentheses-equality -Wno-error=enum-conversion \
|
||||
-Wno-error=unused-function \
|
||||
-Wno-error=tautological-pointer-compare
|
||||
.endif
|
||||
|
||||
MAKE_ENV+= EXTRA_CFLAGS=${EXTRA_CFLAGS:Q}
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
$NetBSD: distinfo,v 1.17 2013/05/03 16:48:37 drochner Exp $
|
||||
$NetBSD: distinfo,v 1.27 2014/03/28 16:07:08 drochner Exp $
|
||||
|
||||
SHA1 (xen-4.1.5.tar.gz) = 38f098cdbcf4612a6e059e6ad332e68bbfc8bf4d
|
||||
RMD160 (xen-4.1.5.tar.gz) = 265d6a9faee6cf9314f4ed647604f7b43c327f52
|
||||
Size (xen-4.1.5.tar.gz) = 10421420 bytes
|
||||
SHA1 (patch-CVE-2013-1918_1) = 7403c3cc0b6481edf581591885843ee24154da06
|
||||
SHA1 (patch-CVE-2013-1918_10) = 3aa6a519013fa3275ad389533e9ebcf0f29e24b7
|
||||
SHA1 (patch-CVE-2013-1918_11) = 57ddcc8afcab390a1ac027a6a063677c89310662
|
||||
SHA1 (patch-CVE-2013-1918_12) = 3d768316139ea189219de4dff13fc1190fbe27a2
|
||||
SHA1 (patch-CVE-2013-1918_13) = bccb34626942b17ed0097977d5a16adcf7acd746
|
||||
SHA1 (patch-CVE-2013-1918_2) = b5a5ddf9549ba4064f587fa6769730158a165bd6
|
||||
SHA1 (patch-CVE-2013-1918_3) = bd6b95c3c359638f1cb95bb9b4119836cb421fea
|
||||
SHA1 (patch-CVE-2013-1918_4) = e6e6648cdf81e543f5c410b1083b97bdd9a08ea6
|
||||
SHA1 (patch-CVE-2013-1918_5) = 0bc2755b024d14d53e83b47621f6a550538b5347
|
||||
SHA1 (patch-CVE-2013-1918_6) = 027711424053ebae1093ff7d4be2353113612b5c
|
||||
SHA1 (patch-CVE-2013-1918_7) = 77414ec5283278433a15a96e91ed5842326370b9
|
||||
SHA1 (patch-CVE-2013-1918_8) = 1abd13678a24365ab651483fb3e3feeb2c0248ce
|
||||
SHA1 (patch-CVE-2013-1918_9) = 28a34dda25693501c78043f550009dba53fa9e62
|
||||
SHA1 (patch-CVE-2013-1952) = b8976b41cc0520993f3c424030f7c9aa8a9be1f3
|
||||
SHA1 (xen-4.1.6.1.tar.gz) = e5f15feb0821578817a65ede16110c6eac01abd0
|
||||
RMD160 (xen-4.1.6.1.tar.gz) = bff11421fc44a26f2cc3156713267abcb36d7a19
|
||||
Size (xen-4.1.6.1.tar.gz) = 10428485 bytes
|
||||
SHA1 (patch-CVE-2013-1442) = 7aa43513ea7cddc50b4e6802412cfc2903cce8e1
|
||||
SHA1 (patch-CVE-2013-4355_1) = 91fb26907b2ac7d2435a6efce000569b71523247
|
||||
SHA1 (patch-CVE-2013-4355_2) = 70fd2f2e45a05a53d8ce7d0bd72b18165dd13509
|
||||
SHA1 (patch-CVE-2013-4355_3) = 93f7bf877945e585fb906dbfc8159e688813c12f
|
||||
SHA1 (patch-CVE-2013-4355_4) = 88f478997d2631ec41adfd42a9d79f2d87bb44d8
|
||||
SHA1 (patch-CVE-2013-4361) = b9074af976ba98c02aeb84288a10527bf7693241
|
||||
SHA1 (patch-CVE-2013-4368) = 77caf392b472e5586eb2fa6a37d173cd856f6f15
|
||||
SHA1 (patch-CVE-2013-4494) = d74dfc898d1128f3c205bd178c8cf663935711e3
|
||||
SHA1 (patch-CVE-2013-4553) = 6708dcef1737b119a3fcf2e3414c22c115cbacc1
|
||||
SHA1 (patch-CVE-2013-6885_1) = 18d155b2c76119988be32cfd43e3c4aa6a507b9d
|
||||
SHA1 (patch-CVE-2013-6885_2) = be3c99ba3e349492d45cd4f2fce0acc26ac1a96d
|
||||
SHA1 (patch-CVE-2014-1666) = acf27080799d4aae6a03b556caadb01081d5314e
|
||||
SHA1 (patch-Config.mk) = a43ed1b3304d6383dc093acd128a7f373d0ca266
|
||||
SHA1 (patch-xen_Makefile) = d1c7e4860221f93d90818f45a77748882486f92b
|
||||
SHA1 (patch-xen_arch_x86_Rules.mk) = 6b9b4bfa28924f7d3f6c793a389f1a7ac9d228e2
|
||||
SHA1 (patch-xen_arch_x86_cpu_mcheck_vmce.c) = 5afd01780a13654f1d21bf1562f6431c8370be0b
|
||||
SHA1 (patch-xen_arch_x86_time.c) = 2dedd8ea1d372ecffea70aad448756dd3688cfba
|
||||
SHA1 (patch-xen_arch_x86_time.c) = 1611959c08ad79e3f042ac70c8d9d57b60225289
|
||||
SHA1 (patch-xen_drivers_char_console_c) = 0fe186369602ccffaeec6f4bfbee8bb4298d3ff0
|
||||
SHA1 (patch-xen_include_xen_stdarg.h) = e9df974a9b783ed442ab17497198432cb9844b70
|
||||
|
||||
27
sysutils/xenkernel41/patches/patch-CVE-2013-1442
Normal file
27
sysutils/xenkernel41/patches/patch-CVE-2013-1442
Normal file
@@ -0,0 +1,27 @@
|
||||
$NetBSD: patch-CVE-2013-1442,v 1.1 2013/10/01 14:54:44 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-09/msg02523.html
|
||||
|
||||
--- xen/arch/x86/i387.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/i387.c 2013-09-30 15:23:07.000000000 +0000
|
||||
@@ -103,9 +103,9 @@ void setup_fpu(struct vcpu *v)
|
||||
{
|
||||
/*
|
||||
* XCR0 normally represents what guest OS set. In case of Xen itself,
|
||||
- * we set all supported feature mask before doing save/restore.
|
||||
+ * we set all supported feature mask before restoring.
|
||||
*/
|
||||
- set_xcr0(v->arch.xcr0_accum);
|
||||
+ set_xcr0(xfeature_mask);
|
||||
xrstor(v);
|
||||
set_xcr0(v->arch.xcr0);
|
||||
}
|
||||
@@ -149,7 +149,7 @@ void save_init_fpu(struct vcpu *v)
|
||||
if ( xsave_enabled(v) )
|
||||
{
|
||||
/* XCR0 normally represents what guest OS set. In case of Xen itself,
|
||||
- * we set all accumulated feature mask before doing save/restore.
|
||||
+ * we set all accumulated feature mask before saving.
|
||||
*/
|
||||
set_xcr0(v->arch.xcr0_accum);
|
||||
if ( cpu_has_xsaveopt )
|
||||
@@ -1,24 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_1,v 1.1 2013/05/03 16:48:37 drochner Exp $
|
||||
|
||||
see http://lists.xen.org/archives/html/xen-announce/2013-05/msg00000.html
|
||||
|
||||
--- xen/include/xen/domain.h.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/include/xen/domain.h
|
||||
@@ -15,7 +15,7 @@ struct vcpu *alloc_vcpu(
|
||||
int boot_vcpu(
|
||||
struct domain *d, int vcpuid, vcpu_guest_context_u ctxt);
|
||||
struct vcpu *alloc_dom0_vcpu0(void);
|
||||
-void vcpu_reset(struct vcpu *v);
|
||||
+int vcpu_reset(struct vcpu *);
|
||||
|
||||
struct xen_domctl_getdomaininfo;
|
||||
void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info);
|
||||
@@ -57,7 +57,7 @@ void arch_dump_vcpu_info(struct vcpu *v)
|
||||
|
||||
void arch_dump_domain_info(struct domain *d);
|
||||
|
||||
-void arch_vcpu_reset(struct vcpu *v);
|
||||
+int arch_vcpu_reset(struct vcpu *);
|
||||
|
||||
bool_t domctl_lock_acquire(void);
|
||||
void domctl_lock_release(void);
|
||||
@@ -1,21 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_10,v 1.1 2013/05/03 16:48:37 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/traps.c.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/arch/x86/traps.c
|
||||
@@ -2317,8 +2317,15 @@ static int emulate_privileged_op(struct
|
||||
rc = new_guest_cr3(gmfn_to_mfn(v->domain, compat_cr3_to_pfn(*reg)));
|
||||
#endif
|
||||
domain_unlock(v->domain);
|
||||
- if ( rc == 0 ) /* not okay */
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -EAGAIN: /* retry after preemption */
|
||||
+ goto skip;
|
||||
+ default: /* not okay */
|
||||
goto fail;
|
||||
+ }
|
||||
break;
|
||||
|
||||
case 4: /* Write CR4 */
|
||||
@@ -1,261 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_11,v 1.1 2013/05/03 16:48:37 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/domain.c.orig 2013-05-03 13:27:23.000000000 +0000
|
||||
+++ xen/arch/x86/domain.c
|
||||
@@ -70,8 +70,6 @@ void (*dead_idle) (void) __read_mostly =
|
||||
static void paravirt_ctxt_switch_from(struct vcpu *v);
|
||||
static void paravirt_ctxt_switch_to(struct vcpu *v);
|
||||
|
||||
-static void vcpu_destroy_pagetables(struct vcpu *v);
|
||||
-
|
||||
static void continue_idle_domain(struct vcpu *v)
|
||||
{
|
||||
reset_stack_and_jump(idle_loop);
|
||||
@@ -678,6 +676,7 @@ int arch_set_info_guest(
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
unsigned long cr3_pfn = INVALID_MFN;
|
||||
+ struct page_info *cr3_page;
|
||||
unsigned long flags, cr4;
|
||||
int i, rc = 0, compat;
|
||||
|
||||
@@ -817,72 +816,103 @@ int arch_set_info_guest(
|
||||
if ( rc != 0 )
|
||||
return rc;
|
||||
|
||||
+ set_bit(_VPF_in_reset, &v->pause_flags);
|
||||
+
|
||||
if ( !compat )
|
||||
- {
|
||||
cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
|
||||
+#ifdef __x86_64__
|
||||
+ else
|
||||
+ cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
|
||||
+#endif
|
||||
+ cr3_page = mfn_to_page(cr3_pfn);
|
||||
|
||||
- if ( !mfn_valid(cr3_pfn) ||
|
||||
- (paging_mode_refcounts(d)
|
||||
- ? !get_page(mfn_to_page(cr3_pfn), d)
|
||||
- : !get_page_and_type(mfn_to_page(cr3_pfn), d,
|
||||
- PGT_base_page_table)) )
|
||||
- {
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+ if ( !mfn_valid(cr3_pfn) || !get_page(cr3_page, d) )
|
||||
+ {
|
||||
+ cr3_page = NULL;
|
||||
+ rc = -EINVAL;
|
||||
+ }
|
||||
+ else if ( paging_mode_refcounts(d) )
|
||||
+ /* nothing */;
|
||||
+ else if ( cr3_page == v->arch.old_guest_table )
|
||||
+ {
|
||||
+ v->arch.old_guest_table = NULL;
|
||||
+ put_page(cr3_page);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /*
|
||||
+ * Since v->arch.guest_table{,_user} are both NULL, this effectively
|
||||
+ * is just a call to put_old_guest_table().
|
||||
+ */
|
||||
+ if ( !compat )
|
||||
+ rc = vcpu_destroy_pagetables(v);
|
||||
+ if ( !rc )
|
||||
+ rc = get_page_type_preemptible(cr3_page,
|
||||
+ !compat ? PGT_root_page_table
|
||||
+ : PGT_l3_page_table);
|
||||
+ if ( rc == -EINTR )
|
||||
+ rc = -EAGAIN;
|
||||
+ }
|
||||
|
||||
+ if ( rc )
|
||||
+ /* handled below */;
|
||||
+ else if ( !compat )
|
||||
+ {
|
||||
v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
|
||||
|
||||
#ifdef __x86_64__
|
||||
if ( c.nat->ctrlreg[1] )
|
||||
{
|
||||
cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
|
||||
+ cr3_page = mfn_to_page(cr3_pfn);
|
||||
|
||||
- if ( !mfn_valid(cr3_pfn) ||
|
||||
- (paging_mode_refcounts(d)
|
||||
- ? !get_page(mfn_to_page(cr3_pfn), d)
|
||||
- : !get_page_and_type(mfn_to_page(cr3_pfn), d,
|
||||
- PGT_base_page_table)) )
|
||||
+ if ( !mfn_valid(cr3_pfn) || !get_page(cr3_page, d) )
|
||||
{
|
||||
- cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
- v->arch.guest_table = pagetable_null();
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(cr3_pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(cr3_pfn));
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
+ cr3_page = NULL;
|
||||
+ rc = -EINVAL;
|
||||
+ }
|
||||
+ else if ( !paging_mode_refcounts(d) )
|
||||
+ {
|
||||
+ rc = get_page_type_preemptible(cr3_page, PGT_root_page_table);
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ v->arch.old_guest_table =
|
||||
+ pagetable_get_page(v->arch.guest_table);
|
||||
+ v->arch.guest_table = pagetable_null();
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
|
||||
+ if ( !rc )
|
||||
+ v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
|
||||
}
|
||||
else if ( !(flags & VGCF_in_kernel) )
|
||||
{
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
+ cr3_page = NULL;
|
||||
+ rc = -EINVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
l4_pgentry_t *l4tab;
|
||||
|
||||
- cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
|
||||
-
|
||||
- if ( !mfn_valid(cr3_pfn) ||
|
||||
- (paging_mode_refcounts(d)
|
||||
- ? !get_page(mfn_to_page(cr3_pfn), d)
|
||||
- : !get_page_and_type(mfn_to_page(cr3_pfn), d,
|
||||
- PGT_l3_page_table)) )
|
||||
- {
|
||||
- destroy_gdt(v);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
|
||||
*l4tab = l4e_from_pfn(
|
||||
cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
|
||||
#endif
|
||||
}
|
||||
+ if ( rc )
|
||||
+ {
|
||||
+ if ( cr3_page )
|
||||
+ put_page(cr3_page);
|
||||
+ destroy_gdt(v);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ clear_bit(_VPF_in_reset, &v->pause_flags);
|
||||
|
||||
if ( v->vcpu_id == 0 )
|
||||
update_domain_wallclock_time(d);
|
||||
@@ -904,17 +934,16 @@ int arch_set_info_guest(
|
||||
#undef c
|
||||
}
|
||||
|
||||
-void arch_vcpu_reset(struct vcpu *v)
|
||||
+int arch_vcpu_reset(struct vcpu *v)
|
||||
{
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
{
|
||||
destroy_gdt(v);
|
||||
- vcpu_destroy_pagetables(v);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- vcpu_end_shutdown_deferral(v);
|
||||
+ return vcpu_destroy_pagetables(v);
|
||||
}
|
||||
+
|
||||
+ vcpu_end_shutdown_deferral(v);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1917,63 +1946,6 @@ static int relinquish_memory(
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void vcpu_destroy_pagetables(struct vcpu *v)
|
||||
-{
|
||||
- struct domain *d = v->domain;
|
||||
- unsigned long pfn;
|
||||
-
|
||||
-#ifdef __x86_64__
|
||||
- if ( is_pv_32on64_vcpu(v) )
|
||||
- {
|
||||
- pfn = l4e_get_pfn(*(l4_pgentry_t *)
|
||||
- __va(pagetable_get_paddr(v->arch.guest_table)));
|
||||
-
|
||||
- if ( pfn != 0 )
|
||||
- {
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(pfn));
|
||||
- }
|
||||
-
|
||||
- l4e_write(
|
||||
- (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
|
||||
- l4e_empty());
|
||||
-
|
||||
- v->arch.cr3 = 0;
|
||||
- return;
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- pfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
- if ( pfn != 0 )
|
||||
- {
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(pfn));
|
||||
- v->arch.guest_table = pagetable_null();
|
||||
- }
|
||||
-
|
||||
-#ifdef __x86_64__
|
||||
- /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
|
||||
- pfn = pagetable_get_pfn(v->arch.guest_table_user);
|
||||
- if ( pfn != 0 )
|
||||
- {
|
||||
- if ( !is_pv_32bit_vcpu(v) )
|
||||
- {
|
||||
- if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(pfn));
|
||||
- else
|
||||
- put_page_and_type(mfn_to_page(pfn));
|
||||
- }
|
||||
- v->arch.guest_table_user = pagetable_null();
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- v->arch.cr3 = 0;
|
||||
-}
|
||||
-
|
||||
int domain_relinquish_resources(struct domain *d)
|
||||
{
|
||||
int ret;
|
||||
@@ -1992,7 +1964,9 @@ int domain_relinquish_resources(struct d
|
||||
for_each_vcpu ( d, v )
|
||||
{
|
||||
/* Drop the in-use references to page-table bases. */
|
||||
- vcpu_destroy_pagetables(v);
|
||||
+ ret = vcpu_destroy_pagetables(v);
|
||||
+ if ( ret )
|
||||
+ return ret;
|
||||
|
||||
/*
|
||||
* Relinquish GDT mappings. No need for explicit unmapping of the
|
||||
@@ -1,19 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_12,v 1.1 2013/05/03 16:48:37 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/hvm/vlapic.c.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/arch/x86/hvm/vlapic.c
|
||||
@@ -252,10 +252,13 @@ static void vlapic_init_sipi_action(unsi
|
||||
{
|
||||
case APIC_DM_INIT: {
|
||||
bool_t fpu_initialised;
|
||||
+ int rc;
|
||||
+
|
||||
domain_lock(target->domain);
|
||||
/* Reset necessary VCPU state. This does not include FPU state. */
|
||||
fpu_initialised = target->fpu_initialised;
|
||||
- vcpu_reset(target);
|
||||
+ rc = vcpu_reset(target);
|
||||
+ ASSERT(!rc);
|
||||
target->fpu_initialised = fpu_initialised;
|
||||
vlapic_reset(vcpu_vlapic(target));
|
||||
domain_unlock(target->domain);
|
||||
@@ -1,17 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_13,v 1.1 2013/05/03 16:48:37 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/hvm/hvm.c.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/arch/x86/hvm/hvm.c
|
||||
@@ -3083,8 +3083,11 @@ static void hvm_s3_suspend(struct domain
|
||||
|
||||
for_each_vcpu ( d, v )
|
||||
{
|
||||
+ int rc;
|
||||
+
|
||||
vlapic_reset(vcpu_vlapic(v));
|
||||
- vcpu_reset(v);
|
||||
+ rc = vcpu_reset(v);
|
||||
+ ASSERT(!rc);
|
||||
}
|
||||
|
||||
vpic_reset(d);
|
||||
@@ -1,14 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_2,v 1.1 2013/05/03 16:48:37 drochner Exp $
|
||||
|
||||
--- xen/include/xen/sched.h.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/include/xen/sched.h
|
||||
@@ -597,6 +597,9 @@ extern struct domain *domain_list;
|
||||
/* VCPU is blocked on memory-event ring. */
|
||||
#define _VPF_mem_event 4
|
||||
#define VPF_mem_event (1UL<<_VPF_mem_event)
|
||||
+ /* VCPU is being reset. */
|
||||
+#define _VPF_in_reset 7
|
||||
+#define VPF_in_reset (1UL<<_VPF_in_reset)
|
||||
|
||||
static inline int vcpu_runnable(struct vcpu *v)
|
||||
{
|
||||
@@ -1,12 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_3,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/include/asm-x86/domain.h.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/include/asm-x86/domain.h
|
||||
@@ -405,6 +405,7 @@ struct arch_vcpu
|
||||
pagetable_t guest_table_user; /* (MFN) x86/64 user-space pagetable */
|
||||
#endif
|
||||
pagetable_t guest_table; /* (MFN) guest notion of cr3 */
|
||||
+ struct page_info *old_guest_table; /* partially destructed pagetable */
|
||||
/* guest_table holds a ref to the page, and also a type-count unless
|
||||
* shadow refcounts are in use */
|
||||
pagetable_t shadow_table[4]; /* (MFN) shadow(s) of guest */
|
||||
@@ -1,12 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_4,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/include/asm-x86/mm.h.orig 2013-05-03 13:46:46.000000000 +0000
|
||||
+++ xen/include/asm-x86/mm.h
|
||||
@@ -555,6 +555,7 @@ void audit_domains(void);
|
||||
int new_guest_cr3(unsigned long pfn);
|
||||
void make_cr3(struct vcpu *v, unsigned long mfn);
|
||||
void update_cr3(struct vcpu *v);
|
||||
+int vcpu_destroy_pagetables(struct vcpu *);
|
||||
void propagate_page_fault(unsigned long addr, u16 error_code);
|
||||
void *do_page_walk(struct vcpu *v, unsigned long addr);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_5,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/common/compat/domain.c.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/common/compat/domain.c
|
||||
@@ -52,6 +52,10 @@ int compat_vcpu_op(int cmd, int vcpuid,
|
||||
rc = boot_vcpu(d, vcpuid, cmp_ctxt);
|
||||
domain_unlock(d);
|
||||
|
||||
+ if ( rc == -EAGAIN )
|
||||
+ rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
|
||||
+ cmd, vcpuid, arg);
|
||||
+
|
||||
xfree(cmp_ctxt);
|
||||
break;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_6,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/common/domctl.c.orig 2013-05-03 13:37:03.000000000 +0000
|
||||
+++ xen/common/domctl.c
|
||||
@@ -286,8 +286,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
|
||||
|
||||
if ( guest_handle_is_null(op->u.vcpucontext.ctxt) )
|
||||
{
|
||||
- vcpu_reset(v);
|
||||
- ret = 0;
|
||||
+ ret = vcpu_reset(v);
|
||||
+ if ( ret == -EAGAIN )
|
||||
+ ret = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_domctl, "h", u_domctl);
|
||||
goto svc_out;
|
||||
}
|
||||
|
||||
@@ -316,6 +318,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
|
||||
domain_pause(d);
|
||||
ret = arch_set_info_guest(v, c);
|
||||
domain_unpause(d);
|
||||
+
|
||||
+ if ( ret == -EAGAIN )
|
||||
+ ret = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_domctl, "h", u_domctl);
|
||||
}
|
||||
|
||||
svc_out:
|
||||
@@ -1,51 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_7,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/common/domain.c.orig 2013-05-03 13:28:00.000000000 +0000
|
||||
+++ xen/common/domain.c
|
||||
@@ -770,14 +770,18 @@ int boot_vcpu(struct domain *d, int vcpu
|
||||
return arch_set_info_guest(v, ctxt);
|
||||
}
|
||||
|
||||
-void vcpu_reset(struct vcpu *v)
|
||||
+int vcpu_reset(struct vcpu *v)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
+ int rc;
|
||||
|
||||
vcpu_pause(v);
|
||||
domain_lock(d);
|
||||
|
||||
- arch_vcpu_reset(v);
|
||||
+ set_bit(_VPF_in_reset, &v->pause_flags);
|
||||
+ rc = arch_vcpu_reset(v);
|
||||
+ if ( rc )
|
||||
+ goto out_unlock;
|
||||
|
||||
set_bit(_VPF_down, &v->pause_flags);
|
||||
|
||||
@@ -793,9 +797,13 @@ void vcpu_reset(struct vcpu *v)
|
||||
#endif
|
||||
cpus_clear(v->cpu_affinity_tmp);
|
||||
clear_bit(_VPF_blocked, &v->pause_flags);
|
||||
+ clear_bit(_VPF_in_reset, &v->pause_flags);
|
||||
|
||||
+ out_unlock:
|
||||
domain_unlock(v->domain);
|
||||
vcpu_unpause(v);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -834,6 +842,11 @@ long do_vcpu_op(int cmd, int vcpuid, XEN
|
||||
domain_unlock(d);
|
||||
|
||||
xfree(ctxt);
|
||||
+
|
||||
+ if ( rc == -EAGAIN )
|
||||
+ rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih",
|
||||
+ cmd, vcpuid, arg);
|
||||
+
|
||||
break;
|
||||
|
||||
case VCPUOP_up:
|
||||
@@ -1,48 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_8,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/x86_64/compat/mm.c.orig 2013-05-03 13:37:44.000000000 +0000
|
||||
+++ xen/arch/x86/x86_64/compat/mm.c
|
||||
@@ -222,6 +222,13 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
|
||||
int rc = 0;
|
||||
XEN_GUEST_HANDLE(mmuext_op_t) nat_ops;
|
||||
|
||||
+ if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
|
||||
+ likely(guest_handle_is_null(cmp_uops)) )
|
||||
+ {
|
||||
+ set_xen_guest_handle(nat_ops, NULL);
|
||||
+ return do_mmuext_op(nat_ops, count, pdone, foreigndom);
|
||||
+ }
|
||||
+
|
||||
preempt_mask = count & MMU_UPDATE_PREEMPTED;
|
||||
count ^= preempt_mask;
|
||||
|
||||
@@ -319,17 +326,23 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
|
||||
: mcs->call.args[1];
|
||||
unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED;
|
||||
|
||||
- BUG_ON(left == arg1);
|
||||
+ BUG_ON(left == arg1 && left != i);
|
||||
BUG_ON(left > count);
|
||||
guest_handle_add_offset(nat_ops, i - left);
|
||||
guest_handle_subtract_offset(cmp_uops, left);
|
||||
left = 1;
|
||||
- BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
|
||||
- BUG_ON(left != arg1);
|
||||
- if (!test_bit(_MCSF_in_multicall, &mcs->flags))
|
||||
- regs->_ecx += count - i;
|
||||
+ if ( arg1 != MMU_UPDATE_PREEMPTED )
|
||||
+ {
|
||||
+ BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops,
|
||||
+ cmp_uops));
|
||||
+ if ( !test_bit(_MCSF_in_multicall, &mcs->flags) )
|
||||
+ regs->_ecx += count - i;
|
||||
+ else
|
||||
+ mcs->compat_call.args[1] += count - i;
|
||||
+ }
|
||||
else
|
||||
- mcs->compat_call.args[1] += count - i;
|
||||
+ BUG_ON(hypercall_xlat_continuation(&left, 0));
|
||||
+ BUG_ON(left != arg1);
|
||||
}
|
||||
else
|
||||
BUG_ON(err > 0);
|
||||
@@ -1,593 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1918_9,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/mm.c.orig 2013-05-03 13:38:09.000000000 +0000
|
||||
+++ xen/arch/x86/mm.c
|
||||
@@ -1183,7 +1183,16 @@ static int put_page_from_l3e(l3_pgentry_
|
||||
#endif
|
||||
|
||||
if ( unlikely(partial > 0) )
|
||||
+ {
|
||||
+ ASSERT(preemptible >= 0);
|
||||
return __put_page_type(l3e_get_page(l3e), preemptible);
|
||||
+ }
|
||||
+
|
||||
+ if ( preemptible < 0 )
|
||||
+ {
|
||||
+ current->arch.old_guest_table = l3e_get_page(l3e);
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
return put_page_and_type_preemptible(l3e_get_page(l3e), preemptible);
|
||||
}
|
||||
@@ -1196,7 +1205,17 @@ static int put_page_from_l4e(l4_pgentry_
|
||||
(l4e_get_pfn(l4e) != pfn) )
|
||||
{
|
||||
if ( unlikely(partial > 0) )
|
||||
+ {
|
||||
+ ASSERT(preemptible >= 0);
|
||||
return __put_page_type(l4e_get_page(l4e), preemptible);
|
||||
+ }
|
||||
+
|
||||
+ if ( preemptible < 0 )
|
||||
+ {
|
||||
+ current->arch.old_guest_table = l4e_get_page(l4e);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
return put_page_and_type_preemptible(l4e_get_page(l4e), preemptible);
|
||||
}
|
||||
return 1;
|
||||
@@ -1486,12 +1505,17 @@ static int alloc_l3_table(struct page_in
|
||||
if ( rc < 0 && rc != -EAGAIN && rc != -EINTR )
|
||||
{
|
||||
MEM_LOG("Failure in alloc_l3_table: entry %d", i);
|
||||
+ if ( i )
|
||||
+ {
|
||||
+ page->nr_validated_ptes = i;
|
||||
+ page->partial_pte = 0;
|
||||
+ current->arch.old_guest_table = page;
|
||||
+ }
|
||||
while ( i-- > 0 )
|
||||
{
|
||||
if ( !is_guest_l3_slot(i) )
|
||||
continue;
|
||||
unadjust_guest_l3e(pl3e[i], d);
|
||||
- put_page_from_l3e(pl3e[i], pfn, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1521,22 +1545,24 @@ static int alloc_l4_table(struct page_in
|
||||
page->nr_validated_ptes = i;
|
||||
page->partial_pte = partial ?: 1;
|
||||
}
|
||||
- else if ( rc == -EINTR )
|
||||
+ else if ( rc < 0 )
|
||||
{
|
||||
+ if ( rc != -EINTR )
|
||||
+ MEM_LOG("Failure in alloc_l4_table: entry %d", i);
|
||||
if ( i )
|
||||
{
|
||||
page->nr_validated_ptes = i;
|
||||
page->partial_pte = 0;
|
||||
- rc = -EAGAIN;
|
||||
+ if ( rc == -EINTR )
|
||||
+ rc = -EAGAIN;
|
||||
+ else
|
||||
+ {
|
||||
+ if ( current->arch.old_guest_table )
|
||||
+ page->nr_validated_ptes++;
|
||||
+ current->arch.old_guest_table = page;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
- else if ( rc < 0 )
|
||||
- {
|
||||
- MEM_LOG("Failure in alloc_l4_table: entry %d", i);
|
||||
- while ( i-- > 0 )
|
||||
- if ( is_guest_l4_slot(d, i) )
|
||||
- put_page_from_l4e(pl4e[i], pfn, 0, 0);
|
||||
- }
|
||||
if ( rc < 0 )
|
||||
return rc;
|
||||
|
||||
@@ -1966,7 +1992,7 @@ static int mod_l3_entry(l3_pgentry_t *pl
|
||||
pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e);
|
||||
}
|
||||
|
||||
- put_page_from_l3e(ol3e, pfn, 0, 0);
|
||||
+ put_page_from_l3e(ol3e, pfn, 0, -preemptible);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2029,7 +2055,7 @@ static int mod_l4_entry(l4_pgentry_t *pl
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
- put_page_from_l4e(ol4e, pfn, 0, 0);
|
||||
+ put_page_from_l4e(ol4e, pfn, 0, -preemptible);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -2187,7 +2213,15 @@ static int alloc_page_type(struct page_i
|
||||
PRtype_info ": caf=%08lx taf=%" PRtype_info,
|
||||
page_to_mfn(page), get_gpfn_from_mfn(page_to_mfn(page)),
|
||||
type, page->count_info, page->u.inuse.type_info);
|
||||
- page->u.inuse.type_info = 0;
|
||||
+ if ( page != current->arch.old_guest_table )
|
||||
+ page->u.inuse.type_info = 0;
|
||||
+ else
|
||||
+ {
|
||||
+ ASSERT((page->u.inuse.type_info &
|
||||
+ (PGT_count_mask | PGT_validated)) == 1);
|
||||
+ get_page_light(page);
|
||||
+ page->u.inuse.type_info |= PGT_partial;
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2725,49 +2759,150 @@ static void put_superpage(unsigned long
|
||||
|
||||
#endif
|
||||
|
||||
+static int put_old_guest_table(struct vcpu *v)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ if ( !v->arch.old_guest_table )
|
||||
+ return 0;
|
||||
+
|
||||
+ switch ( rc = put_page_and_type_preemptible(v->arch.old_guest_table, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
+
|
||||
+ v->arch.old_guest_table = NULL;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int vcpu_destroy_pagetables(struct vcpu *v)
|
||||
+{
|
||||
+ unsigned long mfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
+ struct page_info *page;
|
||||
+ int rc = put_old_guest_table(v);
|
||||
+
|
||||
+ if ( rc )
|
||||
+ return rc;
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ if ( is_pv_32on64_vcpu(v) )
|
||||
+ mfn = l4e_get_pfn(*(l4_pgentry_t *)mfn_to_virt(mfn));
|
||||
+#endif
|
||||
+
|
||||
+ if ( mfn )
|
||||
+ {
|
||||
+ page = mfn_to_page(mfn);
|
||||
+ if ( paging_mode_refcounts(v->domain) )
|
||||
+ put_page(page);
|
||||
+ else
|
||||
+ rc = put_page_and_type_preemptible(page, 1);
|
||||
+ }
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ if ( is_pv_32on64_vcpu(v) )
|
||||
+ {
|
||||
+ if ( !rc )
|
||||
+ l4e_write(
|
||||
+ (l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)),
|
||||
+ l4e_empty());
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ if ( !rc )
|
||||
+ {
|
||||
+ v->arch.guest_table = pagetable_null();
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ /* Drop ref to guest_table_user (from MMUEXT_NEW_USER_BASEPTR) */
|
||||
+ mfn = pagetable_get_pfn(v->arch.guest_table_user);
|
||||
+ if ( mfn )
|
||||
+ {
|
||||
+ page = mfn_to_page(mfn);
|
||||
+ if ( paging_mode_refcounts(v->domain) )
|
||||
+ put_page(page);
|
||||
+ else
|
||||
+ rc = put_page_and_type_preemptible(page, 1);
|
||||
+ }
|
||||
+ if ( !rc )
|
||||
+ v->arch.guest_table_user = pagetable_null();
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ v->arch.cr3 = 0;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
|
||||
int new_guest_cr3(unsigned long mfn)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
struct domain *d = curr->domain;
|
||||
- int okay;
|
||||
+ int rc;
|
||||
unsigned long old_base_mfn;
|
||||
|
||||
#ifdef __x86_64__
|
||||
if ( is_pv_32on64_domain(d) )
|
||||
{
|
||||
- okay = paging_mode_refcounts(d)
|
||||
- ? 0 /* Old code was broken, but what should it be? */
|
||||
- : mod_l4_entry(
|
||||
+ rc = paging_mode_refcounts(d)
|
||||
+ ? -EINVAL /* Old code was broken, but what should it be? */
|
||||
+ : mod_l4_entry(
|
||||
__va(pagetable_get_paddr(curr->arch.guest_table)),
|
||||
l4e_from_pfn(
|
||||
mfn,
|
||||
(_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)),
|
||||
- pagetable_get_pfn(curr->arch.guest_table), 0, 0, curr) == 0;
|
||||
- if ( unlikely(!okay) )
|
||||
+ pagetable_get_pfn(curr->arch.guest_table), 0, 1, curr);
|
||||
+ switch ( rc )
|
||||
{
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ return -EAGAIN;
|
||||
+ default:
|
||||
MEM_LOG("Error while installing new compat baseptr %lx", mfn);
|
||||
- return 0;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
invalidate_shadow_ldt(curr, 0);
|
||||
write_ptbase(curr);
|
||||
|
||||
- return 1;
|
||||
+ return 0;
|
||||
}
|
||||
#endif
|
||||
- okay = paging_mode_refcounts(d)
|
||||
- ? get_page_from_pagenr(mfn, d)
|
||||
- : !get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d, 0, 0);
|
||||
- if ( unlikely(!okay) )
|
||||
+ rc = put_old_guest_table(curr);
|
||||
+ if ( unlikely(rc) )
|
||||
+ return rc;
|
||||
+
|
||||
+ old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
|
||||
+ /*
|
||||
+ * This is particularly important when getting restarted after the
|
||||
+ * previous attempt got preempted in the put-old-MFN phase.
|
||||
+ */
|
||||
+ if ( old_base_mfn == mfn )
|
||||
{
|
||||
- MEM_LOG("Error while installing new baseptr %lx", mfn);
|
||||
+ write_ptbase(curr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
- invalidate_shadow_ldt(curr, 0);
|
||||
+ rc = paging_mode_refcounts(d)
|
||||
+ ? (get_page_from_pagenr(mfn, d) ? 0 : -EINVAL)
|
||||
+ : get_page_and_type_from_pagenr(mfn, PGT_root_page_table, d, 0, 1);
|
||||
+ switch ( rc )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ return -EAGAIN;
|
||||
+ default:
|
||||
+ MEM_LOG("Error while installing new baseptr %lx", mfn);
|
||||
+ return rc;
|
||||
+ }
|
||||
|
||||
- old_base_mfn = pagetable_get_pfn(curr->arch.guest_table);
|
||||
+ invalidate_shadow_ldt(curr, 0);
|
||||
|
||||
curr->arch.guest_table = pagetable_from_pfn(mfn);
|
||||
update_cr3(curr);
|
||||
@@ -2776,13 +2911,25 @@ int new_guest_cr3(unsigned long mfn)
|
||||
|
||||
if ( likely(old_base_mfn != 0) )
|
||||
{
|
||||
+ struct page_info *page = mfn_to_page(old_base_mfn);
|
||||
+
|
||||
if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(old_base_mfn));
|
||||
+ put_page(page);
|
||||
else
|
||||
- put_page_and_type(mfn_to_page(old_base_mfn));
|
||||
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG_ON(rc);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static struct domain *get_pg_owner(domid_t domid)
|
||||
@@ -2911,12 +3058,29 @@ long do_mmuext_op(
|
||||
unsigned int foreigndom)
|
||||
{
|
||||
struct mmuext_op op;
|
||||
- int rc = 0, i = 0, okay;
|
||||
unsigned long type;
|
||||
- unsigned int done = 0;
|
||||
+ unsigned int i = 0, done = 0;
|
||||
struct vcpu *curr = current;
|
||||
struct domain *d = curr->domain;
|
||||
struct domain *pg_owner;
|
||||
+ int okay, rc = put_old_guest_table(curr);
|
||||
+
|
||||
+ if ( unlikely(rc) )
|
||||
+ {
|
||||
+ if ( likely(rc == -EAGAIN) )
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmuext_op, "hihi", uops, count, pdone,
|
||||
+ foreigndom);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
|
||||
+ likely(guest_handle_is_null(uops)) )
|
||||
+ {
|
||||
+ /* See the curr->arch.old_guest_table related
|
||||
+ * hypercall_create_continuation() below. */
|
||||
+ return (int)foreigndom;
|
||||
+ }
|
||||
|
||||
if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
|
||||
{
|
||||
@@ -2941,7 +3105,7 @@ long do_mmuext_op(
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
- if ( hypercall_preempt_check() )
|
||||
+ if ( curr->arch.old_guest_table || hypercall_preempt_check() )
|
||||
{
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
@@ -3001,21 +3165,17 @@ long do_mmuext_op(
|
||||
page = mfn_to_page(mfn);
|
||||
|
||||
if ( (rc = xsm_memory_pin_page(d, page)) != 0 )
|
||||
- {
|
||||
- put_page_and_type(page);
|
||||
okay = 0;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if ( unlikely(test_and_set_bit(_PGT_pinned,
|
||||
- &page->u.inuse.type_info)) )
|
||||
+ else if ( unlikely(test_and_set_bit(_PGT_pinned,
|
||||
+ &page->u.inuse.type_info)) )
|
||||
{
|
||||
MEM_LOG("Mfn %lx already pinned", mfn);
|
||||
- put_page_and_type(page);
|
||||
okay = 0;
|
||||
- break;
|
||||
}
|
||||
|
||||
+ if ( unlikely(!okay) )
|
||||
+ goto pin_drop;
|
||||
+
|
||||
/* A page is dirtied when its pin status is set. */
|
||||
paging_mark_dirty(pg_owner, mfn);
|
||||
|
||||
@@ -3029,7 +3189,13 @@ long do_mmuext_op(
|
||||
&page->u.inuse.type_info));
|
||||
spin_unlock(&pg_owner->page_alloc_lock);
|
||||
if ( drop_ref )
|
||||
- put_page_and_type(page);
|
||||
+ {
|
||||
+ pin_drop:
|
||||
+ if ( type == PGT_l1_page_table )
|
||||
+ put_page_and_type(page);
|
||||
+ else
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ }
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -3059,7 +3225,17 @@ long do_mmuext_op(
|
||||
break;
|
||||
}
|
||||
|
||||
- put_page_and_type(page);
|
||||
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ case -EAGAIN:
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ rc = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG_ON(rc);
|
||||
+ break;
|
||||
+ }
|
||||
put_page(page);
|
||||
|
||||
/* A page is dirtied when its pin status is cleared. */
|
||||
@@ -3069,7 +3245,8 @@ long do_mmuext_op(
|
||||
}
|
||||
|
||||
case MMUEXT_NEW_BASEPTR:
|
||||
- okay = new_guest_cr3(gmfn_to_mfn(d, op.arg1.mfn));
|
||||
+ rc = new_guest_cr3(gmfn_to_mfn(d, op.arg1.mfn));
|
||||
+ okay = !rc;
|
||||
break;
|
||||
|
||||
#ifdef __x86_64__
|
||||
@@ -3077,29 +3254,55 @@ long do_mmuext_op(
|
||||
unsigned long old_mfn, mfn;
|
||||
|
||||
mfn = gmfn_to_mfn(d, op.arg1.mfn);
|
||||
+ old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
|
||||
+ /*
|
||||
+ * This is particularly important when getting restarted after the
|
||||
+ * previous attempt got preempted in the put-old-MFN phase.
|
||||
+ */
|
||||
+ if ( old_mfn == mfn )
|
||||
+ break;
|
||||
+
|
||||
if ( mfn != 0 )
|
||||
{
|
||||
if ( paging_mode_refcounts(d) )
|
||||
okay = get_page_from_pagenr(mfn, d);
|
||||
else
|
||||
- okay = !get_page_and_type_from_pagenr(
|
||||
- mfn, PGT_root_page_table, d, 0, 0);
|
||||
+ {
|
||||
+ rc = get_page_and_type_from_pagenr(
|
||||
+ mfn, PGT_root_page_table, d, 0, 1);
|
||||
+ okay = !rc;
|
||||
+ }
|
||||
if ( unlikely(!okay) )
|
||||
{
|
||||
- MEM_LOG("Error while installing new mfn %lx", mfn);
|
||||
+ if ( rc == -EINTR )
|
||||
+ rc = -EAGAIN;
|
||||
+ else if ( rc != -EAGAIN )
|
||||
+ MEM_LOG("Error while installing new mfn %lx", mfn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
|
||||
curr->arch.guest_table_user = pagetable_from_pfn(mfn);
|
||||
|
||||
if ( old_mfn != 0 )
|
||||
{
|
||||
+ struct page_info *page = mfn_to_page(old_mfn);
|
||||
+
|
||||
if ( paging_mode_refcounts(d) )
|
||||
- put_page(mfn_to_page(old_mfn));
|
||||
+ put_page(page);
|
||||
else
|
||||
- put_page_and_type(mfn_to_page(old_mfn));
|
||||
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
|
||||
+ {
|
||||
+ case -EINTR:
|
||||
+ rc = -EAGAIN;
|
||||
+ case -EAGAIN:
|
||||
+ curr->arch.old_guest_table = page;
|
||||
+ okay = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ BUG_ON(rc);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -3338,9 +3541,27 @@ long do_mmuext_op(
|
||||
}
|
||||
|
||||
if ( rc == -EAGAIN )
|
||||
+ {
|
||||
+ ASSERT(i < count);
|
||||
rc = hypercall_create_continuation(
|
||||
__HYPERVISOR_mmuext_op, "hihi",
|
||||
uops, (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
|
||||
+ }
|
||||
+ else if ( curr->arch.old_guest_table )
|
||||
+ {
|
||||
+ XEN_GUEST_HANDLE(void) null;
|
||||
+
|
||||
+ ASSERT(rc || i == count);
|
||||
+ set_xen_guest_handle(null, NULL);
|
||||
+ /*
|
||||
+ * In order to have a way to communicate the final return value to
|
||||
+ * our continuation, we pass this in place of "foreigndom", building
|
||||
+ * on the fact that this argument isn't needed anymore.
|
||||
+ */
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmuext_op, "hihi", null,
|
||||
+ MMU_UPDATE_PREEMPTED, null, rc);
|
||||
+ }
|
||||
|
||||
put_pg_owner(pg_owner);
|
||||
|
||||
@@ -3367,11 +3588,28 @@ long do_mmu_update(
|
||||
void *va;
|
||||
unsigned long gpfn, gmfn, mfn;
|
||||
struct page_info *page;
|
||||
- int rc = 0, okay = 1, i = 0;
|
||||
- unsigned int cmd, done = 0, pt_dom;
|
||||
- struct vcpu *v = current;
|
||||
+ unsigned int cmd, i = 0, done = 0, pt_dom;
|
||||
+ struct vcpu *curr = current, *v = curr;
|
||||
struct domain *d = v->domain, *pt_owner = d, *pg_owner;
|
||||
struct domain_mmap_cache mapcache;
|
||||
+ int rc = put_old_guest_table(curr), okay = 1;
|
||||
+
|
||||
+ if ( unlikely(rc) )
|
||||
+ {
|
||||
+ if ( likely(rc == -EAGAIN) )
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmu_update, "hihi", ureqs, count, pdone,
|
||||
+ foreigndom);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if ( unlikely(count == MMU_UPDATE_PREEMPTED) &&
|
||||
+ likely(guest_handle_is_null(ureqs)) )
|
||||
+ {
|
||||
+ /* See the curr->arch.old_guest_table related
|
||||
+ * hypercall_create_continuation() below. */
|
||||
+ return (int)foreigndom;
|
||||
+ }
|
||||
|
||||
if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
|
||||
{
|
||||
@@ -3420,7 +3658,7 @@ long do_mmu_update(
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
- if ( hypercall_preempt_check() )
|
||||
+ if ( curr->arch.old_guest_table || hypercall_preempt_check() )
|
||||
{
|
||||
rc = -EAGAIN;
|
||||
break;
|
||||
@@ -3685,9 +3923,27 @@ long do_mmu_update(
|
||||
}
|
||||
|
||||
if ( rc == -EAGAIN )
|
||||
+ {
|
||||
+ ASSERT(i < count);
|
||||
rc = hypercall_create_continuation(
|
||||
__HYPERVISOR_mmu_update, "hihi",
|
||||
ureqs, (count - i) | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
|
||||
+ }
|
||||
+ else if ( curr->arch.old_guest_table )
|
||||
+ {
|
||||
+ XEN_GUEST_HANDLE(void) null;
|
||||
+
|
||||
+ ASSERT(rc || i == count);
|
||||
+ set_xen_guest_handle(null, NULL);
|
||||
+ /*
|
||||
+ * In order to have a way to communicate the final return value to
|
||||
+ * our continuation, we pass this in place of "foreigndom", building
|
||||
+ * on the fact that this argument isn't needed anymore.
|
||||
+ */
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmu_update, "hihi", null,
|
||||
+ MMU_UPDATE_PREEMPTED, null, rc);
|
||||
+ }
|
||||
|
||||
put_pg_owner(pg_owner);
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
$NetBSD: patch-CVE-2013-1952,v 1.1 2013/05/03 16:48:38 drochner Exp $
|
||||
|
||||
see http://lists.xen.org/archives/html/xen-announce/2013-05/msg00001.html
|
||||
|
||||
--- xen/drivers/passthrough/vtd/intremap.c.orig 2013-04-23 16:44:20.000000000 +0000
|
||||
+++ xen/drivers/passthrough/vtd/intremap.c
|
||||
@@ -477,16 +477,15 @@ static void set_msi_source_id(struct pci
|
||||
type = pdev_type(bus, devfn);
|
||||
switch ( type )
|
||||
{
|
||||
+ case DEV_TYPE_PCIe_ENDPOINT:
|
||||
case DEV_TYPE_PCIe_BRIDGE:
|
||||
case DEV_TYPE_PCIe2PCI_BRIDGE:
|
||||
- case DEV_TYPE_LEGACY_PCI_BRIDGE:
|
||||
- break;
|
||||
-
|
||||
- case DEV_TYPE_PCIe_ENDPOINT:
|
||||
set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16, PCI_BDF2(bus, devfn));
|
||||
break;
|
||||
|
||||
case DEV_TYPE_PCI:
|
||||
+ case DEV_TYPE_LEGACY_PCI_BRIDGE:
|
||||
+ /* case DEV_TYPE_PCI2PCIe_BRIDGE: */
|
||||
ret = find_upstream_bridge(&bus, &devfn, &secbus);
|
||||
if ( ret == 0 ) /* integrated PCI device */
|
||||
{
|
||||
@@ -498,10 +497,15 @@ static void set_msi_source_id(struct pci
|
||||
if ( pdev_type(bus, devfn) == DEV_TYPE_PCIe2PCI_BRIDGE )
|
||||
set_ire_sid(ire, SVT_VERIFY_BUS, SQ_ALL_16,
|
||||
(bus << 8) | pdev->bus);
|
||||
- else if ( pdev_type(bus, devfn) == DEV_TYPE_LEGACY_PCI_BRIDGE )
|
||||
+ else
|
||||
set_ire_sid(ire, SVT_VERIFY_SID_SQ, SQ_ALL_16,
|
||||
PCI_BDF2(bus, devfn));
|
||||
}
|
||||
+ else
|
||||
+ dprintk(XENLOG_WARNING VTDPREFIX,
|
||||
+ "d%d: no upstream bridge for %02x:%02x.%u\n",
|
||||
+ pdev->domain->domain_id,
|
||||
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||
break;
|
||||
|
||||
default:
|
||||
80
sysutils/xenkernel41/patches/patch-CVE-2013-4355_1
Normal file
80
sysutils/xenkernel41/patches/patch-CVE-2013-4355_1
Normal file
@@ -0,0 +1,80 @@
|
||||
$NetBSD: patch-CVE-2013-4355_1,v 1.3 2014/03/28 16:07:08 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-09/msg03160.html
|
||||
also fixes
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-11/msg03827.html
|
||||
(CVE-2013-4554)
|
||||
also fixes
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2014-03/msg03177.html
|
||||
(CVE-2014-2599)
|
||||
|
||||
--- xen/arch/x86/hvm/hvm.c.orig 2014-03-28 15:27:28.000000000 +0000
|
||||
+++ xen/arch/x86/hvm/hvm.c 2014-03-28 15:27:36.000000000 +0000
|
||||
@@ -1961,11 +1961,7 @@
|
||||
|
||||
rc = hvm_copy_from_guest_virt(
|
||||
&tss, prev_tr.base, sizeof(tss), PFEC_page_present);
|
||||
- if ( rc == HVMCOPY_bad_gva_to_gfn )
|
||||
- goto out;
|
||||
- if ( rc == HVMCOPY_gfn_paged_out )
|
||||
- goto out;
|
||||
- if ( rc == HVMCOPY_gfn_shared )
|
||||
+ if ( rc != HVMCOPY_okay )
|
||||
goto out;
|
||||
|
||||
eflags = regs->eflags;
|
||||
@@ -2010,13 +2006,11 @@
|
||||
|
||||
rc = hvm_copy_from_guest_virt(
|
||||
&tss, tr.base, sizeof(tss), PFEC_page_present);
|
||||
- if ( rc == HVMCOPY_bad_gva_to_gfn )
|
||||
- goto out;
|
||||
- if ( rc == HVMCOPY_gfn_paged_out )
|
||||
- goto out;
|
||||
- /* Note: this could be optimised, if the callee functions knew we want RO
|
||||
- * access */
|
||||
- if ( rc == HVMCOPY_gfn_shared )
|
||||
+ /*
|
||||
+ * Note: The HVMCOPY_gfn_shared case could be optimised, if the callee
|
||||
+ * functions knew we want RO access.
|
||||
+ */
|
||||
+ if ( rc != HVMCOPY_okay )
|
||||
goto out;
|
||||
|
||||
|
||||
@@ -2834,7 +2828,7 @@
|
||||
case 4:
|
||||
case 2:
|
||||
hvm_get_segment_register(curr, x86_seg_ss, &sreg);
|
||||
- if ( unlikely(sreg.attr.fields.dpl == 3) )
|
||||
+ if ( unlikely(sreg.attr.fields.dpl) )
|
||||
{
|
||||
default:
|
||||
regs->eax = -EPERM;
|
||||
@@ -3746,7 +3740,7 @@
|
||||
((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) )
|
||||
goto param_fail5;
|
||||
|
||||
- for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
|
||||
+ for ( pfn = a.first_pfn; a.nr; ++pfn )
|
||||
{
|
||||
p2m_type_t t;
|
||||
mfn_t mfn;
|
||||
@@ -3759,6 +3753,17 @@
|
||||
p2m_unlock(p2m);
|
||||
if ( !success )
|
||||
goto param_fail5;
|
||||
+
|
||||
+ /* Check for continuation if it's not the last interation. */
|
||||
+ if ( --a.nr && hypercall_preempt_check() )
|
||||
+ {
|
||||
+ a.first_pfn = pfn + 1;
|
||||
+ if ( copy_to_guest(arg, &a, 1) )
|
||||
+ rc = -EFAULT;
|
||||
+ else
|
||||
+ rc = -EAGAIN;
|
||||
+ goto param_fail5;
|
||||
+ }
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
71
sysutils/xenkernel41/patches/patch-CVE-2013-4355_2
Normal file
71
sysutils/xenkernel41/patches/patch-CVE-2013-4355_2
Normal file
@@ -0,0 +1,71 @@
|
||||
$NetBSD: patch-CVE-2013-4355_2,v 1.1 2013/10/01 14:54:44 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/hvm/intercept.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/hvm/intercept.c 2013-09-30 15:23:07.000000000 +0000
|
||||
@@ -93,17 +93,28 @@ static int hvm_mmio_access(struct vcpu *
|
||||
{
|
||||
for ( i = 0; i < p->count; i++ )
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- ret = hvm_copy_from_guest_phys(&data,
|
||||
- p->data + (sign * i * p->size),
|
||||
- p->size);
|
||||
- if ( (ret == HVMCOPY_gfn_paged_out) ||
|
||||
- (ret == HVMCOPY_gfn_shared) )
|
||||
+ switch ( hvm_copy_from_guest_phys(&data,
|
||||
+ p->data + sign * i * p->size,
|
||||
+ p->size) )
|
||||
{
|
||||
+ case HVMCOPY_okay:
|
||||
+ break;
|
||||
+ case HVMCOPY_gfn_paged_out:
|
||||
+ case HVMCOPY_gfn_shared:
|
||||
rc = X86EMUL_RETRY;
|
||||
break;
|
||||
+ case HVMCOPY_bad_gfn_to_mfn:
|
||||
+ data = ~0;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gva_to_gfn:
|
||||
+ ASSERT(0);
|
||||
+ /* fall through */
|
||||
+ default:
|
||||
+ rc = X86EMUL_UNHANDLEABLE;
|
||||
+ break;
|
||||
}
|
||||
+ if ( rc != X86EMUL_OKAY )
|
||||
+ break;
|
||||
rc = write_handler(v, p->addr + (sign * i * p->size), p->size,
|
||||
data);
|
||||
if ( rc != X86EMUL_OKAY )
|
||||
@@ -171,8 +182,28 @@ static int process_portio_intercept(port
|
||||
for ( i = 0; i < p->count; i++ )
|
||||
{
|
||||
data = 0;
|
||||
- (void)hvm_copy_from_guest_phys(&data, p->data + sign*i*p->size,
|
||||
- p->size);
|
||||
+ switch ( hvm_copy_from_guest_phys(&data,
|
||||
+ p->data + sign * i * p->size,
|
||||
+ p->size) )
|
||||
+ {
|
||||
+ case HVMCOPY_okay:
|
||||
+ break;
|
||||
+ case HVMCOPY_gfn_paged_out:
|
||||
+ case HVMCOPY_gfn_shared:
|
||||
+ rc = X86EMUL_RETRY;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gfn_to_mfn:
|
||||
+ data = ~0;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gva_to_gfn:
|
||||
+ ASSERT(0);
|
||||
+ /* fall through */
|
||||
+ default:
|
||||
+ rc = X86EMUL_UNHANDLEABLE;
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( rc != X86EMUL_OKAY )
|
||||
+ break;
|
||||
rc = action(IOREQ_WRITE, p->addr, p->size, &data);
|
||||
if ( rc != X86EMUL_OKAY )
|
||||
break;
|
||||
36
sysutils/xenkernel41/patches/patch-CVE-2013-4355_3
Normal file
36
sysutils/xenkernel41/patches/patch-CVE-2013-4355_3
Normal file
@@ -0,0 +1,36 @@
|
||||
$NetBSD: patch-CVE-2013-4355_3,v 1.1 2013/10/01 14:54:44 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/hvm/io.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/hvm/io.c 2013-09-30 15:23:07.000000000 +0000
|
||||
@@ -333,14 +333,24 @@ static int dpci_ioport_write(uint32_t mp
|
||||
data = p->data;
|
||||
if ( p->data_is_ptr )
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- ret = hvm_copy_from_guest_phys(&data,
|
||||
- p->data + (sign * i * p->size),
|
||||
- p->size);
|
||||
- if ( (ret == HVMCOPY_gfn_paged_out) &&
|
||||
- (ret == HVMCOPY_gfn_shared) )
|
||||
+ switch ( hvm_copy_from_guest_phys(&data,
|
||||
+ p->data + sign * i * p->size,
|
||||
+ p->size) )
|
||||
+ {
|
||||
+ case HVMCOPY_okay:
|
||||
+ break;
|
||||
+ case HVMCOPY_gfn_paged_out:
|
||||
+ case HVMCOPY_gfn_shared:
|
||||
return X86EMUL_RETRY;
|
||||
+ case HVMCOPY_bad_gfn_to_mfn:
|
||||
+ data = ~0;
|
||||
+ break;
|
||||
+ case HVMCOPY_bad_gva_to_gfn:
|
||||
+ ASSERT(0);
|
||||
+ /* fall through */
|
||||
+ default:
|
||||
+ return X86EMUL_UNHANDLEABLE;
|
||||
+ }
|
||||
}
|
||||
|
||||
switch ( p->size )
|
||||
24
sysutils/xenkernel41/patches/patch-CVE-2013-4355_4
Normal file
24
sysutils/xenkernel41/patches/patch-CVE-2013-4355_4
Normal file
@@ -0,0 +1,24 @@
|
||||
$NetBSD: patch-CVE-2013-4355_4,v 1.1 2013/10/01 14:54:44 drochner Exp $
|
||||
|
||||
--- xen/arch/x86/hvm/vmx/realmode.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/hvm/vmx/realmode.c 2013-09-30 15:23:07.000000000 +0000
|
||||
@@ -38,7 +38,9 @@ static void realmode_deliver_exception(
|
||||
|
||||
again:
|
||||
last_byte = (vector * 4) + 3;
|
||||
- if ( idtr->limit < last_byte )
|
||||
+ if ( idtr->limit < last_byte ||
|
||||
+ hvm_copy_from_guest_phys(&cs_eip, idtr->base + vector * 4, 4) !=
|
||||
+ HVMCOPY_okay )
|
||||
{
|
||||
/* Software interrupt? */
|
||||
if ( insn_len != 0 )
|
||||
@@ -63,8 +65,6 @@ static void realmode_deliver_exception(
|
||||
}
|
||||
}
|
||||
|
||||
- (void)hvm_copy_from_guest_phys(&cs_eip, idtr->base + vector * 4, 4);
|
||||
-
|
||||
frame[0] = regs->eip + insn_len;
|
||||
frame[1] = csr->sel;
|
||||
frame[2] = regs->eflags & ~X86_EFLAGS_RF;
|
||||
20
sysutils/xenkernel41/patches/patch-CVE-2013-4361
Normal file
20
sysutils/xenkernel41/patches/patch-CVE-2013-4361
Normal file
@@ -0,0 +1,20 @@
|
||||
$NetBSD: patch-CVE-2013-4361,v 1.1 2013/10/01 14:54:44 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-09/msg03162.html
|
||||
|
||||
--- xen/arch/x86/x86_emulate/x86_emulate.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/x86_emulate/x86_emulate.c 2013-09-30 15:23:08.000000000 +0000
|
||||
@@ -2975,11 +2975,11 @@ x86_emulate(
|
||||
break;
|
||||
case 4: /* fbld m80dec */
|
||||
ea.bytes = 10;
|
||||
- dst = ea;
|
||||
+ src = ea;
|
||||
if ( (rc = ops->read(src.mem.seg, src.mem.off,
|
||||
&src.val, src.bytes, ctxt)) != 0 )
|
||||
goto done;
|
||||
- emulate_fpu_insn_memdst("fbld", src.val);
|
||||
+ emulate_fpu_insn_memsrc("fbld", src.val);
|
||||
break;
|
||||
case 5: /* fild m64i */
|
||||
ea.bytes = 8;
|
||||
21
sysutils/xenkernel41/patches/patch-CVE-2013-4368
Normal file
21
sysutils/xenkernel41/patches/patch-CVE-2013-4368
Normal file
@@ -0,0 +1,21 @@
|
||||
$NetBSD: patch-CVE-2013-4368,v 1.1 2013/10/22 19:41:58 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-10/msg00812.html
|
||||
|
||||
--- xen/arch/x86/traps.c.orig 2013-09-10 08:42:18.000000000 +0200
|
||||
+++ xen/arch/x86/traps.c 2013-10-22 21:11:24.000000000 +0200
|
||||
@@ -1965,10 +1965,10 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
}
|
||||
}
|
||||
- else
|
||||
- read_descriptor(data_sel, v, regs,
|
||||
- &data_base, &data_limit, &ar,
|
||||
- 0);
|
||||
+ else if ( !read_descriptor(data_sel, v, regs,
|
||||
+ &data_base, &data_limit, &ar, 0) ||
|
||||
+ !(ar & _SEGMENT_S) || !(ar & _SEGMENT_P) )
|
||||
+ goto fail;
|
||||
data_limit = ~0UL;
|
||||
ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P;
|
||||
}
|
||||
80
sysutils/xenkernel41/patches/patch-CVE-2013-4494
Normal file
80
sysutils/xenkernel41/patches/patch-CVE-2013-4494
Normal file
@@ -0,0 +1,80 @@
|
||||
$NetBSD: patch-CVE-2013-4494,v 1.1 2013/11/23 14:04:59 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-11/msg00225.html
|
||||
|
||||
--- xen/common/grant_table.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/common/grant_table.c 2013-11-19 16:46:13.000000000 +0000
|
||||
@@ -1459,6 +1459,8 @@ gnttab_transfer(
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
+ bool_t okay;
|
||||
+
|
||||
if (i && hypercall_preempt_check())
|
||||
return i;
|
||||
|
||||
@@ -1555,16 +1557,18 @@ gnttab_transfer(
|
||||
* pages when it is dying.
|
||||
*/
|
||||
if ( unlikely(e->is_dying) ||
|
||||
- unlikely(e->tot_pages >= e->max_pages) ||
|
||||
- unlikely(!gnttab_prepare_for_transfer(e, d, gop.ref)) )
|
||||
+ unlikely(e->tot_pages >= e->max_pages) )
|
||||
{
|
||||
- if ( !e->is_dying )
|
||||
- gdprintk(XENLOG_INFO, "gnttab_transfer: "
|
||||
- "Transferee has no reservation "
|
||||
- "headroom (%d,%d) or provided a bad grant ref (%08x) "
|
||||
- "or is dying (%d)\n",
|
||||
- e->tot_pages, e->max_pages, gop.ref, e->is_dying);
|
||||
spin_unlock(&e->page_alloc_lock);
|
||||
+
|
||||
+ if ( e->is_dying )
|
||||
+ gdprintk(XENLOG_INFO, "gnttab_transfer: "
|
||||
+ "Transferee (d%d) is dying\n", e->domain_id);
|
||||
+ else
|
||||
+ gdprintk(XENLOG_INFO, "gnttab_transfer: "
|
||||
+ "Transferee (d%d) has no headroom (tot %u, max %u)\n",
|
||||
+ e->domain_id, e->tot_pages, e->max_pages);
|
||||
+
|
||||
rcu_unlock_domain(e);
|
||||
page->count_info &= ~(PGC_count_mask|PGC_allocated);
|
||||
free_domheap_page(page);
|
||||
@@ -1575,6 +1579,37 @@ gnttab_transfer(
|
||||
/* Okay, add the page to 'e'. */
|
||||
if ( unlikely(e->tot_pages++ == 0) )
|
||||
get_knownalive_domain(e);
|
||||
+
|
||||
+ /*
|
||||
+ * We must drop the lock to avoid a possible deadlock in
|
||||
+ * gnttab_prepare_for_transfer. We have reserved a page in e so can
|
||||
+ * safely drop the lock and re-aquire it later to add page to the
|
||||
+ * pagelist.
|
||||
+ */
|
||||
+ spin_unlock(&e->page_alloc_lock);
|
||||
+ okay = gnttab_prepare_for_transfer(e, d, gop.ref);
|
||||
+ spin_lock(&e->page_alloc_lock);
|
||||
+
|
||||
+ if ( unlikely(!okay) || unlikely(e->is_dying) )
|
||||
+ {
|
||||
+ bool_t drop_dom_ref = (e->tot_pages-- == 1);
|
||||
+
|
||||
+ spin_unlock(&e->page_alloc_lock);
|
||||
+
|
||||
+ if ( okay /* i.e. e->is_dying due to the surrounding if() */ )
|
||||
+ gdprintk(XENLOG_INFO, "gnttab_transfer: "
|
||||
+ "Transferee (d%d) is now dying\n", e->domain_id);
|
||||
+
|
||||
+ if ( drop_dom_ref )
|
||||
+ put_domain(e);
|
||||
+ rcu_unlock_domain(e);
|
||||
+
|
||||
+ page->count_info &= ~(PGC_count_mask|PGC_allocated);
|
||||
+ free_domheap_page(page);
|
||||
+ gop.status = GNTST_general_error;
|
||||
+ goto copyback;
|
||||
+ }
|
||||
+
|
||||
page_list_add_tail(page, &e->page_list);
|
||||
page_set_owner(page, e);
|
||||
|
||||
33
sysutils/xenkernel41/patches/patch-CVE-2013-4553
Normal file
33
sysutils/xenkernel41/patches/patch-CVE-2013-4553
Normal file
@@ -0,0 +1,33 @@
|
||||
$NetBSD: patch-CVE-2013-4553,v 1.1 2013/11/29 19:29:58 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-11/msg03828.html
|
||||
|
||||
--- xen/arch/x86/domctl.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/domctl.c 2013-11-29 15:19:13.000000000 +0000
|
||||
@@ -383,6 +383,26 @@ long arch_do_domctl(
|
||||
break;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * XSA-74: This sub-hypercall is broken in several ways:
|
||||
+ * - lock order inversion (p2m locks inside page_alloc_lock)
|
||||
+ * - no preemption on huge max_pfns input
|
||||
+ * - not (re-)checking d->is_dying with page_alloc_lock held
|
||||
+ * - not honoring start_pfn input (which libxc also doesn't set)
|
||||
+ * Additionally it is rather useless, as the result is stale by
|
||||
+ * the time the caller gets to look at it.
|
||||
+ * As it only has a single, non-production consumer (xen-mceinj),
|
||||
+ * rather than trying to fix it we restrict it for the time being.
|
||||
+ */
|
||||
+ if ( /* No nested locks inside copy_to_guest_offset(). */
|
||||
+ paging_mode_external(current->domain) ||
|
||||
+ /* Arbitrary limit capping processing time. */
|
||||
+ max_pfns > GB(4) / PAGE_SIZE )
|
||||
+ {
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
spin_lock(&d->page_alloc_lock);
|
||||
|
||||
if ( unlikely(d->is_dying) ) {
|
||||
28
sysutils/xenkernel41/patches/patch-CVE-2013-6885_1
Normal file
28
sysutils/xenkernel41/patches/patch-CVE-2013-6885_1
Normal file
@@ -0,0 +1,28 @@
|
||||
$NetBSD: patch-CVE-2013-6885_1,v 1.2 2014/02/20 17:37:25 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2013-12/msg00235.html
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2014-02/msg01800.html
|
||||
|
||||
--- xen/arch/x86/cpu/amd.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/cpu/amd.c
|
||||
@@ -661,6 +661,20 @@ static void __devinit init_amd(struct cp
|
||||
}
|
||||
#endif
|
||||
|
||||
+ if (c->x86 == 0x16 && c->x86_model <= 0xf) {
|
||||
+ rdmsrl(MSR_AMD64_LS_CFG, value);
|
||||
+ if (!(value & (1 << 15))) {
|
||||
+ static bool_t warned;
|
||||
+
|
||||
+ if (c == &boot_cpu_data || opt_cpu_info ||
|
||||
+ !test_and_set_bool(warned))
|
||||
+ printk(KERN_WARNING
|
||||
+ "CPU%u: Applying workaround for erratum 793\n",
|
||||
+ smp_processor_id());
|
||||
+ wrmsrl(MSR_AMD64_LS_CFG, value | (1 << 15));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (c->x86 == 0x10) {
|
||||
/*
|
||||
* On family 10h BIOS may not have properly enabled WC+
|
||||
12
sysutils/xenkernel41/patches/patch-CVE-2013-6885_2
Normal file
12
sysutils/xenkernel41/patches/patch-CVE-2013-6885_2
Normal file
@@ -0,0 +1,12 @@
|
||||
$NetBSD: patch-CVE-2013-6885_2,v 1.1 2013/12/04 10:35:01 drochner Exp $
|
||||
|
||||
--- xen/include/asm-x86/msr-index.h.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/include/asm-x86/msr-index.h 2013-12-03 16:55:24.000000000 +0000
|
||||
@@ -245,6 +245,7 @@
|
||||
|
||||
/* AMD64 MSRs */
|
||||
#define MSR_AMD64_NB_CFG 0xc001001f
|
||||
+#define MSR_AMD64_LS_CFG 0xc0011020
|
||||
#define MSR_AMD64_IC_CFG 0xc0011021
|
||||
#define MSR_AMD64_DC_CFG 0xc0011022
|
||||
#define AMD64_NB_CFG_CF8_EXT_ENABLE_BIT 46
|
||||
17
sysutils/xenkernel41/patches/patch-CVE-2014-1666
Normal file
17
sysutils/xenkernel41/patches/patch-CVE-2014-1666
Normal file
@@ -0,0 +1,17 @@
|
||||
$NetBSD: patch-CVE-2014-1666,v 1.1 2014/01/24 17:07:36 drochner Exp $
|
||||
|
||||
http://lists.xenproject.org/archives/html/xen-devel/2014-01/msg02075.html
|
||||
|
||||
--- xen/arch/x86/physdev.c.orig 2014-01-24 16:04:18.000000000 +0000
|
||||
+++ xen/arch/x86/physdev.c 2014-01-24 16:05:09.000000000 +0000
|
||||
@@ -554,7 +554,9 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
||||
case PHYSDEVOP_release_msix: {
|
||||
struct physdev_pci_device dev;
|
||||
|
||||
- if ( copy_from_guest(&dev, arg, 1) )
|
||||
+ if ( !IS_PRIV(v->domain) )
|
||||
+ ret = -EPERM;
|
||||
+ else if ( copy_from_guest(&dev, arg, 1) )
|
||||
ret = -EFAULT;
|
||||
else if ( dev.seg )
|
||||
ret = -EOPNOTSUPP;
|
||||
@@ -1,8 +1,6 @@
|
||||
$NetBSD: patch-xen_arch_x86_time.c,v 1.1 2013/04/11 19:57:52 joerg Exp $
|
||||
|
||||
--- xen/arch/x86/time.c.orig 2013-03-25 14:01:22.000000000 +0000
|
||||
+++ xen/arch/x86/time.c
|
||||
@@ -105,7 +105,7 @@ static inline u32 mul_frac(u32 multiplic
|
||||
--- xen/arch/x86/time.c.orig 2013-09-10 06:42:18.000000000 +0000
|
||||
+++ xen/arch/x86/time.c 2013-09-11 14:30:13.000000000 +0000
|
||||
@@ -105,7 +105,7 @@
|
||||
{
|
||||
u32 product_int, product_frac;
|
||||
asm (
|
||||
@@ -11,7 +9,7 @@ $NetBSD: patch-xen_arch_x86_time.c,v 1.1 2013/04/11 19:57:52 joerg Exp $
|
||||
: "=a" (product_frac), "=d" (product_int)
|
||||
: "0" (multiplicand), "r" (multiplier) );
|
||||
return product_int;
|
||||
@@ -129,10 +129,10 @@ static inline u64 scale_delta(u64 delta,
|
||||
@@ -129,10 +129,10 @@
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
asm (
|
||||
@@ -24,12 +22,3 @@ $NetBSD: patch-xen_arch_x86_time.c,v 1.1 2013/04/11 19:57:52 joerg Exp $
|
||||
"xor %5,%5 ; "
|
||||
"add %4,%%eax ; "
|
||||
"adc %5,%%edx ; "
|
||||
@@ -140,7 +140,7 @@ static inline u64 scale_delta(u64 delta,
|
||||
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (scale->mul_frac) );
|
||||
#else
|
||||
asm (
|
||||
- "mul %2 ; shrd $32,%1,%0"
|
||||
+ "mulq %2 ; shrd $32,%1,%0"
|
||||
: "=a" (product), "=d" (delta)
|
||||
: "rm" (delta), "0" ((u64)scale->mul_frac) );
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user