VirtualBox

Opened 6 years ago

Closed 5 years ago

#17316 closed defect (fixed)

Wrong instruction after single-step exception with 'rdtsc' -> fixed in 6.0

Reported by: gim Owned by:
Component: VMM Version: VirtualBox 5.1.30
Keywords: rdtsc, tf Cc:
Guest type: Windows Host type: Linux

Description (last modified by janitor)

There was bug 5 years ago (#10947) and was fixed, but in current release still appears. Here slightly modified code with looping 1000000 times around RDTSC call with charged TF. If at least one call does not work correctly, a corresponding message is displayed:

      .586
      .model flat, stdcall
      option casemap :none   ; case sensitive

      include \masm32\include\windows.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\user32.inc
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\user32.lib
     
.data
Flag	dd 0
Address dd 0
Counter dd 0
szRight	db 'Flag Value is right!, address = 0x%lx, counter = %ld',0
szWrong	db 'Flag Value is wrong!, address = 0x%lx, counter = %ld',0
szMessage db 256 dup(0)
    
szInfo	db 'Info:'

.code
start:
	assume fs: nothing
test_loop:
	call @MyCode
	mov     ecx, dword ptr [esp+0Ch]
	mov 	ecx, dword ptr [ecx+0B8h]	;;Ecx = Seh.eip
        mov     Address, ecx
	.if ecx == offset @WrongExceptionEip
		mov Flag,0
	.else
		mov Flag,1
	.endif
	xor     eax, eax
	retn
	@MyCode:
	push    dword ptr fs:[0]
	mov     dword ptr fs:[0], esp
	push 397h             ;;Set Eflags
	popfd
	rdtsc
	@RightExceptionEip:		;;Normally,Seh.eip should be pointed here
	nop
	@WrongExceptionEip:		;;In Guest system,('Without' VT-X/AMD-V),Seh.eip is pointed here.But 'With' VT-X/AMD-V,Seh.eip is right.
        cmp Flag, 1
        jnz flag_wrong
        pop eax
        pop fs:[0]
        inc Counter
        cmp Counter, 1000000
        jnz test_loop
        invoke wsprintf,offset szMessage, offset szRight, Address, Counter
        jmp exit
flag_wrong:
        invoke wsprintf,offset szMessage, offset szWrong, Address, Counter
exit:
        invoke MessageBoxA,0,offset szMessage,offset szInfo,MB_OK
	invoke ExitProcess,0
end start

(compiled sample attached rdtsc.exe)

For example, in the real world, this misbehavior is used by the vmprotect to detect a virtual machine. I hope there is no good program crashing because of this misbehavior...

Attachments (5)

rdtsc.exe (2.5 KB ) - added by gim 6 years ago.
compiled asm code
VBox.log (73.2 KB ) - added by gim 6 years ago.
VirtualBox_IE11 - Win7_1_14_03_2018_09_53_38.png (91.9 KB ) - added by gim 6 years ago.
pending_fix.patch (1.8 KB ) - added by gim 5 years ago.
vmx_singlestep_001.diff (13.8 KB ) - added by Ramshankar Venkataraman 5 years ago.
Single-step patch to VirtualBox r127059

Download all attachments as: .zip

Change History (16)

by gim, 6 years ago

Attachment: rdtsc.exe added

compiled asm code

comment:1 by gim, 6 years ago

And this problem appears with VT-X/AMD-V too on any Windows OS

comment:2 by gim, 6 years ago

up

comment:3 by michaln, 6 years ago

Please provide a VBox.log from a VM showing the problem. It would not hurt to specify what "any" Windows OS is either. Windows 3.1? Windows 95? Windows 10 64-bit?

by gim, 6 years ago

Attachment: VBox.log added

comment:4 by gim, 6 years ago

I've attached VBox.log and proof screenshot. But I believe that you could not find any usefully info inside VBox.log without enabling R0-logging or at least some VBOX RELEASE LOGGING flags. The problem probably lies somewhere deeply in VMM.

About OSes. We can confirm for Linux/Windows hosts with Windows XP, Windows 7 and Windows 10 guests for sure with latest VirtualBox 5.2.8. For others OSes we can't confirm, but you can check by self, I think it will reproduce.

Last edited 6 years ago by gim (previous) (diff)

comment:5 by gim, 6 years ago

up

comment:6 by gim, 6 years ago

up

comment:7 by janitor, 6 years ago

Description: modified (diff)

comment:8 by janitor, 6 years ago

See also #17961.

by gim, 5 years ago

Attachment: pending_fix.patch added

comment:9 by gim, 5 years ago

Well, we have been able to understand a little essence of the problem. The problem happens only when between "rdtsc vmexit handler" and "single step exception handler" on this instruction one more another interrupt was received (pended). We think this is because BS flag in VMCS clears during processing these last interrupt (probably because of some "27.3.4 Intel 64 and IA-32 Architectures Software Developers Manual Volume 3C: Part3" reasons) and single step exception will occur only on next instruction (so one instruction was skipped).

We’ve added single step interruption event pending and this solve the problem. Accordingly 32.2.1 "Intel 64 and IA-32 Architectures Software Developers Manual Volume 3C: Part3" it is possible to do so.

pending_fix.patch with this code attached

comment:10 by Ramshankar Venkataraman, 5 years ago

Thanks for the patch and the testcases.

Unfortunately, your patch does not take into account the case where we single-step using EFLAGS.TF using the hypervisor debugger.

Also, the problem was not about an interrupt pending with RDTSC, it was simply RDTSC interception (which is dynamic) combined with single-stepping in the guest. When RDTSC was not intercepted by VirtualBox, it should work 100% of the time. Without Hyper-V/KVM paravirtualization interface in effect, we would be intercepting RDTSCs occasionally and only in those instances would it hit this issue.

I've implemented a more comprehensive fix which also makes your testcase work. The fix will be included in the upcoming release of VirtualBox 6.0.

I will try provide a test build shortly for you early next week.

In the mean time if you'd like the patch (probably only applies cleanly to the very latest VirtualBox OSE trunk and not 5.2.x branch), I've attached it to this ticket (vmx_singlestep_001.diff).

Last edited 5 years ago by Ramshankar Venkataraman (previous) (diff)

by Ramshankar Venkataraman, 5 years ago

Attachment: vmx_singlestep_001.diff added

Single-step patch to VirtualBox r127059

comment:11 by Michael Thayer, 5 years ago

Resolution: fixed
Status: newclosed
Summary: Wrong instruction after single-step exception with 'rdtsc'Wrong instruction after single-step exception with 'rdtsc' -> fixed in 6.0
Note: See TracTickets for help on using tickets.

© 2023 Oracle
ContactPrivacy policyTerms of Use