i386: Stopped IOPL from being changed by IRET when CPL is zero.

This commit is contained in:
mahlemiut 2012-01-23 08:04:00 +00:00
parent b5c66b9930
commit 1174a05034

View File

@ -2389,6 +2389,11 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
FAULT(FAULT_GP,0);
}
*/
if(CPL != 0)
{
UINT32 oldflags = get_flags(cpustate);
newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
}
set_flags(cpustate,newflags);
cpustate->eip = POP32(cpustate) & 0xffff; // high 16 bits are ignored
cpustate->sreg[CS].selector = POP32(cpustate) & 0xffff;
@ -2513,7 +2518,14 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
if(newEIP > desc.limit)
{
logerror("IRET: Return EIP is past return CS limit.\n");
FAULT(FAULT_GP,0) }
FAULT(FAULT_GP,0)
}
if(CPL != 0)
{
UINT32 oldflags = get_flags(cpustate);
newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
}
if(operand32 == 0)
{
@ -2668,6 +2680,13 @@ static void i386_protected_mode_iret(i386_state* cpustate, int operand32)
// else
// REG32(ESP) += 20;
// IOPL can only change if CPL is zero
if(CPL != 0)
{
UINT32 oldflags = get_flags(cpustate);
newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
}
if(operand32 == 0)
{
cpustate->eip = newEIP & 0xffff;