[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

 


Rackspace

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