pkgsrc-Changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
CVS commit: pkgsrc/sysutils
Module Name: pkgsrc
Committed By: bouyer
Date: Thu Sep 8 15:41:01 UTC 2016
Modified Files:
pkgsrc/sysutils/xenkernel41: Makefile distinfo
pkgsrc/sysutils/xenkernel42: Makefile distinfo
Added Files:
pkgsrc/sysutils/xenkernel41/patches: patch-XSA-185 patch-XSA-187-1
patch-XSA-187-2
pkgsrc/sysutils/xenkernel42/patches: patch-XSA-185 patch-XSA-187-1
patch-XSA-187-2
Log Message:
Backport upstream patches for security issues:
XSA-185: x86: Disallow L3 recursive pagetable for 32-bit PV guests
XSA-187: x86 HVM: Overflow of sh_ctxt->seg_reg[]
bump PKGREVISION
To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 pkgsrc/sysutils/xenkernel41/Makefile
cvs rdiff -u -r1.43 -r1.44 pkgsrc/sysutils/xenkernel41/distinfo
cvs rdiff -u -r0 -r1.1 pkgsrc/sysutils/xenkernel41/patches/patch-XSA-185 \
pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-1 \
pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-2
cvs rdiff -u -r1.22 -r1.23 pkgsrc/sysutils/xenkernel42/Makefile
cvs rdiff -u -r1.20 -r1.21 pkgsrc/sysutils/xenkernel42/distinfo
cvs rdiff -u -r0 -r1.1 pkgsrc/sysutils/xenkernel42/patches/patch-XSA-185 \
pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-1 \
pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-2
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: pkgsrc/sysutils/xenkernel41/Makefile
diff -u pkgsrc/sysutils/xenkernel41/Makefile:1.50 pkgsrc/sysutils/xenkernel41/Makefile:1.51
--- pkgsrc/sysutils/xenkernel41/Makefile:1.50 Tue Jul 26 15:59:20 2016
+++ pkgsrc/sysutils/xenkernel41/Makefile Thu Sep 8 15:41:01 2016
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.50 2016/07/26 15:59:20 bouyer Exp $
+# $NetBSD: Makefile,v 1.51 2016/09/08 15:41:01 bouyer Exp $
VERSION= 4.1.6.1
DISTNAME= xen-${VERSION}
PKGNAME= xenkernel41-${VERSION}
-PKGREVISION= 19
+PKGREVISION= 20
CATEGORIES= sysutils
MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/
Index: pkgsrc/sysutils/xenkernel41/distinfo
diff -u pkgsrc/sysutils/xenkernel41/distinfo:1.43 pkgsrc/sysutils/xenkernel41/distinfo:1.44
--- pkgsrc/sysutils/xenkernel41/distinfo:1.43 Tue Jul 26 15:59:20 2016
+++ pkgsrc/sysutils/xenkernel41/distinfo Thu Sep 8 15:41:01 2016
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.43 2016/07/26 15:59:20 bouyer Exp $
+$NetBSD: distinfo,v 1.44 2016/09/08 15:41:01 bouyer Exp $
SHA1 (xen-4.1.6.1.tar.gz) = e5f15feb0821578817a65ede16110c6eac01abd0
RMD160 (xen-4.1.6.1.tar.gz) = bff11421fc44a26f2cc3156713267abcb36d7a19
@@ -38,6 +38,9 @@ SHA1 (patch-CVE-2015-8339) = e5485ab9e73
SHA1 (patch-Config.mk) = a43ed1b3304d6383dc093acd128a7f373d0ca266
SHA1 (patch-XSA-166) = 24fccf8e30ccf910a128e5e0365800191a90524c
SHA1 (patch-XSA-182) = 70a7a6175a4b87ffaf72cbc5a3932f076efa3f9c
+SHA1 (patch-XSA-185) = a2313922aa4dad734b96c80f64fe54eca3c14019
+SHA1 (patch-XSA-187-1) = 55ea0c2d9c7d8d9476a5ab97342ff552be4faf56
+SHA1 (patch-XSA-187-2) = e21b24771fa9417f593b8f6d1550660bbad36b98
SHA1 (patch-xen_Makefile) = d1c7e4860221f93d90818f45a77748882486f92b
SHA1 (patch-xen_arch_x86_Rules.mk) = 6b9b4bfa28924f7d3f6c793a389f1a7ac9d228e2
SHA1 (patch-xen_arch_x86_cpu_mcheck_vmce.c) = 5afd01780a13654f1d21bf1562f6431c8370be0b
Index: pkgsrc/sysutils/xenkernel42/Makefile
diff -u pkgsrc/sysutils/xenkernel42/Makefile:1.22 pkgsrc/sysutils/xenkernel42/Makefile:1.23
--- pkgsrc/sysutils/xenkernel42/Makefile:1.22 Tue Jul 26 15:38:00 2016
+++ pkgsrc/sysutils/xenkernel42/Makefile Thu Sep 8 15:41:01 2016
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.22 2016/07/26 15:38:00 bouyer Exp $
+# $NetBSD: Makefile,v 1.23 2016/09/08 15:41:01 bouyer Exp $
VERSION= 4.2.5
DISTNAME= xen-${VERSION}
PKGNAME= xenkernel42-${VERSION}
-PKGREVISION= 11
+PKGREVISION= 12
CATEGORIES= sysutils
MASTER_SITES= http://bits.xensource.com/oss-xen/release/${VERSION}/
Index: pkgsrc/sysutils/xenkernel42/distinfo
diff -u pkgsrc/sysutils/xenkernel42/distinfo:1.20 pkgsrc/sysutils/xenkernel42/distinfo:1.21
--- pkgsrc/sysutils/xenkernel42/distinfo:1.20 Tue Jul 26 15:38:00 2016
+++ pkgsrc/sysutils/xenkernel42/distinfo Thu Sep 8 15:41:01 2016
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.20 2016/07/26 15:38:00 bouyer Exp $
+$NetBSD: distinfo,v 1.21 2016/09/08 15:41:01 bouyer Exp $
SHA1 (xen-4.2.5.tar.gz) = f42741e4ec174495ace70c4b17a6b9b0e60e798a
RMD160 (xen-4.2.5.tar.gz) = 7d4f7f1b32ee541d341a756b1f8da02816438d19
@@ -27,6 +27,9 @@ SHA1 (patch-CVE-2015-8555) = 594f85557ef
SHA1 (patch-Config.mk) = a43ed1b3304d6383dc093acd128a7f373d0ca266
SHA1 (patch-XSA-166) = 24fccf8e30ccf910a128e5e0365800191a90524c
SHA1 (patch-XSA-182) = f0325a6f7c7cc20c3f11367384628dbe25c90b2d
+SHA1 (patch-XSA-185) = a2313922aa4dad734b96c80f64fe54eca3c14019
+SHA1 (patch-XSA-187-1) = 55ea0c2d9c7d8d9476a5ab97342ff552be4faf56
+SHA1 (patch-XSA-187-2) = ed2d384b4cf429443560afbf71b42fb4123a279b
SHA1 (patch-xen_Makefile) = e0d1b74518b9675ddc64295d1523ded9a8757c0a
SHA1 (patch-xen_arch_x86_Rules.mk) = 6b9b4bfa28924f7d3f6c793a389f1a7ac9d228e2
SHA1 (patch-xen_arch_x86_hvm_hvm.c) = b6bac1d466ba5bc276bc3aea9d4c9df37f2b9b0f
Added files:
Index: pkgsrc/sysutils/xenkernel41/patches/patch-XSA-185
diff -u /dev/null pkgsrc/sysutils/xenkernel41/patches/patch-XSA-185:1.1
--- /dev/null Thu Sep 8 15:41:01 2016
+++ pkgsrc/sysutils/xenkernel41/patches/patch-XSA-185 Thu Sep 8 15:41:01 2016
@@ -0,0 +1,37 @@
+$NetBSD: patch-XSA-185,v 1.1 2016/09/08 15:41:01 bouyer Exp $
+
+From 30aba4992b18245c436f16df7326a16c01a51570 Mon Sep 17 00:00:00 2001
+From: Jan Beulich <jbeulich%suse.com@localhost>
+Date: Mon, 8 Aug 2016 10:58:12 +0100
+Subject: x86/32on64: don't allow recursive page tables from L3
+
+L3 entries are special in PAE mode, and hence can't reasonably be used
+for setting up recursive (and hence linear) page table mappings. Since
+abuse is possible when the guest in fact gets run on 4-level page
+tables, this needs to be excluded explicitly.
+
+This is XSA-185.
+
+Reported-by: Jérémie Boutoille <jboutoille%ext.quarkslab.com@localhost>
+Reported-by: 栾尚聪(好风) <shangcong.lsc%alibaba-inc.com@localhost>
+Signed-off-by: Jan Beulich <jbeulich%suse.com@localhost>
+Reviewed-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+---
+ xen/arch/x86/mm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
+index 109b8be..69b8b8d 100644
+--- xen/arch/x86/mm.c.orig
++++ xen/arch/x86/mm.c
+@@ -1122,7 +1122,9 @@ get_page_from_l3e(
+
+ rc = get_page_and_type_from_pagenr(
+ l3e_get_pfn(l3e), PGT_l2_page_table, d, partial, 1);
+- if ( unlikely(rc == -EINVAL) && get_l3_linear_pagetable(l3e, pfn, d) )
++ if ( unlikely(rc == -EINVAL) &&
++ !is_pv_32bit_domain(d) &&
++ get_l3_linear_pagetable(l3e, pfn, d) )
+ rc = 0;
+
+ return rc;
Index: pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-1
diff -u /dev/null pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-1:1.1
--- /dev/null Thu Sep 8 15:41:01 2016
+++ pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-1 Thu Sep 8 15:41:01 2016
@@ -0,0 +1,44 @@
+$NetBSD: patch-XSA-187-1,v 1.1 2016/09/08 15:41:01 bouyer Exp $
+
+From: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Subject: x86/shadow: Avoid overflowing sh_ctxt->seg_reg[]
+
+hvm_get_seg_reg() does not perform a range check on its input segment, calls
+hvm_get_segment_register() and writes straight into sh_ctxt->seg_reg[].
+
+x86_seg_none is outside the bounds of sh_ctxt->seg_reg[], and will hit a BUG()
+in {vmx,svm}_get_segment_register().
+
+HVM guests running with shadow paging can end up performing a virtual to
+linear translation with x86_seg_none. This is used for addresses which are
+already linear. However, none of this is a legitimate pagetable update, so
+fail the emulation in such a case.
+
+This is XSA-187
+
+Reported-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Signed-off-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Reviewed-by: Tim Deegan <tim%xen.org@localhost>
+
+--- xen/arch/x86/mm/shadow/common.c.orig
++++ xen/arch/x86/mm/shadow/common.c
+@@ -140,9 +140,18 @@ static int hvm_translate_linear_addr(
+ struct sh_emulate_ctxt *sh_ctxt,
+ unsigned long *paddr)
+ {
+- struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt);
++ struct segment_register *reg;
+ int okay;
+
++ /*
++ * Can arrive here with non-user segments. However, no such cirucmstance
++ * is part of a legitimate pagetable update, so fail the emulation.
++ */
++ if ( !is_x86_user_segment(seg) )
++ return X86EMUL_UNHANDLEABLE;
++
++ reg = hvm_get_seg_reg(seg, sh_ctxt);
++
+ okay = hvm_virtual_to_linear_addr(
+ seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr);
+
Index: pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-2
diff -u /dev/null pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-2:1.1
--- /dev/null Thu Sep 8 15:41:01 2016
+++ pkgsrc/sysutils/xenkernel41/patches/patch-XSA-187-2 Thu Sep 8 15:41:01 2016
@@ -0,0 +1,152 @@
+$NetBSD: patch-XSA-187-2,v 1.1 2016/09/08 15:41:01 bouyer Exp $
+
+From: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Subject: x86/segment: Bounds check accesses to emulation ctxt->seg_reg[]
+
+HVM HAP codepaths have space for all segment registers in the seg_reg[]
+cache (with x86_seg_none still risking an array overrun), while the shadow
+codepaths only have space for the user segments.
+
+Range check the input segment of *_get_seg_reg() against the size of the array
+used to cache the results, to avoid overruns in the case that the callers
+don't filter their input suitably.
+
+Subsume the is_x86_user_segment(seg) checks from the shadow code, which were
+an incomplete attempt at range checking, and are now superceeded. Make
+hvm_get_seg_reg() static, as it is not used outside of shadow/common.c
+
+No functional change, but far easier to reason that no overflow is possible.
+
+Reported-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Signed-off-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Acked-by: Tim Deegan <tim%xen.org@localhost>
+Acked-by: Jan Beulich <jbeulich%suse.com@localhost>
+
+--- xen/include/asm-x86/hvm/emulate.h.orig 2014-09-02 08:22:57.000000000 +0200
++++ xen/include/asm-x86/hvm/emulate.h 2016-09-08 15:57:32.000000000 +0200
+@@ -13,6 +13,7 @@
+ #define __ASM_X86_HVM_EMULATE_H__
+
+ #include <xen/config.h>
++#include <xen/err.h>
+ #include <asm/x86_emulate.h>
+
+ struct hvm_emulate_ctxt {
+--- xen/arch/x86/hvm/emulate.c.orig 2014-09-02 08:22:57.000000000 +0200
++++ xen/arch/x86/hvm/emulate.c 2016-09-08 16:01:31.000000000 +0200
+@@ -390,6 +390,8 @@
+ *reps = min_t(unsigned long, *reps, 4096);
+
+ reg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
++ if ( IS_ERR(reg) )
++ return -PTR_ERR(reg);
+
+ if ( (hvmemul_ctxt->ctxt.regs->eflags & X86_EFLAGS_DF) && (*reps > 1) )
+ {
+@@ -777,6 +779,10 @@
+ struct hvm_emulate_ctxt *hvmemul_ctxt =
+ container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
+ struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
++
++ if ( IS_ERR(sreg) )
++ return -PTR_ERR(sreg);
++
+ memcpy(reg, sreg, sizeof(struct segment_register));
+ return X86EMUL_OKAY;
+ }
+@@ -790,6 +796,9 @@
+ container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
+ struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
+
++ if ( IS_ERR(sreg) )
++ return -PTR_ERR(sreg);
++
+ memcpy(sreg, reg, sizeof(struct segment_register));
+ __set_bit(seg, &hvmemul_ctxt->seg_reg_dirty);
+
+@@ -1130,10 +1139,17 @@
+ }
+ }
+
++/*
++ * Callers which pass a known in-range x86_segment can rely on the return
++ * pointer being valid. Other callers must explicitly check for errors.
++ */
+ struct segment_register *hvmemul_get_seg_reg(
+ enum x86_segment seg,
+ struct hvm_emulate_ctxt *hvmemul_ctxt)
+ {
++ if ( seg < 0 || seg >= ARRAY_SIZE(hvmemul_ctxt->seg_reg) )
++ return ERR_PTR(-X86EMUL_UNHANDLEABLE);
++
+ if ( !__test_and_set_bit(seg, &hvmemul_ctxt->seg_reg_accessed) )
+ hvm_get_segment_register(current, seg, &hvmemul_ctxt->seg_reg[seg]);
+ return &hvmemul_ctxt->seg_reg[seg];
+--- xen/arch/x86/mm/shadow/common.c.orig 2016-09-08 17:15:35.000000000 +0200
++++ xen/arch/x86/mm/shadow/common.c 2016-09-08 17:29:23.000000000 +0200
+@@ -22,6 +22,7 @@
+ */
+
+ #include <xen/config.h>
++#include <xen/err.h>
+ #include <xen/types.h>
+ #include <xen/mm.h>
+ #include <xen/trace.h>
+@@ -116,10 +117,19 @@
+ /* x86 emulator support for the shadow code
+ */
+
++/*
++ * Callers which pass a known in-range x86_segment can rely on the return
++ * pointer being valid. Other callers must explicitly check for errors.
++ */
+ struct segment_register *hvm_get_seg_reg(
+ enum x86_segment seg, struct sh_emulate_ctxt *sh_ctxt)
+ {
+- struct segment_register *seg_reg = &sh_ctxt->seg_reg[seg];
++ struct segment_register *seg_reg;
++
++ if ( seg < 0 || seg >= ARRAY_SIZE(sh_ctxt->seg_reg) )
++ return ERR_PTR(-X86EMUL_UNHANDLEABLE);
++
++ seg_reg = &sh_ctxt->seg_reg[seg];
+ if ( !__test_and_set_bit(seg, &sh_ctxt->valid_seg_regs) )
+ hvm_get_segment_register(current, seg, seg_reg);
+ return seg_reg;
+@@ -136,14 +146,9 @@
+ struct segment_register *reg;
+ int okay;
+
+- /*
+- * Can arrive here with non-user segments. However, no such cirucmstance
+- * is part of a legitimate pagetable update, so fail the emulation.
+- */
+- if ( !is_x86_user_segment(seg) )
+- return X86EMUL_UNHANDLEABLE;
+-
+ reg = hvm_get_seg_reg(seg, sh_ctxt);
++ if ( IS_ERR(reg) )
++ return -PTR_ERR(reg);
+
+ okay = hvm_virtual_to_linear_addr(
+ seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr);
+@@ -245,9 +250,6 @@
+ unsigned long addr;
+ int rc;
+
+- if ( !is_x86_user_segment(seg) )
+- return X86EMUL_UNHANDLEABLE;
+-
+ /* How many emulations could we save if we unshadowed on stack writes? */
+ if ( seg == x86_seg_ss )
+ perfc_incr(shadow_fault_emulate_stack);
+@@ -275,9 +277,6 @@
+ unsigned long addr, old[2], new[2];
+ int rc;
+
+- if ( !is_x86_user_segment(seg) )
+- return X86EMUL_UNHANDLEABLE;
+-
+ rc = hvm_translate_linear_addr(
+ seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
+ if ( rc )
Index: pkgsrc/sysutils/xenkernel42/patches/patch-XSA-185
diff -u /dev/null pkgsrc/sysutils/xenkernel42/patches/patch-XSA-185:1.1
--- /dev/null Thu Sep 8 15:41:01 2016
+++ pkgsrc/sysutils/xenkernel42/patches/patch-XSA-185 Thu Sep 8 15:41:01 2016
@@ -0,0 +1,37 @@
+$NetBSD: patch-XSA-185,v 1.1 2016/09/08 15:41:01 bouyer Exp $
+
+From 30aba4992b18245c436f16df7326a16c01a51570 Mon Sep 17 00:00:00 2001
+From: Jan Beulich <jbeulich%suse.com@localhost>
+Date: Mon, 8 Aug 2016 10:58:12 +0100
+Subject: x86/32on64: don't allow recursive page tables from L3
+
+L3 entries are special in PAE mode, and hence can't reasonably be used
+for setting up recursive (and hence linear) page table mappings. Since
+abuse is possible when the guest in fact gets run on 4-level page
+tables, this needs to be excluded explicitly.
+
+This is XSA-185.
+
+Reported-by: Jérémie Boutoille <jboutoille%ext.quarkslab.com@localhost>
+Reported-by: 栾尚聪(好风) <shangcong.lsc%alibaba-inc.com@localhost>
+Signed-off-by: Jan Beulich <jbeulich%suse.com@localhost>
+Reviewed-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+---
+ xen/arch/x86/mm.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
+index 109b8be..69b8b8d 100644
+--- xen/arch/x86/mm.c.orig
++++ xen/arch/x86/mm.c
+@@ -1122,7 +1122,9 @@ get_page_from_l3e(
+
+ rc = get_page_and_type_from_pagenr(
+ l3e_get_pfn(l3e), PGT_l2_page_table, d, partial, 1);
+- if ( unlikely(rc == -EINVAL) && get_l3_linear_pagetable(l3e, pfn, d) )
++ if ( unlikely(rc == -EINVAL) &&
++ !is_pv_32bit_domain(d) &&
++ get_l3_linear_pagetable(l3e, pfn, d) )
+ rc = 0;
+
+ return rc;
Index: pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-1
diff -u /dev/null pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-1:1.1
--- /dev/null Thu Sep 8 15:41:01 2016
+++ pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-1 Thu Sep 8 15:41:01 2016
@@ -0,0 +1,44 @@
+$NetBSD: patch-XSA-187-1,v 1.1 2016/09/08 15:41:01 bouyer Exp $
+
+From: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Subject: x86/shadow: Avoid overflowing sh_ctxt->seg_reg[]
+
+hvm_get_seg_reg() does not perform a range check on its input segment, calls
+hvm_get_segment_register() and writes straight into sh_ctxt->seg_reg[].
+
+x86_seg_none is outside the bounds of sh_ctxt->seg_reg[], and will hit a BUG()
+in {vmx,svm}_get_segment_register().
+
+HVM guests running with shadow paging can end up performing a virtual to
+linear translation with x86_seg_none. This is used for addresses which are
+already linear. However, none of this is a legitimate pagetable update, so
+fail the emulation in such a case.
+
+This is XSA-187
+
+Reported-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Signed-off-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Reviewed-by: Tim Deegan <tim%xen.org@localhost>
+
+--- xen/arch/x86/mm/shadow/common.c.orig
++++ xen/arch/x86/mm/shadow/common.c
+@@ -140,9 +140,18 @@ static int hvm_translate_linear_addr(
+ struct sh_emulate_ctxt *sh_ctxt,
+ unsigned long *paddr)
+ {
+- struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt);
++ struct segment_register *reg;
+ int okay;
+
++ /*
++ * Can arrive here with non-user segments. However, no such cirucmstance
++ * is part of a legitimate pagetable update, so fail the emulation.
++ */
++ if ( !is_x86_user_segment(seg) )
++ return X86EMUL_UNHANDLEABLE;
++
++ reg = hvm_get_seg_reg(seg, sh_ctxt);
++
+ okay = hvm_virtual_to_linear_addr(
+ seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr);
+
Index: pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-2
diff -u /dev/null pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-2:1.1
--- /dev/null Thu Sep 8 15:41:01 2016
+++ pkgsrc/sysutils/xenkernel42/patches/patch-XSA-187-2 Thu Sep 8 15:41:01 2016
@@ -0,0 +1,144 @@
+$NetBSD: patch-XSA-187-2,v 1.1 2016/09/08 15:41:01 bouyer Exp $
+
+From: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Subject: x86/segment: Bounds check accesses to emulation ctxt->seg_reg[]
+
+HVM HAP codepaths have space for all segment registers in the seg_reg[]
+cache (with x86_seg_none still risking an array overrun), while the shadow
+codepaths only have space for the user segments.
+
+Range check the input segment of *_get_seg_reg() against the size of the array
+used to cache the results, to avoid overruns in the case that the callers
+don't filter their input suitably.
+
+Subsume the is_x86_user_segment(seg) checks from the shadow code, which were
+an incomplete attempt at range checking, and are now superceeded. Make
+hvm_get_seg_reg() static, as it is not used outside of shadow/common.c
+
+No functional change, but far easier to reason that no overflow is possible.
+
+Reported-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Signed-off-by: Andrew Cooper <andrew.cooper3%citrix.com@localhost>
+Acked-by: Tim Deegan <tim%xen.org@localhost>
+Acked-by: Jan Beulich <jbeulich%suse.com@localhost>
+
+--- xen/arch/x86/mm/shadow/common.c.orig
++++ xen/arch/x86/mm/shadow/common.c
+@@ -125,10 +125,19 @@ __initcall(shadow_audit_key_init);
+ /* x86 emulator support for the shadow code
+ */
+
++/*
++ * Callers which pass a known in-range x86_segment can rely on the return
++ * pointer being valid. Other callers must explicitly check for errors.
++ */
+ struct segment_register *hvm_get_seg_reg(
+ enum x86_segment seg, struct sh_emulate_ctxt *sh_ctxt)
+ {
+- struct segment_register *seg_reg = &sh_ctxt->seg_reg[seg];
++ struct segment_register *seg_reg;
++
++ if ( seg < 0 || seg >= ARRAY_SIZE(sh_ctxt->seg_reg) )
++ return ERR_PTR(-X86EMUL_UNHANDLEABLE);
++
++ seg_reg = &sh_ctxt->seg_reg[seg];
+ if ( !__test_and_set_bit(seg, &sh_ctxt->valid_seg_regs) )
+ hvm_get_segment_register(current, seg, seg_reg);
+ return seg_reg;
+@@ -145,14 +154,9 @@ static int hvm_translate_linear_addr(
+ struct segment_register *reg;
+ int okay;
+
+- /*
+- * Can arrive here with non-user segments. However, no such cirucmstance
+- * is part of a legitimate pagetable update, so fail the emulation.
+- */
+- if ( !is_x86_user_segment(seg) )
+- return X86EMUL_UNHANDLEABLE;
+-
+ reg = hvm_get_seg_reg(seg, sh_ctxt);
++ if ( IS_ERR(reg) )
++ return -PTR_ERR(reg);
+
+ okay = hvm_virtual_to_linear_addr(
+ seg, reg, offset, bytes, access_type, sh_ctxt->ctxt.addr_size, paddr);
+@@ -254,9 +258,6 @@ hvm_emulate_write(enum x86_segment seg,
+ unsigned long addr;
+ int rc;
+
+- if ( !is_x86_user_segment(seg) )
+- return X86EMUL_UNHANDLEABLE;
+-
+ /* How many emulations could we save if we unshadowed on stack writes? */
+ if ( seg == x86_seg_ss )
+ perfc_incr(shadow_fault_emulate_stack);
+@@ -284,9 +285,6 @@ hvm_emulate_cmpxchg(enum x86_segment seg
+ unsigned long addr, old[2], new[2];
+ int rc;
+
+- if ( !is_x86_user_segment(seg) )
+- return X86EMUL_UNHANDLEABLE;
+-
+ rc = hvm_translate_linear_addr(
+ seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
+ if ( rc )
+--- xen/include/asm-x86/hvm/emulate.h.orig 2014-09-02 08:22:57.000000000 +0200
++++ xen/include/asm-x86/hvm/emulate.h 2016-09-08 15:57:32.000000000 +0200
+@@ -13,6 +13,7 @@
+ #define __ASM_X86_HVM_EMULATE_H__
+
+ #include <xen/config.h>
++#include <xen/err.h>
+ #include <asm/x86_emulate.h>
+
+ struct hvm_emulate_ctxt {
+--- xen/arch/x86/hvm/emulate.c.orig 2014-09-02 08:22:57.000000000 +0200
++++ xen/arch/x86/hvm/emulate.c 2016-09-08 16:01:31.000000000 +0200
+@@ -390,6 +390,8 @@
+ *reps = min_t(unsigned long, *reps, 4096);
+
+ reg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
++ if ( IS_ERR(reg) )
++ return -PTR_ERR(reg);
+
+ if ( (hvmemul_ctxt->ctxt.regs->eflags & X86_EFLAGS_DF) && (*reps > 1) )
+ {
+@@ -777,6 +779,10 @@
+ struct hvm_emulate_ctxt *hvmemul_ctxt =
+ container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
+ struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
++
++ if ( IS_ERR(sreg) )
++ return -PTR_ERR(sreg);
++
+ memcpy(reg, sreg, sizeof(struct segment_register));
+ return X86EMUL_OKAY;
+ }
+@@ -790,6 +796,9 @@
+ container_of(ctxt, struct hvm_emulate_ctxt, ctxt);
+ struct segment_register *sreg = hvmemul_get_seg_reg(seg, hvmemul_ctxt);
+
++ if ( IS_ERR(sreg) )
++ return -PTR_ERR(sreg);
++
+ memcpy(sreg, reg, sizeof(struct segment_register));
+ __set_bit(seg, &hvmemul_ctxt->seg_reg_dirty);
+
+@@ -1130,10 +1139,17 @@
+ }
+ }
+
++/*
++ * Callers which pass a known in-range x86_segment can rely on the return
++ * pointer being valid. Other callers must explicitly check for errors.
++ */
+ struct segment_register *hvmemul_get_seg_reg(
+ enum x86_segment seg,
+ struct hvm_emulate_ctxt *hvmemul_ctxt)
+ {
++ if ( seg < 0 || seg >= ARRAY_SIZE(hvmemul_ctxt->seg_reg) )
++ return ERR_PTR(-X86EMUL_UNHANDLEABLE);
++
+ if ( !__test_and_set_bit(seg, &hvmemul_ctxt->seg_reg_accessed) )
+ hvm_get_segment_register(current, seg, &hvmemul_ctxt->seg_reg[seg]);
+ return &hvmemul_ctxt->seg_reg[seg];
Home |
Main Index |
Thread Index |
Old Index