$NetBSD: patch-CVE-2013-4355_2,v 1.1 2013/10/01 14:54:44 drochner Exp $ --- xen/arch/x86/hvm/intercept.c.orig 2013-09-10 06:42:18.000000000 +0000 +++ xen/arch/x86/hvm/intercept.c 2013-09-30 15:23:07.000000000 +0000 @@ -93,17 +93,28 @@ static int hvm_mmio_access(struct vcpu * { for ( i = 0; i < p->count; i++ ) { - int ret; - - ret = hvm_copy_from_guest_phys(&data, - p->data + (sign * i * p->size), - p->size); - if ( (ret == HVMCOPY_gfn_paged_out) || - (ret == HVMCOPY_gfn_shared) ) + switch ( hvm_copy_from_guest_phys(&data, + p->data + sign * i * p->size, + p->size) ) { + case HVMCOPY_okay: + break; + case HVMCOPY_gfn_paged_out: + case HVMCOPY_gfn_shared: rc = X86EMUL_RETRY; break; + case HVMCOPY_bad_gfn_to_mfn: + data = ~0; + break; + case HVMCOPY_bad_gva_to_gfn: + ASSERT(0); + /* fall through */ + default: + rc = X86EMUL_UNHANDLEABLE; + break; } + if ( rc != X86EMUL_OKAY ) + break; rc = write_handler(v, p->addr + (sign * i * p->size), p->size, data); if ( rc != X86EMUL_OKAY ) @@ -171,8 +182,28 @@ static int process_portio_intercept(port for ( i = 0; i < p->count; i++ ) { data = 0; - (void)hvm_copy_from_guest_phys(&data, p->data + sign*i*p->size, - p->size); + switch ( hvm_copy_from_guest_phys(&data, + p->data + sign * i * p->size, + p->size) ) + { + case HVMCOPY_okay: + break; + case HVMCOPY_gfn_paged_out: + case HVMCOPY_gfn_shared: + rc = X86EMUL_RETRY; + break; + case HVMCOPY_bad_gfn_to_mfn: + data = ~0; + break; + case HVMCOPY_bad_gva_to_gfn: + ASSERT(0); + /* fall through */ + default: + rc = X86EMUL_UNHANDLEABLE; + break; + } + if ( rc != X86EMUL_OKAY ) + break; rc = action(IOREQ_WRITE, p->addr, p->size, &data); if ( rc != X86EMUL_OKAY ) break;