[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 1/2] 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>
---
v2: Re-base.

--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -496,6 +496,7 @@ int xc_domain_hvm_getcontext_partial(xc_
     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);
--- 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:
--- 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, uint1
             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;
             }
         }
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -746,6 +746,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug
 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);
--- a/xen/include/xen/hvm/save.h
+++ b/xen/include/xen/hvm/save.h
@@ -132,8 +132,8 @@ __initcall(__hvm_register_##_x##_save_an
 /* 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. */


Attachment: HVM-save-one-inputs.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.