diff options
author | Roger Pau Monne <roger.pau@citrix.com> | 2012-12-03 19:51:49 +0100 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2012-12-04 06:54:47 +0000 |
commit | 02c9cf16cb335a73de4a175a8f9a451a4a19a1ed (patch) | |
tree | 481db828ae338f47654b3a5dbd560223d14f11e0 /main/xen/xsa26-4.2.patch | |
parent | 9dcb820d809f104dd8d04314d3ab175334a7470f (diff) | |
download | aports-02c9cf16cb335a73de4a175a8f9a451a4a19a1ed.tar.bz2 aports-02c9cf16cb335a73de4a175a8f9a451a4a19a1ed.tar.xz |
xen: security fixes
This covers:
XSA-26 (CVE-2012-5510)
XSA-27 (CVE-2012-5511)
XSA-29 (CVE-2012-5513)
XSA-30 (CVE-2012-5514)
XSA-31 (CVE-2012-5515)
XSA-32 (CVE-2012-5525)
Diffstat (limited to 'main/xen/xsa26-4.2.patch')
-rw-r--r-- | main/xen/xsa26-4.2.patch | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/main/xen/xsa26-4.2.patch b/main/xen/xsa26-4.2.patch new file mode 100644 index 000000000..44b8f344e --- /dev/null +++ b/main/xen/xsa26-4.2.patch @@ -0,0 +1,105 @@ +gnttab: fix releasing of memory upon switches between versions + +gnttab_unpopulate_status_frames() incompletely freed the pages +previously used as status frame in that they did not get removed from +the domain's xenpage_list, thus causing subsequent list corruption +when those pages did get allocated again for the same or another purpose. + +Similarly, grant_table_create() and gnttab_grow_table() both improperly +clean up in the event of an error - pages already shared with the guest +can't be freed by just passing them to free_xenheap_page(). Fix this by +sharing the pages only after all allocations succeeded. + +This is CVE-2012-5510 / XSA-26. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Acked-by: Ian Campbell <ian.campbell@citrix.com> + +diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c +index c01ad00..6fb2be9 100644 +--- a/xen/common/grant_table.c ++++ b/xen/common/grant_table.c +@@ -1173,12 +1173,13 @@ fault: + } + + static int +-gnttab_populate_status_frames(struct domain *d, struct grant_table *gt) ++gnttab_populate_status_frames(struct domain *d, struct grant_table *gt, ++ unsigned int req_nr_frames) + { + unsigned i; + unsigned req_status_frames; + +- req_status_frames = grant_to_status_frames(gt->nr_grant_frames); ++ req_status_frames = grant_to_status_frames(req_nr_frames); + for ( i = nr_status_frames(gt); i < req_status_frames; i++ ) + { + if ( (gt->status[i] = alloc_xenheap_page()) == NULL ) +@@ -1209,7 +1210,12 @@ gnttab_unpopulate_status_frames(struct domain *d, struct grant_table *gt) + + for ( i = 0; i < nr_status_frames(gt); i++ ) + { +- page_set_owner(virt_to_page(gt->status[i]), dom_xen); ++ struct page_info *pg = virt_to_page(gt->status[i]); ++ ++ BUG_ON(page_get_owner(pg) != d); ++ if ( test_and_clear_bit(_PGC_allocated, &pg->count_info) ) ++ put_page(pg); ++ BUG_ON(pg->count_info & ~PGC_xen_heap); + free_xenheap_page(gt->status[i]); + gt->status[i] = NULL; + } +@@ -1247,19 +1253,18 @@ gnttab_grow_table(struct domain *d, unsigned int req_nr_frames) + clear_page(gt->shared_raw[i]); + } + +- /* Share the new shared frames with the recipient domain */ +- for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ ) +- gnttab_create_shared_page(d, gt, i); +- +- gt->nr_grant_frames = req_nr_frames; +- + /* Status pages - version 2 */ + if (gt->gt_version > 1) + { +- if ( gnttab_populate_status_frames(d, gt) ) ++ if ( gnttab_populate_status_frames(d, gt, req_nr_frames) ) + goto shared_alloc_failed; + } + ++ /* Share the new shared frames with the recipient domain */ ++ for ( i = nr_grant_frames(gt); i < req_nr_frames; i++ ) ++ gnttab_create_shared_page(d, gt, i); ++ gt->nr_grant_frames = req_nr_frames; ++ + return 1; + + shared_alloc_failed: +@@ -2157,7 +2162,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop)) + + if ( op.version == 2 && gt->gt_version < 2 ) + { +- res = gnttab_populate_status_frames(d, gt); ++ res = gnttab_populate_status_frames(d, gt, nr_grant_frames(gt)); + if ( res < 0) + goto out_unlock; + } +@@ -2600,14 +2605,15 @@ grant_table_create( + clear_page(t->shared_raw[i]); + } + +- for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ ) +- gnttab_create_shared_page(d, t, i); +- + /* Status pages for grant table - for version 2 */ + t->status = xzalloc_array(grant_status_t *, + grant_to_status_frames(max_nr_grant_frames)); + if ( t->status == NULL ) + goto no_mem_4; ++ ++ for ( i = 0; i < INITIAL_NR_GRANT_FRAMES; i++ ) ++ gnttab_create_shared_page(d, t, i); ++ + t->nr_status_frames = 0; + + /* Okay, install the structure. */ |