[vbox-dev] [Patch] Fix for bug #10947

Konrad Kuźmiński kuzminski.konrad at gmail.com
Tue Nov 12 12:44:42 GMT 2013


Hi,

It looks like gmail silently failed to attach the file and didn't even
notify me about this. I reattached my program in this message. It was
compiled with MASM using attached script and tested under Windows XP SP3
host and guest.

Here's the bat file I used for compilation (I cannot attach such files):
@REM Make sure this path is correct before attempting to build
@set MASM_PATH=C:\masm32
@set PATH=%PATH%;%MASM_PATH%\bin

ml -c -coff -I%MASM_PATH%\include 10947_test.asm
link /ENTRY:start /SUBSYSTEM:CONSOLE /LIBPATH:%MASM_PATH%\lib 10947_test.obj

Regards,
Konrad


2013/11/12 Ramshankar <ramshankar.venkataraman at oracle.com>

> Hi,
>
> You said in the attachment, you have included a testcase, I can't find any
> attachment in your original email. Could you please re-attach it?
>
> Regards,
> Ram.
>
>
> On 11/09/2013 05:01 AM, Ramshankar wrote:
>
>> Hi,
>>
>> Thank you for the patch. I'll take a look at it next week.
>>
>> Regards,
>> Ram.
>>
>> On 08/11/13 22:13, Konrad Kuźmiński wrote:
>>
>>> Hi,
>>>
>>> I've made a fix for this bug https://www.virtualbox.org/ticket/10947.
>>> Mentioned ticket isn't very descriptive so I will try to explain this
>>> issue a little bit more in detail. First of all this problem occurs only
>>> when VT-x is enabled. Basically some instructions don't generate
>>> expected single step exception after they are executed with the trap
>>> flag being set. The behaviour is observed that such instructions are
>>> executed under the control of the guest system but single step exception
>>> is generated after the next instruction. This is a well known bug
>>> amongst malware researchers and malware authors who can easily take
>>> advantage of this fact in order to detect virtualized environment.
>>>
>>> It turns out that the problem lies in the way VirtualBox handles some VM
>>> exits initiated by the execution of certain instructions. Several
>>> instructions can never be executed in VMX non-root operation and those
>>> need to be emulated and skipped within VM exit handlers by adjusting
>>> RIP. Unfortunately the code lacks necessary check for the trap flag
>>> being set, so it doesn't inject expected exception into the guest.
>>>
>>> Here's the fix:
>>> *** src\VBox\VMM\VMMR0\HMVMXR0_original.cpp    2013-11-01
>>> 18:58:26.000000000 +0100
>>> --- src\VBox\VMM\VMMR0\HMVMXR0_fixed.cpp        2013-11-08
>>> 20:24:30.578125000 +0100
>>> ***************
>>> *** 8166,8181 ****
>>> --- 8166,8190 ----
>>>     DECLINLINE(int) hmR0VmxAdvanceGuestRip(PVMCPU pVCpu, PCPUMCTX
>>> pMixedCtx, PVMXTRANSIENT pVmxTransient)
>>>     {
>>>         int rc = hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient);
>>>         rc    |= hmR0VmxSaveGuestRip(pVCpu, pMixedCtx);
>>>         AssertRCReturn(rc, rc);
>>>
>>>         pMixedCtx->rip += pVmxTransient->cbInstr;
>>>         VMCPU_HMCF_SET(pVCpu, HM_CHANGED_GUEST_RIP);
>>> +
>>> +     X86EFLAGS Eflags;
>>> +     rc = VMXReadVmcs32(VMX_VMCS_GUEST_RFLAGS, &Eflags.u32);
>>> +     AssertRCReturn(rc, rc);
>>> +     if (Eflags.Bits.u1TF)
>>> +     {
>>> +         hmR0VmxSetPendingXcptDB(pVCpu, pMixedCtx);
>>> +     }
>>> +
>>>         return rc;
>>>     }
>>>
>>> This fix ensures correct handling of mentioned condition in all 13
>>> affected VM exit handlers: VMX_EXIT_CPUID, VMX_EXIT_RDTSC,
>>> VMX_EXIT_RDTSCP, VMX_EXIT_RDPMC, VMX_EXIT_MOV_CRX, VMX_EXIT_MOV_DRX,
>>> VMX_EXIT_MWAIT, VMX_EXIT_MONITOR, VMX_EXIT_RDMSR, VMX_EXIT_WRMSR,
>>> VMX_EXIT_INVD, VMX_EXIT_INVLPG, VMX_EXIT_WBINVD.
>>>
>>> In the attachment I provided a simple program which can be used to test
>>> this condition on 2 representative instructions: CPUID and RDTSC. I
>>> picked those because they don't require CPL = 0.
>>>
>>> I release this patch and test program under MIT license.
>>>
>>> Best regards,
>>> Konrad
>>>
>>>
>>> _______________________________________________
>>> vbox-dev mailing list
>>> vbox-dev at virtualbox.org
>>> https://www.virtualbox.org/mailman/listinfo/vbox-dev
>>>
>>>
>> _______________________________________________
>> vbox-dev mailing list
>> vbox-dev at virtualbox.org
>> https://www.virtualbox.org/mailman/listinfo/vbox-dev
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.virtualbox.org/pipermail/vbox-dev/attachments/20131112/6e124a2a/attachment.html>
-------------- next part --------------
; Copyright (c) 2013 Konrad Kuźmiński
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.

.686
.model flat, stdcall
option casemap:none
public start

include windows.inc
include kernel32.inc
includelib kernel32.lib

.data
cpuid_ok		db	'CPUID has been executed correctly.', 0AH, 0
cpuid_bugged	db	'Bugged CPUID has been detected!', 0AH, 0
rdtsc_ok		db	'RDTSC has been executed correctly.', 0AH, 0
rdtsc_bugged	db	'Bugged RDTSC has been detected!', 0AH, 0

.code
;this is a simple test case for vbox bug #10947
start:
	assume fs : nothing

	;installing exception handler
	push edi
	push offset handler
	push fs:[0]
	mov fs:[0], esp
	
	xor edi, edi
	xor eax, eax
	pushf
	pop ecx
	or ch, 1	;set the trap flag
	push ecx
	popf
	cpuid		;exception should be generated after this instruction, BEFORE the next one executes
	inc edi		;#DB expected here
	inc edi		;but under VT-x enabled VM it's being delivered here, so EDI=1

	mov edi, 8000H
	pushf
	pop ecx
	or ch, 1
	push ecx
	popf
	rdtsc
	inc edi
	inc edi
	
	;cleanup
    mov eax, [esp]
    mov fs:[0], eax
    add esp, 8
	pop edi
	ret
	
;exception handler itself, uses lower part of edi to check when exception was delivered and notifies the user
handler:
	mov eax, [esp+0CH]
	mov eax, [eax+9CH]	;extract EDI value from the CONTEXT structure
	test eax, 8000H
	jnz check_rdtsc
	
	mov ecx, offset cpuid_ok
	test eax, eax
	jz do_print
	mov ecx, offset cpuid_bugged
	jmp do_print

check_rdtsc:
	mov ecx, offset rdtsc_ok
	test al, al
	jz do_print
	mov ecx, offset rdtsc_bugged

do_print:
	push ecx
	call console_print
	add esp, 4
	xor eax, eax
	ret

;helper function for printing to console, nothing special here
console_print:
	sub esp, 4
	push 0
	lea eax, [esp+4]
	push eax
	mov edx, [esp+10H]
	xor ecx, ecx
@@:
	cmp byte ptr[edx+ecx], 0
	jz @F
	inc ecx
	jmp @B
@@:
	push ecx
	push edx
	push -11
	call GetStdHandle
	push eax
	call WriteConsole
	add esp, 4
	ret
	
END


More information about the vbox-dev mailing list