From adcb9bd1753c355beff0779d3a43deb5a6240081 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 3 Feb 2018 15:52:31 -0800 Subject: [PATCH] [ROSLOAD]: Begin target preparation code. 1/104. [ROSLOAD]: Stubs for OslFatalErrorEx, OslAbortBoot. OslpSanitizeLoadOptionsString, OslpSanitizeStringOptions [ROSLOAD]: Implement OslBlStatusErrorHandler, OslpRemoveInternalApplicationOptions [ROSLOAD]: Begin work on OslPrepareTarget. Small misc. fixes. [BOOTLIB]: Extend BlStatusError to handle a custom status error handler. --- boot/environ/app/rosload/rosload.c | 291 ++++++++++++++++++++++++++++- boot/environ/include/bl.h | 16 +- boot/environ/lib/misc/debug.c | 31 +++ boot/environ/lib/misc/image.c | 6 +- boot/environ/lib/mm/pagealloc.c | 2 +- 5 files changed, 334 insertions(+), 12 deletions(-) diff --git a/boot/environ/app/rosload/rosload.c b/boot/environ/app/rosload/rosload.c index 67568f5289b..65ec28b2bf7 100644 --- a/boot/environ/app/rosload/rosload.c +++ b/boot/environ/app/rosload/rosload.c @@ -18,7 +18,7 @@ OslArchTransferToKernel ( /* DATA VARIABLES ************************************************************/ -LOADER_PARAMETER_BLOCK OslLoaderBlock; +PLOADER_PARAMETER_BLOCK OslLoaderBlock; PVOID OslEntryPoint; PVOID UserSharedAddress; ULONGLONG ArchXCr0BitsToClear; @@ -27,15 +27,296 @@ BOOLEAN BdDebugAfterExitBootServices; KDESCRIPTOR OslKernelGdt; KDESCRIPTOR OslKernelIdt; +ULONG_PTR OslImcHiveHandle; +ULONG_PTR OslMachineHiveHandle; +ULONG_PTR OslElamHiveHandle; +ULONG_PTR OslSystemHiveHandle; + +PBL_DEVICE_DESCRIPTOR OslLoadDevice; +PCHAR OslLoadOptions; +PWCHAR OslSystemRoot; + +LIST_ENTRY OslFreeMemoryDesctiptorsList; +LIST_ENTRY OslFinalMemoryMap; +LIST_ENTRY OslCoreExtensionSubGroups[2]; +LIST_ENTRY OslLoadedFirmwareDriverList; + +BL_BUFFER_DESCRIPTOR OslFinalMemoryMapDescriptorsBuffer; + +GUID OslApplicationIdentifier; + +ULONG OslResetBootStatus; +BOOLEAN OslImcProcessingValid; +ULONG OslFreeMemoryDesctiptorsListSize; +PVOID OslMemoryDescriptorBuffer; + /* FUNCTIONS *****************************************************************/ +VOID +OslFatalErrorEx ( + _In_ ULONG ErrorCode, + _In_ ULONG Parameter1, + _In_ ULONG_PTR Parameter2, + _In_ ULONG_PTR Parameter3 + ) +{ + /* For now just do this */ + BlStatusPrint(L"FATAL ERROR IN ROSLOAD: %lx\n", ErrorCode); +} + +VOID +OslAbortBoot ( + _In_ NTSTATUS Status + ) +{ + /* For now just do this */ + BlStatusPrint(L"BOOT ABORTED: %lx\n", Status); +} + +NTSTATUS +OslBlStatusErrorHandler ( + _In_ ULONG ErrorCode, + _In_ ULONG Parameter1, + _In_ ULONG_PTR Parameter2, + _In_ ULONG_PTR Parameter3, + _In_ ULONG_PTR Parameter4 + ) +{ + /* We only filter error code 4 */ + if (ErrorCode != 4) + { + return STATUS_NOT_IMPLEMENTED; + } + + /* Handle error 4 as a fatal error 3 internally */ + OslFatalErrorEx(3, Parameter1, Parameter2, Parameter3); + return STATUS_SUCCESS; +} + +VOID +OslpSanitizeLoadOptionsString ( + _In_ PWCHAR OptionString, + _In_ PWCHAR SanitizeString + ) +{ + /* TODO */ + return; +} + +VOID +OslpSanitizeStringOptions ( + _In_ PBL_BCD_OPTION BcdOptions + ) +{ + /* TODO */ + return; +} + +NTSTATUS +OslpRemoveInternalApplicationOptions ( + VOID + ) +{ + PWCHAR LoadString; + NTSTATUS Status; + + /* Assume success */ + Status = STATUS_SUCCESS; + + /* Remove attempts to disable integrity checks or ELAM driver load */ + BlRemoveBootOption(BlpApplicationEntry.BcdData, + BcdLibraryBoolean_DisableIntegrityChecks); + BlRemoveBootOption(BlpApplicationEntry.BcdData, + BcdOSLoaderBoolean_DisableElamDrivers); + + /* Get the command-line parameters, if any */ + Status = BlGetBootOptionString(BlpApplicationEntry.BcdData, + BcdLibraryString_LoadOptionsString, + &LoadString); + if (NT_SUCCESS(Status)) + { + /* Conver to upper case */ + _wcsupr(LoadString); + + /* Remove the existing one */ + //BlRemoveBootOption(BlpApplicationEntry.BcdData, + // BcdLibraryString_LoadOptionsString); + + /* Sanitize strings we don't want */ + OslpSanitizeLoadOptionsString(LoadString, L"DISABLE_INTEGRITY_CHECKS"); + OslpSanitizeLoadOptionsString(LoadString, L"NOINTEGRITYCHECKS"); + OslpSanitizeLoadOptionsString(LoadString, L"DISABLEELAMDRIVERS"); + + /* Add the sanitized one back */ + //Status = BlAppendBootOptionsString(&BlpApplicationEntry, + // BcdLibraryString_LoadOptionsString, + // LoadString); + + /* Free the original BCD one */ + BlMmFreeHeap(LoadString); + } + + /* One more pass for secure-boot options */ + OslpSanitizeStringOptions(BlpApplicationEntry.BcdData); + + /* All good */ + return Status; +} + NTSTATUS OslPrepareTarget ( _Out_ PULONG ReturnFlags, _Out_ PBOOLEAN Jump ) { - return STATUS_NOT_IMPLEMENTED; + PGUID AppId; + NTSTATUS Status; + PBL_DEVICE_DESCRIPTOR OsDevice; + PWCHAR SystemRoot; + SIZE_T RootLength, RootLengthWithSep; + ULONG i; + ULONG64 StartPerf, EndPerf; + + /* Assume no flags */ + *ReturnFlags = 0; + + /* Make all registry handles invalid */ + OslImcHiveHandle = -1; + OslMachineHiveHandle = -1; + OslElamHiveHandle = -1; + OslSystemHiveHandle = -1; + + /* Initialize memory lists */ + InitializeListHead(&OslFreeMemoryDesctiptorsList); + InitializeListHead(&OslFinalMemoryMap); + InitializeListHead(&OslLoadedFirmwareDriverList); + for (i = 0; i < RTL_NUMBER_OF(OslCoreExtensionSubGroups); i++) + { + InitializeListHead(&OslCoreExtensionSubGroups[i]); + } + + /* Initialize the memory map descriptor buffer */ + RtlZeroMemory(&OslFinalMemoryMapDescriptorsBuffer, + sizeof(OslFinalMemoryMapDescriptorsBuffer)); + + /* Initialize general pointers */ + OslLoadDevice = NULL; + OslLoadOptions = NULL; + OslSystemRoot = NULL; + OslLoaderBlock = NULL; + OslMemoryDescriptorBuffer = NULL; + + /* Initialize general variables */ + OslResetBootStatus = 0; + OslImcProcessingValid = FALSE; + OslFreeMemoryDesctiptorsListSize = 0; + + /* Capture the current TSC */ + StartPerf = BlArchGetPerformanceCounter(); + +#ifdef BL_TPM_SUPPORT + BlpSbdiCurrentApplicationType = 0x10200003; +#endif + + /* Register an error handler */ + BlpStatusErrorHandler = OslBlStatusErrorHandler; + + /* Get the application identifier and save it */ + AppId = BlGetApplicationIdentifier(); + if (AppId) + { + OslApplicationIdentifier = *AppId; + } + + /* Enable tracing */ +#ifdef BL_ETW_SUPPORT + TraceLoggingRegister(&TlgOslBootProviderProv); +#endif + + /* Remove dangerous BCD options */ + Status = OslpRemoveInternalApplicationOptions(); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* Get the OS device */ + Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData, + BcdOSLoaderDevice_OSDevice, + &OsDevice, + 0); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + /* If the OS device is the boot device, use the one provided by bootlib */ + if (OsDevice->DeviceType == BootDevice) + { + OsDevice = BlpBootDevice; + } + + /* Save it as a global for later */ + OslLoadDevice = OsDevice; + + /* Get the system root */ + Status = BlGetBootOptionString(BlpApplicationEntry.BcdData, + BcdOSLoaderString_SystemRoot, + &SystemRoot); + if (!NT_SUCCESS(Status)) + { + goto Quickie; + } + + EfiPrintf(L"System root: %s\r\n", SystemRoot); + + /* Get the system root length and make sure it's slash-terminated */ + RootLength = wcslen(SystemRoot); + if (SystemRoot[RootLength - 1] == OBJ_NAME_PATH_SEPARATOR) + { + /* Perfect, set it */ + OslSystemRoot = SystemRoot; + } + else + { + /* Allocate a new buffer large enough to contain the slash */ + RootLengthWithSep = RootLength + sizeof(OBJ_NAME_PATH_SEPARATOR); + OslSystemRoot = BlMmAllocateHeap(RootLengthWithSep * sizeof(WCHAR)); + if (!OslSystemRoot) + { + /* Bail out if we're out of memory */ + Status = STATUS_NO_MEMORY; + goto Quickie; + } + + /* Make a copy of the path, adding the separator */ + wcscpy(OslSystemRoot, SystemRoot); + wcscat(OslSystemRoot, L"\\"); + + /* Free the original one from the BCD library */ + BlMmFreeHeap(SystemRoot); + } + + Status = STATUS_NOT_IMPLEMENTED; + + /* Printf perf */ + EndPerf = BlArchGetPerformanceCounter(); + EfiPrintf(L"Delta: %lld\r\n", EndPerf - StartPerf); + +Quickie: +#if BL_BITLOCKER_SUPPORT + /* Destroy the RNG/AES library for BitLocker */ + SymCryptRngAesUninstantiate(); +#endif + + /* Abort the boot */ + OslAbortBoot(Status); + + /* This is a failure path, so never do the jump */ + *Jump = FALSE; + + /* Return error code */ + return Status; } NTSTATUS @@ -132,11 +413,11 @@ OslExecuteTransition ( } /* Setup Firmware for Phase 1 */ - Status = OslFwpKernelSetupPhase1(&OslLoaderBlock); + Status = OslFwpKernelSetupPhase1(OslLoaderBlock); if (NT_SUCCESS(Status)) { /* Setup kernel for Phase 2 */ - Status = OslArchKernelSetup(2, &OslLoaderBlock); + Status = OslArchKernelSetup(2, OslLoaderBlock); if (NT_SUCCESS(Status)) { #ifdef BL_KD_SUPPORT @@ -144,7 +425,7 @@ OslExecuteTransition ( BlBdStop(); #endif /* Jump to the kernel entrypoint */ - OslArchTransferToKernel(&OslLoaderBlock, OslEntryPoint); + OslArchTransferToKernel(OslLoaderBlock, OslEntryPoint); /* Infinite loop if we got here */ for (;;); diff --git a/boot/environ/include/bl.h b/boot/environ/include/bl.h index 40d11895c2c..0e31deb8e92 100644 --- a/boot/environ/include/bl.h +++ b/boot/environ/include/bl.h @@ -742,6 +742,15 @@ typedef BOOLEAN _Out_opt_ PULONG CacheAttributes ); +typedef NTSTATUS +(*PBL_STATUS_ERROR_HANDLER) ( + _In_ ULONG ErrorCode, + _In_ ULONG Parameter1, + _In_ ULONG_PTR Parameter2, + _In_ ULONG_PTR Parameter3, + _In_ ULONG_PTR Parameter4 + ); + /* DATA STRUCTURES ***********************************************************/ typedef struct _BL_LIBRARY_PARAMETERS @@ -1277,12 +1286,12 @@ typedef struct _BL_IMAGE_APPLICATION_ENTRY ULONG ImageSize; } BL_IMAGE_APPLICATION_ENTRY, *PBL_IMAGE_APPLICATION_ENTRY; -typedef struct _BL_IMAGE_PARAMETERS +typedef struct _BL_BUFFER_DESCRIPTOR { PVOID Buffer; ULONG ActualSize; ULONG BufferSize; -} BL_IMAGE_PARAMETERS, *PBL_IMAGE_PARAMETERS; +} BL_BUFFER_DESCRIPTOR, *PBL_BUFFER_DESCRIPTOR; typedef struct _BL_DEFERRED_FONT_FILE { @@ -2287,7 +2296,7 @@ BlMmRemoveBadMemory ( NTSTATUS BlMmGetMemoryMap ( _In_ PLIST_ENTRY MemoryMap, - _In_ PBL_IMAGE_PARAMETERS MemoryParameters, + _In_ PBL_BUFFER_DESCRIPTOR MemoryParameters, _In_ ULONG WhichTypes, _In_ ULONG Flags ); @@ -2831,5 +2840,6 @@ extern PBL_MM_RELOCATE_SELF_MAP BlMmRelocateSelfMap; extern PBL_MM_FLUSH_TLB BlMmFlushTlb; extern PBL_MM_MOVE_VIRTUAL_ADDRESS_RANGE BlMmMoveVirtualAddressRange; extern PBL_MM_ZERO_VIRTUAL_ADDRESS_RANGE BlMmZeroVirtualAddressRange; +extern PBL_STATUS_ERROR_HANDLER BlpStatusErrorHandler; #endif diff --git a/boot/environ/lib/misc/debug.c b/boot/environ/lib/misc/debug.c index a4c82e2cb05..b38a29f1926 100644 --- a/boot/environ/lib/misc/debug.c +++ b/boot/environ/lib/misc/debug.c @@ -16,6 +16,8 @@ CHAR AnsiBuffer[1024]; BOOLEAN BdDebuggerNotPresent; BOOLEAN BdSubsystemInitialized; BOOLEAN BdArchBlockDebuggerOperation; +BOOLEAN BlpStatusErrorInProgress; +PBL_STATUS_ERROR_HANDLER BlpStatusErrorHandler; /* FUNCTIONS *****************************************************************/ @@ -124,6 +126,35 @@ BlStatusError ( _In_ ULONG_PTR Parameter4 ) { + NTSTATUS Status; + + /* Is this a non-boot error? */ + if (ErrorCode != 1) + { + /* Is one already ongoing? */ + if (!BlpStatusErrorInProgress) + { + /* Do we have a custom error handler registered? */ + if (BlpStatusErrorHandler) + { + /* Call it, making sure to avoid recursion */ + BlpStatusErrorInProgress = TRUE; + Status = BlpStatusErrorHandler(ErrorCode, + Parameter1, + Parameter2, + Parameter3, + Parameter4); + BlpStatusErrorInProgress = FALSE; + + /* If the error handler consumed the error, we're done */ + if (NT_SUCCESS(Status)) + { + return; + } + } + } + } + /* Check if the boot debugger is enabled */ if (BlBdDebuggerEnabled()) { diff --git a/boot/environ/lib/misc/image.c b/boot/environ/lib/misc/image.c index 4073eae3e93..29fdb9def92 100644 --- a/boot/environ/lib/misc/image.c +++ b/boot/environ/lib/misc/image.c @@ -1654,7 +1654,7 @@ ImgpCopyApplicationBootDevice ( NTSTATUS ImgpInitializeBootApplicationParameters ( - _In_ PBL_IMAGE_PARAMETERS ImageParameters, + _In_ PBL_BUFFER_DESCRIPTOR ImageParameters, _In_ PBL_APPLICATION_ENTRY AppEntry, _In_ PVOID ImageBase, _In_ ULONG ImageSize @@ -1662,7 +1662,7 @@ ImgpInitializeBootApplicationParameters ( { NTSTATUS Status; PIMAGE_NT_HEADERS NtHeaders; - BL_IMAGE_PARAMETERS MemoryParameters; + BL_BUFFER_DESCRIPTOR MemoryParameters; LIST_ENTRY MemoryList; PBL_FIRMWARE_DESCRIPTOR FirmwareParameters; PBL_DEVICE_DESCRIPTOR BootDevice; @@ -1841,7 +1841,7 @@ ImgArchEfiStartBootApplication ( PVOID BootData; PIMAGE_NT_HEADERS NtHeaders; PVOID NewStack, NewGdt, NewIdt; - BL_IMAGE_PARAMETERS Parameters; + BL_BUFFER_DESCRIPTOR Parameters; /* Read the current IDT and GDT */ _sgdt(&Gdt.Limit); diff --git a/boot/environ/lib/mm/pagealloc.c b/boot/environ/lib/mm/pagealloc.c index f39904d9c9f..fc42077ce5e 100644 --- a/boot/environ/lib/mm/pagealloc.c +++ b/boot/environ/lib/mm/pagealloc.c @@ -1221,7 +1221,7 @@ MmPapFreePages ( NTSTATUS BlMmGetMemoryMap ( _In_ PLIST_ENTRY MemoryMap, - _In_ PBL_IMAGE_PARAMETERS MemoryParameters, + _In_ PBL_BUFFER_DESCRIPTOR MemoryParameters, _In_ ULONG WhichTypes, _In_ ULONG Flags ) -- 2.17.1