Commit f87a9718 authored by Natanael Copa's avatar Natanael Copa

main/xen: main/xen: fix xsa45 and xsa58 (CVE-2013-1918,CVE-2013-1432)

ref #2123
fixes #2126
parent e4a6a3bd
......@@ -3,7 +3,7 @@
# Maintainer: William Pitcock <nenolod@dereferenced.org>
pkgname=xen
pkgver=4.1.4
pkgrel=5
pkgrel=6
pkgdesc="Xen hypervisor"
url="http://www.xen.org/"
arch="x86 x86_64"
......@@ -24,12 +24,14 @@ source="http://bits.xensource.com/oss-xen/release/$pkgver/$pkgname-$pkgver.tar.g
busybox-sed.patch
xsa33-4.1.patch
xsa41.patch
xsa45-4.1.patch
xsa52-4.1.patch
xsa53-4.1.patch
xsa54.patch
xsa55-4.1.patch
xsa56.patch
xsa57-4.1.patch
xsa58-4.1.patch
xenstored.initd
xenstored.confd
......@@ -131,12 +133,14 @@ fa06495a175571f4aa3b6cb88937953e librt.patch
1bea3543ddc712330527b62fd9ff6520 busybox-sed.patch
25ba4efc5eee29daa12855fbadce84f8 xsa33-4.1.patch
ce56f00762139cd611dfc3332b7571cf xsa41.patch
09c675a4a28ee00dd9abeacc07426edd xsa45-4.1.patch
db1e5a92547c8c8ed2e1872efed99ab0 xsa52-4.1.patch
e11ae888997d11fcb91b431ebf609d4e xsa53-4.1.patch
a8393d1ec6b886ea72ffe624a04ee10a xsa54.patch
391d90e3851df0b42b2971e8b860e19a xsa55-4.1.patch
e70b9128ffc2175cea314a533a7d8457 xsa56.patch
a065178b8f5ed028b97fa51db97e41e2 xsa57-4.1.patch
dd46795cf7bb7bb9baa50bfdf4813d4f xsa58-4.1.patch
6e5739dad7e2bd1b625e55ddc6c782b7 xenstored.initd
b017ccdd5e1c27bbf1513e3569d4ff07 xenstored.confd
ed262f15fb880badb53575539468646c xenconsoled.initd
......
This diff is collapsed.
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@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Tim Deegan <tim@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);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment