Author: aandrejevic Date: Thu Oct 1 02:24:17 2015 New Revision: 69424
URL: http://svn.reactos.org/svn/reactos?rev=69424&view=rev Log: [FAST486] Fix the TSS limit validity check. Implement I/O privilege checking.
Modified: trunk/reactos/lib/fast486/common.c trunk/reactos/lib/fast486/common.inl trunk/reactos/lib/fast486/opcodes.c
Modified: trunk/reactos/lib/fast486/common.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=69... ============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Thu Oct 1 02:24:17 2015 @@ -628,8 +628,8 @@ PFAST486_LEGACY_TSS NewLegacyTss = (PFAST486_LEGACY_TSS)&NewTss; USHORT NewLdtr, NewEs, NewCs, NewSs, NewDs;
- if (State->TaskReg.Limit < (sizeof(FAST486_TSS) - 1) - && State->TaskReg.Limit != (sizeof(FAST486_LEGACY_TSS) - 1)) + if ((State->TaskReg.Modern && State->TaskReg.Limit < (sizeof(FAST486_TSS) - 1)) + || (!State->TaskReg.Modern && State->TaskReg.Limit < (sizeof(FAST486_LEGACY_TSS) - 1))) { /* Invalid task register limit */ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, State->TaskReg.Selector); @@ -882,6 +882,7 @@ State->TaskReg.Selector = Selector; State->TaskReg.Base = NewTssAddress; State->TaskReg.Limit = NewTssLimit; + State->TaskReg.Modern = (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE);
if (NewTssDescriptor.Signature == FAST486_BUSY_TSS_SIGNATURE) {
Modified: trunk/reactos/lib/fast486/common.inl URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev=... ============================================================================== --- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Thu Oct 1 02:24:17 2015 @@ -1599,6 +1599,54 @@ return TRUE; }
+FORCEINLINE +BOOLEAN +FASTCALL +Fast486IoPrivilegeCheck(PFAST486_STATE State, USHORT Port) +{ + UCHAR Bits; + ULONG Location; + FAST486_TSS Tss; + + /* Access is always allowed if the CPL is less than or equal to the IOPL */ + if (State->Cpl <= State->Flags.Iopl) return TRUE; + + /* Legacy Task State Segments have no IOPB */ + if (!State->TaskReg.Modern) return FALSE; + + /* Read the TSS */ + if (!Fast486ReadLinearMemory(State, State->TaskReg.Base, &Tss, sizeof(FAST486_TSS), FALSE)) + { + /* Exception occurred */ + return FALSE; + } + + Location = State->TaskReg.Base + HIWORD(Tss.IopbOffset) + (Port >> 3); + + if (Location > State->TaskReg.Limit) + { + /* Access denied */ + Fast486Exception(State, FAST486_EXCEPTION_GP); + return FALSE; + } + + /* Read the appropriate bit from the TSS IOPB */ + if (!Fast486ReadLinearMemory(State, Location, &Bits, sizeof(UCHAR), FALSE)) + { + /* Exception occurred */ + return FALSE; + } + + if (Bits & (1 << (Port & 0x07))) + { + /* Access denied */ + Fast486Exception(State, FAST486_EXCEPTION_GP); + return FALSE; + } + + return TRUE; +} + #ifndef FAST486_NO_FPU
FORCEINLINE
Modified: trunk/reactos/lib/fast486/opcodes.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=6... ============================================================================== --- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Thu Oct 1 02:24:17 2015 @@ -790,6 +790,8 @@ Port = State->GeneralRegs[FAST486_REG_EDX].LowWord; }
+ if (!Fast486IoPrivilegeCheck(State, Port)) return; + /* Read a byte from the I/O port */ State->IoReadCallback(State, Port, &Data, 1, sizeof(UCHAR));
@@ -828,6 +830,8 @@ Port = State->GeneralRegs[FAST486_REG_EDX].LowWord; }
+ if (!Fast486IoPrivilegeCheck(State, Port)) return; + if (Size) { ULONG Data; @@ -876,6 +880,8 @@ Port = State->GeneralRegs[FAST486_REG_EDX].LowWord; }
+ if (!Fast486IoPrivilegeCheck(State, Port)) return; + /* Read the value from AL */ Data = State->GeneralRegs[FAST486_REG_EAX].LowByte;
@@ -913,6 +919,8 @@ /* The port number is in DX */ Port = State->GeneralRegs[FAST486_REG_EDX].LowWord; } + + if (!Fast486IoPrivilegeCheck(State, Port)) return;
if (Size) { @@ -5836,6 +5844,8 @@ TOGGLE_OPSIZE(OperandSize); TOGGLE_ADSIZE(AddressSize);
+ if (!Fast486IoPrivilegeCheck(State, State->GeneralRegs[FAST486_REG_EDX].LowWord)) return; + /* Calculate the size */ if (Opcode == 0x6C) DataSize = sizeof(UCHAR); else DataSize = OperandSize ? sizeof(ULONG) : sizeof(USHORT); @@ -5973,6 +5983,8 @@
TOGGLE_OPSIZE(OperandSize); TOGGLE_ADSIZE(AddressSize); + + if (!Fast486IoPrivilegeCheck(State, State->GeneralRegs[FAST486_REG_EDX].LowWord)) return;
/* Calculate the size */ if (Opcode == 0x6E) DataSize = sizeof(UCHAR);