x86/HVM: prefill partially used variable on emulation paths
authorJan Beulich <jbeulich@suse.com>
Thu, 12 Oct 2017 12:43:26 +0000 (14:43 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 12 Oct 2017 12:43:26 +0000 (14:43 +0200)
Certain handlers ignore the access size (vioapic_write() being the
example this was found with), perhaps leading to subsequent reads
seeing data that wasn't actually written by the guest. For
consistency and extra safety also do this on the read path of
hvm_process_io_intercept(), even if this doesn't directly affect what
guests get to see, as we've supposedly already dealt with read handlers
leaving data completely unitialized.

This is XSA-239.

Reported-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/hvm/emulate.c
xen/arch/x86/hvm/intercept.c

index d4fb37bbf87a8fd9ff64a631b10da19187f11a6f..e924ce07c42228d014e1876b2b198b25b3952ace 100644 (file)
@@ -131,7 +131,7 @@ static int hvmemul_do_io(
         .count = *reps,
         .dir = dir,
         .df = df,
-        .data = data,
+        .data = data_is_addr ? data : 0,
         .data_is_ptr = data_is_addr, /* ioreq_t field name is misleading */
         .state = STATE_IOREQ_READY,
     };
index ef82419bfd27e15d0ee24fda39c3721fe8ca5c89..2bc156df2936de66ee8c5dcbd49d1842cb11da7a 100644 (file)
@@ -127,6 +127,7 @@ int hvm_process_io_intercept(const struct hvm_io_handler *handler,
             addr = (p->type == IOREQ_TYPE_COPY) ?
                    p->addr + step * i :
                    p->addr;
+            data = 0;
             rc = ops->read(handler, addr, p->size, &data);
             if ( rc != X86EMUL_OKAY )
                 break;
@@ -161,6 +162,7 @@ int hvm_process_io_intercept(const struct hvm_io_handler *handler,
         {
             if ( p->data_is_ptr )
             {
+                data = 0;
                 switch ( hvm_copy_from_guest_phys(&data, p->data + step * i,
                                                   p->size) )
                 {