aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-02-03 09:46:01 +0000
committerKeir Fraser <keir.fraser@citrix.com>2010-02-03 09:46:01 +0000
commitafe765651db2e8f99af74bb8da2a29ee5d923aa6 (patch)
treee9fb394a900ad8e591d21cadde5a48571208a514 /tools/libxc
parent91e172bf6bc82d0f26564d545ef181d0d18ae1af (diff)
downloadxen-afe765651db2e8f99af74bb8da2a29ee5d923aa6.tar.gz
xen-afe765651db2e8f99af74bb8da2a29ee5d923aa6.tar.bz2
xen-afe765651db2e8f99af74bb8da2a29ee5d923aa6.zip
libxc: Check there's enough memory for segments we're creating
Previously, xc_dom_alloc_segment would go ahead even if the segment we're trying to create is too big for the domain's RAM (or the requested addr is out of range). It would pass invalid parameters to xc_dom_seg_to_ptr giving undefined behaviour. Fixing xc_dom_seg_to_ptr to fail is not sufficient because we want to provide a comprehensible explanation to the caller - which may ultimately be the user. In particular, with this change attempting "xl create" with a ramdisk image bigger than the guest's specified RAM will provide a useful error message mentioning the ramdisk. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxc')
-rw-r--r--tools/libxc/xc_dom_core.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index 23c655efb3..df8e83b6ba 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -409,8 +409,19 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
}
seg->vstart = start;
- seg->vend = start + pages * page_size;
seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size;
+
+ if ( pages > dom->total_pages || /* double test avoids overflow probs */
+ pages > dom->total_pages - seg->pfn)
+ {
+ xc_dom_panic(XC_OUT_OF_MEMORY,
+ "%s: segment %s too large (0x%"PRIpfn" > "
+ "0x%"PRIpfn" - 0x%"PRIpfn" pages)\n",
+ __FUNCTION__, name, pages, dom->total_pages, seg->pfn);
+ return -1;
+ }
+
+ seg->vend = start + pages * page_size;
dom->virt_alloc_end = seg->vend;
if (dom->allocate)
dom->allocate(dom, dom->virt_alloc_end);