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=6…
==============================================================================
--- 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=…
==============================================================================
--- 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);