Ring3: Added Ring3EntryPoint draft.

This commit is contained in:
Mikhail Krichanov 2024-02-06 18:48:23 +03:00
parent ad33670b08
commit 2392881e22
13 changed files with 256 additions and 52 deletions

View File

@ -228,6 +228,7 @@ typedef struct {
VOID *HiiData; VOID *HiiData;
BOOLEAN IsUserImage; BOOLEAN IsUserImage;
BOOLEAN IsRing3EntryPoint;
} LOADED_IMAGE_PRIVATE_DATA; } LOADED_IMAGE_PRIVATE_DATA;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
@ -2739,13 +2740,15 @@ RemoveImageRecord (
@param[in] ImageOrigin Where File comes from. @param[in] ImageOrigin Where File comes from.
@param[in] LoadedImageDevicePath The loaded image device path protocol @param[in] LoadedImageDevicePath The loaded image device path protocol
@param[out] IsUserImage Whether the loaded image is in user space. @param[out] IsUserImage Whether the loaded image is in user space.
@param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls.
**/ **/
VOID VOID
ProtectUefiImage ( ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin, IN UINT8 ImageOrigin,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT BOOLEAN *IsUserImage OUT BOOLEAN *IsUserImage,
OUT BOOLEAN *IsRing3EntryPoint
); );
/** /**

View File

@ -69,7 +69,7 @@
DxeMain/DxeMain.c DxeMain/DxeMain.c
SysCall/BootServices.c SysCall/BootServices.c
SysCall/SupportedProtocols.h SysCall/SupportedProtocols.h
SysCall/DriverBindingProtocol.c SysCall/SupportedProtocols.c
[Sources.X64] [Sources.X64]
SysCall/X64/CoreBootServices.nasm SysCall/X64/CoreBootServices.nasm

View File

@ -332,7 +332,7 @@ DxeMain (
CoreInitializeMemoryProtection (); CoreInitializeMemoryProtection ();
ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage); ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage, &mCurrentImage->IsRing3EntryPoint);
// //
// Call constructor for all libraries // Call constructor for all libraries

View File

@ -28,6 +28,8 @@ STATIC VOID *mPeCoffEmuProtocolNotifyRegistration;
extern BOOLEAN gBdsStarted; extern BOOLEAN gBdsStarted;
VOID *gCoreSysCallStackTop; VOID *gCoreSysCallStackTop;
VOID *gRing3CallStackTop;
VOID *gRing3EntryPoint;
// //
// This code is needed to build the Image handle for the DXE Core // This code is needed to build the Image handle for the DXE Core
@ -70,7 +72,8 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
NULL, // LoadedImageDevicePath NULL, // LoadedImageDevicePath
EFI_SUCCESS, // LoadImageStatus EFI_SUCCESS, // LoadImageStatus
NULL, // HiiData NULL, // HiiData
FALSE // IsUserImage FALSE, // IsUserImage
FALSE // IsRing3EntryPoint
}; };
// //
// The field is define for Loading modules at fixed address feature to tracker the PEI code // The field is define for Loading modules at fixed address feature to tracker the PEI code
@ -1441,7 +1444,7 @@ CoreLoadImageCommon (
} }
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage); ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage, &Image->IsRing3EntryPoint);
RegisterMemoryProfileImage ( RegisterMemoryProfileImage (
Image->LoadedImageDevicePath, Image->LoadedImageDevicePath,
@ -1718,6 +1721,13 @@ CoreStartImage (
if (!Image->IsUserImage) { if (!Image->IsUserImage) {
Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
} else if (Image->IsRing3EntryPoint) {
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
gRing3EntryPoint = (VOID *)Image->EntryPoint;
Image->Status = EFI_SUCCESS;
} else { } else {
gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes);
ASSERT ((Attributes & EFI_MEMORY_USER) != 0); ASSERT ((Attributes & EFI_MEMORY_USER) != 0);
@ -1753,8 +1763,10 @@ CoreStartImage (
TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
gRing3CallStackTop = TopOfStack;
SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER);
DEBUG ((DEBUG_ERROR, "Core: UserTopOfStack = %p\n", TopOfStack)); DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop));
// //
// Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor()
@ -1780,7 +1792,7 @@ CoreStartImage (
(SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint,
ImageHandle, ImageHandle,
Image->Info.SystemTable, Image->Info.SystemTable,
TopOfStack, gRing3CallStackTop,
(UINT16)RING3_CODE64_SEL, (UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL (UINT16)RING3_DATA64_SEL
); );

View File

@ -170,13 +170,15 @@ IsMemoryProtectionSectionAligned (
@param[in] ImageOrigin Where File comes from. @param[in] ImageOrigin Where File comes from.
@param[in] LoadedImageDevicePath The loaded image device path protocol @param[in] LoadedImageDevicePath The loaded image device path protocol
@param[out] IsUserImage Whether the loaded image is in user space. @param[out] IsUserImage Whether the loaded image is in user space.
@param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls.
**/ **/
VOID VOID
ProtectUefiImage ( ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin, IN UINT8 ImageOrigin,
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext,
OUT BOOLEAN *IsUserImage OUT BOOLEAN *IsUserImage,
OUT BOOLEAN *IsRing3EntryPoint
) )
{ {
RETURN_STATUS PdbStatus; RETURN_STATUS PdbStatus;
@ -231,6 +233,8 @@ ProtectUefiImage (
// //
InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link); InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link);
*IsRing3EntryPoint = FALSE;
if (gCpu != NULL) { if (gCpu != NULL) {
// //
// CPU ARCH present. Update memory attribute directly. // CPU ARCH present. Update memory attribute directly.
@ -238,7 +242,11 @@ ProtectUefiImage (
if (AsciiStrStr (PdbPointer, "Ntfs") != NULL) { if (AsciiStrStr (PdbPointer, "Ntfs") != NULL) {
SetUefiImageProtectionAttributes (ImageRecord, TRUE); SetUefiImageProtectionAttributes (ImageRecord, TRUE);
*IsUserImage = TRUE; *IsUserImage = TRUE;
} else { } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) {
SetUefiImageProtectionAttributes (ImageRecord, TRUE);
*IsUserImage = TRUE;
*IsRing3EntryPoint = TRUE;
} else {
SetUefiImageProtectionAttributes (ImageRecord, FALSE); SetUefiImageProtectionAttributes (ImageRecord, FALSE);
*IsUserImage = FALSE; *IsUserImage = FALSE;
} }

View File

@ -191,6 +191,10 @@ CallBootService (
if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) { if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) {
CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1]; CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1];
mUserDriverBindingSupported = CoreDriverBinding->Supported;
mUserDriverBindingStart = CoreDriverBinding->Start;
mUserDriverBindingStop = CoreDriverBinding->Stop;
CoreDriverBinding->Supported = CoreDriverBindingSupported; CoreDriverBinding->Supported = CoreDriverBindingSupported;
CoreDriverBinding->Start = CoreDriverBindingStart; CoreDriverBinding->Start = CoreDriverBindingStart;
CoreDriverBinding->Stop = CoreDriverBindingStop; CoreDriverBinding->Stop = CoreDriverBindingStop;

View File

@ -1,42 +0,0 @@
/** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include "DxeMain.h"
EFI_STATUS
EFIAPI
CoreDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
CoreDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return EFI_UNSUPPORTED;
}
EFI_STATUS
EFIAPI
CoreDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
return EFI_UNSUPPORTED;
}

View File

@ -0,0 +1,18 @@
/** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include <Uefi.h>
EFI_STATUS
EFIAPI
Ring3EntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EFI_SUCCESS;
}

View File

@ -0,0 +1,42 @@
## @file
#
# Ring3 driver for SysCalls.
#
# Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
# SPDX-License-Identifier: BSD-3-Clause
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = Ring3Dxe
FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = Ring3EntryPoint
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
Ring3Dxe.c
[Sources.X64]
X64/Ring3Dxe.nasm
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
BaseLib
DebugLib
[Protocols]
[Guids]
[Depex]
TRUE

View File

@ -0,0 +1,88 @@
/** @file
Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include "DxeMain.h"
EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported;
EFI_DRIVER_BINDING_START mUserDriverBindingStart;
EFI_DRIVER_BINDING_STOP mUserDriverBindingStop;
typedef enum {
UserDriverBindingSupported = 1,
UserDriverBindingStart = 2,
UserDriverBindingStop = 3,
UserCallMax
} USER_CALL_TYPE;
EFI_STATUS
EFIAPI
CallRing3 (
IN UINT8 Type,
IN UINT16 CodeSelector,
IN UINT16 DataSelector,
IN VOID *FunctionAddress,
...
);
EFI_STATUS
EFIAPI
CoreDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return CallRing3 (
UserDriverBindingSupported,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL,
(VOID *)mUserDriverBindingSupported,
This,
ControllerHandle,
RemainingDevicePath
);
}
EFI_STATUS
EFIAPI
CoreDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
)
{
return CallRing3 (
UserDriverBindingStart,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL,
(VOID *)mUserDriverBindingStart,
This,
ControllerHandle,
RemainingDevicePath
);
}
EFI_STATUS
EFIAPI
CoreDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
)
{
return CallRing3 (
UserDriverBindingStop,
(UINT16)RING3_CODE64_SEL,
(UINT16)RING3_DATA64_SEL,
(VOID *)mUserDriverBindingStop,
This,
ControllerHandle,
NumberOfChildren,
ChildHandleBuffer
);
}

View File

@ -5,6 +5,10 @@
**/ **/
extern EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported;
extern EFI_DRIVER_BINDING_START mUserDriverBindingStart;
extern EFI_DRIVER_BINDING_STOP mUserDriverBindingStop;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CoreDriverBindingSupported ( CoreDriverBindingSupported (
@ -12,7 +16,7 @@ CoreDriverBindingSupported (
IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
); );
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
CoreDriverBindingStart ( CoreDriverBindingStart (

View File

@ -10,6 +10,8 @@ SECTION .text
extern ASM_PFX(CallBootService) extern ASM_PFX(CallBootService)
extern ASM_PFX(gCoreSysCallStackTop) extern ASM_PFX(gCoreSysCallStackTop)
extern ASM_PFX(gRing3CallStackTop)
extern ASM_PFX(gRing3EntryPoint)
global ASM_PFX(DisableSMAP) global ASM_PFX(DisableSMAP)
ASM_PFX(DisableSMAP): ASM_PFX(DisableSMAP):
@ -151,3 +153,47 @@ ASM_PFX(InternalEnterUserImage):
; Pass control to user image ; Pass control to user image
retfq retfq
;------------------------------------------------------------------------------
; EFI_STATUS
; EFIAPI
; CallRing3 (
; IN UINT8 Type,
; IN UINT16 CodeSelector,
; IN UINT16 DataSelector,
; IN VOID *FunctionAddress,
; ...
; );
;
; (rcx) Type.
; (rdx) CodeSelector - Segment selector for code.
; (r8) DataSelector - Segment selector for data.
; (r9) FunctionAddress
;
; (On User Stack) Argument 1, 2, 3, ...
;------------------------------------------------------------------------------
global ASM_PFX(CallRing3)
ASM_PFX(CallRing3):
; Set Data selectors
or r8, 3H ; RPL = 3
o16 mov ds, r8
o16 mov es, r8
o16 mov fs, r8
o16 mov gs, r8
; Save Code selector
or rdx, 3H ; RPL = 3
; Prepare stack before swithcing
push r8 ; ss
push qword [gRing3CallStackTop] ; rsp
push rdx ; cs
push qword [gRing3EntryPoint] ; rip
; Copy Arguments from Core Stack to User Stack + return address
; Pass control to User driver function.
retfq
coreReturnAddress:
ret

View File

@ -0,0 +1,21 @@
;------------------------------------------------------------------------------
;
; Copyright (c) 2024, Mikhail Krichanov. All rights reserved.
; SPDX-License-Identifier: BSD-3-Clause
;
;------------------------------------------------------------------------------
DEFAULT REL
SECTION .text
;------------------------------------------------------------------------------
; EFI_STATUS
; EFIAPI
; _ModuleEntryPoint (
; IN EFI_HANDLE ImageHandle,
; IN EFI_SYSTEM_TABLE *SystemTable
; )
;------------------------------------------------------------------------------
global ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
ret