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;
BOOLEAN IsUserImage;
BOOLEAN IsRing3EntryPoint;
} LOADED_IMAGE_PRIVATE_DATA;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
@ -2739,13 +2740,15 @@ RemoveImageRecord (
@param[in] ImageOrigin Where File comes from.
@param[in] LoadedImageDevicePath The loaded image device path protocol
@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
ProtectUefiImage (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN UINT8 ImageOrigin,
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
SysCall/BootServices.c
SysCall/SupportedProtocols.h
SysCall/DriverBindingProtocol.c
SysCall/SupportedProtocols.c
[Sources.X64]
SysCall/X64/CoreBootServices.nasm

View File

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

View File

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

View File

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

View File

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

View File

@ -10,6 +10,8 @@ SECTION .text
extern ASM_PFX(CallBootService)
extern ASM_PFX(gCoreSysCallStackTop)
extern ASM_PFX(gRing3CallStackTop)
extern ASM_PFX(gRing3EntryPoint)
global ASM_PFX(DisableSMAP)
ASM_PFX(DisableSMAP):
@ -151,3 +153,47 @@ ASM_PFX(InternalEnterUserImage):
; Pass control to user image
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