[xen/f17] XSA-45/CVE-2013-1918 breaks page reference counting let pygrub handle set default="${next_entry}" li
myoung
myoung at fedoraproject.org
Wed Jun 26 21:13:23 UTC 2013
commit b29be0eabfb0fa65e3523e2a905007a0bded71a9
Author: Michael Young <m.a.young at durham.ac.uk>
Date: Wed Jun 26 22:11:00 2013 +0100
XSA-45/CVE-2013-1918 breaks page reference counting
let pygrub handle set default="${next_entry}" line in F19
pygrub.next_entryfix.patch | 13 +++++
xen.spec | 14 +++++-
xsa58-4.1.patch | 119 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 144 insertions(+), 2 deletions(-)
---
diff --git a/pygrub.next_entryfix.patch b/pygrub.next_entryfix.patch
new file mode 100644
index 0000000..e9eb782
--- /dev/null
+++ b/pygrub.next_entryfix.patch
@@ -0,0 +1,13 @@
+diff --git a/tools/pygrub/src/GrubConf.py b/tools/pygrub/src/GrubConf.py
+index 629951f..6324c62 100644
+--- a/tools/pygrub/src/GrubConf.py
++++ b/tools/pygrub/src/GrubConf.py
+@@ -427,6 +427,8 @@ class Grub2ConfigFile(_GrubConfigFile):
+ if self.commands[com] is not None:
+ if arg.strip() == "${saved_entry}":
+ arg = "0"
++ elif arg.strip() == "${next_entry}":
++ arg = "0"
+ setattr(self, self.commands[com], arg.strip())
+ else:
+ logging.info("Ignored directive %s" %(com,))
diff --git a/xen.spec b/xen.spec
index 9296378..dbef674 100644
--- a/xen.spec
+++ b/xen.spec
@@ -20,7 +20,7 @@
Summary: Xen is a virtual machine monitor
Name: xen
Version: 4.1.5
-Release: 8%{?dist}
+Release: 9%{?dist}
Group: Development/Libraries
License: GPLv2+ and LGPLv2+ and BSD
URL: http://xen.org/
@@ -108,6 +108,8 @@ Patch92: xsa55-4.10020-libxc-range-checks-in-xc_dom_p2m_host-and-_guest.patch
Patch93: xsa55-4.10021-libxc-check-blob-size-before-proceeding-in-xc_dom_ch.patch
Patch94: xsa57-4.1.patch
Patch95: xen.git-934a5253d932b6f67fe40fc48975a2b0117e4cce.patch
+Patch96: xsa58-4.1.patch
+Patch97: pygrub.next_entryfix.patch
Patch100: xen-configure-xend.patch
@@ -302,6 +304,8 @@ manage Xen virtual machines.
%patch93 -p1
%patch94 -p1
%patch95 -p1
+%patch96 -p1
+%patch97 -p1
%patch100 -p1
@@ -760,11 +764,17 @@ rm -rf %{buildroot}
%endif
%changelog
+* Wed Jun 26 2013 Michael Young <m.a.young at durham.ac.uk> - 4.1.5-9
+- XSA-45/CVE-2013-1918 breaks page reference counting [XSA-58,
+ CVE-2013-1432] (#978383)
+- let pygrub handle set default="${next_entry}" line in F19 (#978036)
+
* Mon Jun 24 2013 Michael Young <m.a.young at durham.ac.uk> - 4.1.5-8
- add upstream patch for PCI passthrough problems after XSA-46
* Fri Jun 21 2013 Michael Young <m.a.young at durham.ac.uk> - 4.1.5-7
-- xenstore permissions not set correctly by libxl [XSA-57] (#976779)
+- xenstore permissions not set correctly by libxl [XSA-57,
+ CVE-2013-2211] (#976779)
* Fri Jun 14 2013 Michael Young <m.a.young at durham.ac.uk> - 4.1.5-6
- Revised fixes for [XSA-55, CVE-2013-2194 CVE-2013-2195
diff --git a/xsa58-4.1.patch b/xsa58-4.1.patch
new file mode 100644
index 0000000..3c982a3
--- /dev/null
+++ b/xsa58-4.1.patch
@@ -0,0 +1,119 @@
+x86: fix page refcount handling in page table pin error path
+
+In the original patch 7 of the series addressing XSA-45 I mistakenly
+took the addition of the call to get_page_light() in alloc_page_type()
+to cover two decrements that would happen: One for the PGT_partial bit
+that is getting set along with the call, and the other for the page
+reference the caller hold (and would be dropping on its error path).
+But of course the additional page reference is tied to the PGT_partial
+bit, and hence any caller of a function that may leave
+->arch.old_guest_table non-NULL for error cleanup purposes has to make
+sure a respective page reference gets retained.
+
+Similar issues were then also spotted elsewhere: In effect all callers
+of get_page_type_preemptible() need to deal with errors in similar
+ways. To make sure error handling can work this way without leaking
+page references, a respective assertion gets added to that function.
+
+This is CVE-2013-1432 / XSA-58.
+
+Reported-by: Andrew Cooper <andrew.cooper3 at citrix.com>
+Signed-off-by: Jan Beulich <jbeulich at suse.com>
+Tested-by: Andrew Cooper <andrew.cooper3 at citrix.com>
+Reviewed-by: Tim Deegan <tim at xen.org>
+
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -798,6 +798,10 @@ int arch_set_info_guest(
+ if ( v->vcpu_id == 0 )
+ d->vm_assist = c(vm_assist);
+
++ rc = put_old_guest_table(current);
++ if ( rc )
++ return rc;
++
+ if ( !compat )
+ rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
+ #ifdef CONFIG_COMPAT
+@@ -840,18 +844,24 @@ int arch_set_info_guest(
+ }
+ 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);
++ rc = put_old_guest_table(v);
+ if ( !rc )
+ rc = get_page_type_preemptible(cr3_page,
+ !compat ? PGT_root_page_table
+ : PGT_l3_page_table);
+- if ( rc == -EINTR )
++ switch ( rc )
++ {
++ case -EINTR:
+ rc = -EAGAIN;
++ case -EAGAIN:
++ case 0:
++ break;
++ default:
++ if ( cr3_page == current->arch.old_guest_table )
++ cr3_page = NULL;
++ break;
++ }
+ }
+
+ if ( rc )
+@@ -883,6 +893,11 @@ int arch_set_info_guest(
+ pagetable_get_page(v->arch.guest_table);
+ v->arch.guest_table = pagetable_null();
+ break;
++ default:
++ if ( cr3_page == current->arch.old_guest_table )
++ cr3_page = NULL;
++ case 0:
++ break;
+ }
+ }
+
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -682,7 +682,8 @@ static int get_page_and_type_from_pagenr
+ get_page_type_preemptible(page, type) :
+ (get_page_type(page, type) ? 0 : -EINVAL));
+
+- if ( unlikely(rc) && partial >= 0 )
++ if ( unlikely(rc) && partial >= 0 &&
++ (!preemptible || page != current->arch.old_guest_table) )
+ put_page(page);
+
+ return rc;
+@@ -2555,6 +2556,7 @@ int put_page_type_preemptible(struct pag
+
+ int get_page_type_preemptible(struct page_info *page, unsigned long type)
+ {
++ ASSERT(!current->arch.old_guest_table);
+ return __get_page_type(page, type, 1);
+ }
+
+@@ -2765,7 +2767,7 @@ static void put_superpage(unsigned long
+
+ #endif
+
+-static int put_old_guest_table(struct vcpu *v)
++int put_old_guest_table(struct vcpu *v)
+ {
+ int rc;
+
+--- a/xen/include/asm-x86/mm.h
++++ b/xen/include/asm-x86/mm.h
+@@ -337,6 +337,7 @@ void put_page_type(struct page_info *pag
+ int get_page_type(struct page_info *page, unsigned long type);
+ int put_page_type_preemptible(struct page_info *page);
+ int get_page_type_preemptible(struct page_info *page, unsigned long type);
++int put_old_guest_table(struct vcpu *);
+ int get_page_from_l1e(
+ l1_pgentry_t l1e, struct domain *l1e_owner, struct domain *pg_owner);
+ void put_page_from_l1e(l1_pgentry_t l1e, struct domain *l1e_owner);
More information about the scm-commits
mailing list