From 5b281e2c16d79aba8f97a060e98d24b7b84ab84a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 5 Mar 2024 20:01:19 +0300 Subject: [PATCH] Ring3: Forbade Ring3 accsess to all ports but for UART to allow DEBUG printing. --- MdeModulePkg/Core/Dxe/Image/Image.c | 4 ---- .../X64/ArchExceptionHandler.c | 23 +++++++++++++++++-- .../X64/ArchInterruptDefs.h | 6 ++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 51c8edc820..170fbf08bc 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1645,10 +1645,6 @@ InitializeRing3 ( Eflags.UintN = AsmReadEflags (); Eflags.Bits.AC = 0; - // - // Allow user image to access ports. - // - Eflags.Bits.IOPL = 3; AsmWriteEflags (Eflags.UintN); // // Enable SYSCALL and SYSRET. diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 4e85880ed4..76a51e28d0 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -139,6 +139,7 @@ ArchSetupExceptionStack ( UINTN TssBase; UINT8 *StackSwitchExceptions; UINTN NeedBufferSize; + UINT8 *IOBitMap; if (BufferSize == NULL) { return EFI_INVALID_PARAMETER; @@ -210,12 +211,12 @@ ArchSetupExceptionStack ( TssDesc->Uint128.Uint64 = 0; TssDesc->Uint128.Uint64_1 = 0; - TssDesc->Bits.LimitLow = sizeof (IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.LimitLow = (UINT16)(CPU_TSS_SIZE - 1); TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; TssDesc->Bits.P = 1; - TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 1) >> 16; TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24); TssDesc->Bits.BaseHigh = (UINT32)(TssBase >> 32); @@ -254,6 +255,24 @@ ArchSetupExceptionStack ( // AsmWriteGdtr (&Gdtr); + // + // Set I/O Permission Bit Map + // + Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); + for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { + if ((Index * 8) == 0x3F8) { + *IOBitMap = 0x84; + } else { + *IOBitMap = 0xFF; + } + + ++IOBitMap; + } + // // Load current task // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h index 008670cb0d..39f19f3b3b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h @@ -38,6 +38,10 @@ typedef struct { } RESERVED_VECTORS_DATA; #define CPU_TSS_DESC_SIZE sizeof (IA32_TSS_DESCRIPTOR) -#define CPU_TSS_SIZE sizeof (IA32_TASK_STATE_SEGMENT) +// +// 0x81 is needed to allow Ring3 code access to Uart in I/O Permission Bit Map. +// +#define IO_BIT_MAP_SIZE 0x81 +#define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE) #endif