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:
Jan Beulich committed 2017-06-14 11:38:32 +02:00
1 parent 6391b22113
commit 38d42c5ecf
5 files changed
+21 -11

No files matched your search

+1
View File
@@ -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);
+5 -1
View File
@@ -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
View File
@@ -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;
}
}
+1
View File
@@ -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);
+2 -2
View File
@@ -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. */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.