mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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@suse.com> Acked-by: Wei Liu <wei.liu2@citrix.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
6391b22113
commit
38d42c5ecf
5 files changed
+21
-11
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
+12
-8
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||