Ring3: Fixed SysCallInstallMultipleProtocolInterfaces.

This commit is contained in:
Mikhail Krichanov 2024-02-08 19:15:55 +03:00
parent 313cf0bfae
commit df7a3fa963
4 changed files with 128 additions and 26 deletions

View File

@ -11,8 +11,6 @@
#include <Protocol/ComponentName.h> #include <Protocol/ComponentName.h>
#include <Protocol/DevicePathUtilities.h> #include <Protocol/DevicePathUtilities.h>
#define MAX_LIST 32
VOID VOID
EFIAPI EFIAPI
DisableSMAP ( DisableSMAP (
@ -25,6 +23,15 @@ EnableSMAP (
VOID VOID
); );
EFI_STATUS
EFIAPI
CallInstallMultipleProtocolInterfaces (
IN EFI_HANDLE *Handle,
IN VOID **ArgList,
IN UINT32 ArgListSize,
IN VOID *Function
);
VOID VOID
EFIAPI EFIAPI
InternalEnterUserImage ( InternalEnterUserImage (
@ -73,7 +80,9 @@ CallBootService (
EFI_HANDLE Argument5; EFI_HANDLE Argument5;
UINT32 Argument6; UINT32 Argument6;
UINT32 Index; UINT32 Index;
UINTN *ArgList[MAX_LIST]; VOID **UserArgList;
VOID *CoreArgList[MAX_LIST];
EFI_HANDLE CoreHandle;
EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding;
@ -92,8 +101,9 @@ CallBootService (
CoreProtocol = &gEfiDevicePathUtilitiesProtocolGuid; CoreProtocol = &gEfiDevicePathUtilitiesProtocolGuid;
MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL);
} else { } else {
CoreProtocol = NULL; DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n"));
MemoryCoreSize = 0; EnableSMAP ();
return EFI_INVALID_PARAMETER;
} }
EnableSMAP (); EnableSMAP ();
@ -129,8 +139,9 @@ CallBootService (
CoreProtocol = &gEfiLoadedImageProtocolGuid; CoreProtocol = &gEfiLoadedImageProtocolGuid;
MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL);
} else { } else {
CoreProtocol = NULL; DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n"));
MemoryCoreSize = 0; EnableSMAP ();
return EFI_INVALID_PARAMETER;
} }
Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; Argument4 = (EFI_HANDLE)UserRsp->Arguments[4];
@ -165,31 +176,34 @@ CallBootService (
// ... // ...
// //
DisableSMAP (); DisableSMAP ();
for (Index = 0; ((VOID *)UserRsp->Arguments[Index] != NULL) && (Index < MAX_LIST); Index += 2) { CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1;
if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiDriverBindingProtocolGuid)) { UserArgList = (VOID **)CoreRbp->Argument2;
ArgList[Index] = (UINTN *)&gEfiDriverBindingProtocolGuid;
for (Index = 0; UserArgList[Index] != NULL; ++Index) {
if (CompareGuid ((EFI_GUID *)UserArgList[Index], &gEfiDriverBindingProtocolGuid)) {
CoreArgList[Index] = (VOID *)&gEfiDriverBindingProtocolGuid;
MemoryCoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); MemoryCoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL);
} else if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiComponentNameProtocolGuid)) { continue;
ArgList[Index] = (UINTN *)&gEfiComponentNameProtocolGuid; } else if (CompareGuid ((EFI_GUID *)UserArgList[Index], &gEfiComponentNameProtocolGuid)) {
CoreArgList[Index] = (VOID *)&gEfiComponentNameProtocolGuid;
MemoryCoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); MemoryCoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL);
} else { continue;
DEBUG ((DEBUG_INFO, "Ring0: Argument %d is not a GUID.\n", Index)); } else if ((Index % 2) == 0) {
DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n"));
EnableSMAP ();
return EFI_INVALID_PARAMETER;
} }
ArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserRsp->Arguments[Index + 1]); CoreArgList[Index] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index]);
} }
EnableSMAP (); EnableSMAP ();
if ((Index == MAX_LIST) && ((VOID *)UserRsp->Arguments[Index] != NULL)) { ASSERT (Index < MAX_LIST);
DEBUG ((DEBUG_ERROR, "Ring0: Too many protocols!\n")); CoreArgList[Index] = NULL;
return EFI_OUT_OF_RESOURCES;
}
ArgList[Index] = NULL; for (Index = 0; CoreArgList[Index] != NULL; Index += 2) {
if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) {
for (Index = 0; ArgList[Index] != NULL; Index += 2) { CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1];
if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) {
CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1];
mUserDriverBindingSupported = CoreDriverBinding->Supported; mUserDriverBindingSupported = CoreDriverBinding->Supported;
mUserDriverBindingStart = CoreDriverBinding->Start; mUserDriverBindingStart = CoreDriverBinding->Start;
@ -201,7 +215,12 @@ CallBootService (
} }
} }
Status = gBS->InstallMultipleProtocolInterfaces ((EFI_HANDLE *)ArgList); Status = CallInstallMultipleProtocolInterfaces (
&CoreHandle,
CoreArgList,
Index + 1,
(VOID *)gBS->InstallMultipleProtocolInterfaces
);
return Status; return Status;

View File

@ -13,6 +13,13 @@ extern ASM_PFX(gCoreSysCallStackTop)
extern ASM_PFX(gRing3CallStackTop) extern ASM_PFX(gRing3CallStackTop)
extern ASM_PFX(gRing3EntryPoint) extern ASM_PFX(gRing3EntryPoint)
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; DisableSMAP (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(DisableSMAP) global ASM_PFX(DisableSMAP)
ASM_PFX(DisableSMAP): ASM_PFX(DisableSMAP):
pushfq pushfq
@ -22,6 +29,13 @@ ASM_PFX(DisableSMAP):
popfq popfq
ret ret
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; EnableSMAP (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(EnableSMAP) global ASM_PFX(EnableSMAP)
ASM_PFX(EnableSMAP): ASM_PFX(EnableSMAP):
pushfq pushfq
@ -31,6 +45,51 @@ ASM_PFX(EnableSMAP):
popfq popfq
ret ret
;------------------------------------------------------------------------------
; EFI_STATUS
; EFIAPI
; CallInstallMultipleProtocolInterfaces (
; IN EFI_HANDLE *Handle,
; IN VOID **ArgList,
; IN UINT32 ArgListSize,
; IN VOID *Function
; );
;------------------------------------------------------------------------------
global ASM_PFX(CallInstallMultipleProtocolInterfaces)
ASM_PFX(CallInstallMultipleProtocolInterfaces):
push r12
; Save funtion input.
mov rax, rdx
mov r10, r8
mov r11, r9
; Prepare registers for call.
mov rdx, [rax]
mov r8, [rax + 8]
mov r9, [rax + 8*2]
; Prepare stack for call.
lea rax, [rax + r10 * 8]
mov r12, r10
copy:
sub rax, 8
push qword [rax]
cmp r10, 0
sub r10, 1
jne copy
push rcx
call r11
; Step over Function arguments.
pop rcx
lea rsp, [rsp + r12 * 8]
pop r12
ret
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; EFI_STATUS ; EFI_STATUS
; EFIAPI ; EFIAPI

View File

@ -2020,6 +2020,8 @@ typedef enum {
SysCallMax SysCallMax
} SYS_CALL_TYPE; } SYS_CALL_TYPE;
#define MAX_LIST 32
/// ///
/// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the /// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the
/// EFI System Table. /// EFI System Table.

View File

@ -564,9 +564,31 @@ Ring3InstallMultipleProtocolInterfaces (
... ...
) )
{ {
VA_LIST Marker;
VOID *Argument;
VOID *ArgList[MAX_LIST];
UINTN Index;
VA_START (Marker, Handle);
for (Index = 0; Index < MAX_LIST; ++Index) {
Argument = VA_ARG (Marker, VOID *);
ArgList[Index] = Argument;
if (Argument == NULL) {
break;
}
}
VA_END (Marker);
if (Index == MAX_LIST) {
DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n"));
return EFI_INVALID_PARAMETER;
}
return SysCall ( return SysCall (
SysCallInstallMultipleProtocolInterfaces, SysCallInstallMultipleProtocolInterfaces,
Handle Handle,
ArgList
); );
} }