[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] HVM: sanitize DOMCTL_gethvmcontext_partial handling
commit 38d42c5ecf794a391ea6933b9a93e2fd6ffdfcbe Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Wed Jun 14 11:38:32 2017 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Jun 14 11:38:32 2017 +0200 HVM: sanitize DOMCTL_gethvmcontext_partial handling Have the caller indicate its buffer size, provide a means to query the needed size, don't ignore the upper halves of type code and instance, and don't copy partial data. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- tools/libxc/xc_domain.c | 1 + xen/arch/x86/domctl.c | 6 +++++- xen/common/hvm/save.c | 20 ++++++++++++-------- xen/include/public/domctl.h | 1 + xen/include/xen/hvm/save.h | 4 ++-- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index b1a286e..5d192ea 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -496,6 +496,7 @@ int xc_domain_hvm_getcontext_partial(xc_interface *xch, domctl.domain = (domid_t) domid; domctl.u.hvmcontext_partial.type = typecode; domctl.u.hvmcontext_partial.instance = instance; + domctl.u.hvmcontext_partial.bufsz = size; set_xen_guest_handle(domctl.u.hvmcontext_partial.buffer, ctxt_buf); ret = do_domctl(xch, &domctl); diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index e104be2..f40e989 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -590,8 +590,12 @@ long arch_do_domctl( domain_pause(d); ret = hvm_save_one(d, domctl->u.hvmcontext_partial.type, domctl->u.hvmcontext_partial.instance, - domctl->u.hvmcontext_partial.buffer); + domctl->u.hvmcontext_partial.buffer, + &domctl->u.hvmcontext_partial.bufsz); domain_unpause(d); + + if ( !ret ) + copyback = true; break; case XEN_DOMCTL_set_address_size: diff --git a/xen/common/hvm/save.c b/xen/common/hvm/save.c index 579b2d4..045e5a3 100644 --- a/xen/common/hvm/save.c +++ b/xen/common/hvm/save.c @@ -76,8 +76,8 @@ size_t hvm_save_size(struct domain *d) /* Extract a single instance of a save record, by marshalling all * records of that type and copying out the one we need. */ -int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance, - XEN_GUEST_HANDLE_64(uint8) handle) +int hvm_save_one(struct domain *d, unsigned int typecode, unsigned int instance, + XEN_GUEST_HANDLE_64(uint8) handle, uint64_t *bufsz) { int rv = -ENOENT; size_t sz = 0; @@ -117,16 +117,20 @@ int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance, desc = (void *)(ctxt.data + off); /* Move past header */ off += sizeof(*desc); + if ( ctxt.cur < desc->length || + off > ctxt.cur - desc->length ) + break; if ( instance == desc->instance ) { - uint32_t copy_length = desc->length; - - if ( ctxt.cur < copy_length || - off > ctxt.cur - copy_length ) - copy_length = ctxt.cur - off; rv = 0; - if ( copy_to_guest(handle, ctxt.data + off, copy_length) ) + if ( guest_handle_is_null(handle) ) + *bufsz = desc->length; + else if ( *bufsz < desc->length ) + rv = -ENOBUFS; + else if ( copy_to_guest(handle, ctxt.data + off, desc->length) ) rv = -EFAULT; + else + *bufsz = desc->length; break; } } diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 3f3b3eb..f7cbc0a 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -746,6 +746,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug_op_t); typedef struct xen_domctl_hvmcontext_partial { uint32_t type; /* IN: Type of record required */ uint32_t instance; /* IN: Instance of that type */ + uint64_aligned_t bufsz; /* IN: size of buffer */ XEN_GUEST_HANDLE_64(uint8) buffer; /* OUT: buffer to write record into */ } xen_domctl_hvmcontext_partial_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t); diff --git a/xen/include/xen/hvm/save.h b/xen/include/xen/hvm/save.h index a9a78f9..f889e8f 100644 --- a/xen/include/xen/hvm/save.h +++ b/xen/include/xen/hvm/save.h @@ -132,8 +132,8 @@ __initcall(__hvm_register_##_x##_save_and_restore); /* Entry points for saving and restoring HVM domain state */ size_t hvm_save_size(struct domain *d); int hvm_save(struct domain *d, hvm_domain_context_t *h); -int hvm_save_one(struct domain *d, uint16_t typecode, uint16_t instance, - XEN_GUEST_HANDLE_64(uint8) handle); +int hvm_save_one(struct domain *d, unsigned int typecode, unsigned int instance, + XEN_GUEST_HANDLE_64(uint8) handle, uint64_t *bufsz); int hvm_load(struct domain *d, hvm_domain_context_t *h); /* Arch-specific definitions. */ -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |