diff options
Diffstat (limited to 'MdePkg/Library/DynamicStackCookieEntryPointLib')
19 files changed, 1166 insertions, 0 deletions
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S new file mode 100644 index 000000000000..f508f692d3f9 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S @@ -0,0 +1,56 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# Module Name: +# +# DynamicCookie.S +# +# Abstract: +# +# Generates random number through the RNDR instruction on a 64-bit AARCH64 platform +# to store a random value in the GCC __stack_check_guard stack cookie. +# The first byte is 0'd to prevent string copy functions from clobbering +# the stack cookie. +# +# Notes: +# +# If RNDR fails, the build time static stack cookie value will be used instead. +# +#------------------------------------------------------------------------------ + +#include <AArch64/AArch64.h> + +.text +.p2align 2 + +GCC_ASM_IMPORT(__stack_chk_guard) +GCC_ASM_IMPORT(_CModuleEntryPoint) +GCC_ASM_EXPORT(_ModuleEntryPoint) + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# _ModuleEntryPoint ( +# Parameters are passed through. +# ) +#------------------------------------------------------------------------------ +ASM_PFX(_ModuleEntryPoint): + AARCH64_BTI(c) + + mrs x9, ID_AA64ISAR0_EL1 // Read the AArch64 Instruction Set Attribute Register 0 + ubfx x9, x9, #60, #4 // Extract the RNDR bit field (bits 60-63) + cbz x9, c_entry // If RNDR is not supported, jump to c_entry + + mrs x9, RNDR // Generate a random number + b.eq c_entry // RNDR sets NZCV to 0b0100 on failure + // So if the zero flag is set, use the static stack guard + + and x9, x9, #0xFFFFFFFFFFFFFF00 // Zero the first byte of the random value + + adrp x8, ASM_PFX(__stack_chk_guard) // Load the page address of __stack_chk_guard + str x9, [x8, :lo12:ASM_PFX(__stack_chk_guard)] // Store the random value in __stack_chk_guard + +c_entry: + b ASM_PFX(_CModuleEntryPoint) // Jump to the C module entry point diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c new file mode 100644 index 000000000000..5118132bd2c3 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c @@ -0,0 +1,70 @@ +/** @file + Entry point to the DXE Core. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiDxe.h> + +#include <Library/DxeCoreEntryPoint.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> + +// +// Cache copy of HobList pointer. +// +VOID *gHobList = NULL; + +/** + The entry point of PE/COFF Image for the DXE Core. + + This function is the entry point for the DXE Core. This function is required to call + ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return. + The DXE Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI + System Table and the image handle for the DXE Core itself have been established. + If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system. + + @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase. + +**/ +VOID +EFIAPI +_CModuleEntryPoint ( + IN VOID *HobStart + ) +{ + // + // Cache a pointer to the HobList + // + gHobList = HobStart; + + // + // Call the DXE Core entry point + // + ProcessModuleEntryPointList (HobStart); + + // + // Should never return + // + ASSERT (FALSE); + CpuDeadLoop (); +} + +/** + Required by the EBC compiler and identical in functionality to _ModuleEntryPoint(). + + This function is required to call _ModuleEntryPoint() passing in HobStart. + + @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase. + +**/ +VOID +EFIAPI +EfiMain ( + IN VOID *HobStart + ) +{ + _ModuleEntryPoint (HobStart); +} diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni new file mode 100644 index 000000000000..e6515659a9e0 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni @@ -0,0 +1,16 @@ +// /** @file +// Module entry point library for DXE core. +// +// Module entry point library for DXE core. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for DXE core" + +#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for DXE core." + diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf new file mode 100644 index 000000000000..1da877ae1d97 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf @@ -0,0 +1,45 @@ +## @file +# Module entry point library for DXE core that dynamically updates the stack cookie. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeCoreEntryPointDynamicInit + MODULE_UNI_FILE = DxeCore/DxeCoreEntryPoint.uni + FILE_GUID = FD044D85-1407-4043-B527-471F16ABD8C6 + MODULE_TYPE = DXE_CORE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DxeCoreEntryPoint|DXE_CORE + + +# +# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# + +[Sources] + DxeCore/DxeCoreEntryPoint.c + +[Sources.IA32] + IA32/DynamicCookieGcc.nasm | GCC + IA32/DynamicCookieMsvc.nasm | MSFT + +[Sources.X64] + X64/DynamicCookieGcc.nasm | GCC + X64/DynamicCookieMsvc.nasm | MSFT + +[Sources.AARCH64] + AArch64/DynamicCookieGcc.S | GCC + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + StackCheckLib diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm new file mode 100644 index 000000000000..c3c3e0e9931c --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm @@ -0,0 +1,63 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; DynamicCookie.nasm +; +; Abstract: +; +; Generates random number through CPU RdRand instruction on a 32-bit platform +; to store a random value in the GCC __stack_check_guard stack cookie. +; The first byte is 0'd to prevent string copy functions from clobbering +; the stack cookie. +; +; Notes: +; +; If RdRand fails, the build time static stack cookie value will be used instead. +; +;------------------------------------------------------------------------------ + +SECTION .text + +extern ASM_PFX(__stack_chk_guard) +extern ASM_PFX(_CModuleEntryPoint) +global ASM_PFX(_ModuleEntryPoint) + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; _ModuleEntryPoint ( +; Parameters are passed through +; ); +;------------------------------------------------------------------------------ +global _ModuleEntryPoint +_ModuleEntryPoint: + push ebx + push ecx + push edx + + mov eax, 1 ; CPUID function 1 + cpuid + test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX + jz c_entry ; If not set, jump to c_entry + + rdrand eax ; Use rdrand, getting a 32 bit value as on + ; IA32, __stack_chk_guard is a 32 bit value. + ; CF=1 if RN generated ok, otherwise CF=0 + jnc c_entry ; If the cmd fails, don't update __stack_chk_guard, we'll have to move forward + ; with the static value provided at build time. + + lea ebx, [ASM_PFX(__stack_chk_guard)] ; load the address of __stack_chk_guard into ebx + + xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions + ; (such as strcpy like functions) clobbering past the canary + mov [ebx], eax ; Store our random value, with 0'd first byte to __stack_chk_guard + +c_entry: + pop edx + pop ecx + pop ebx + jmp ASM_PFX(_CModuleEntryPoint) diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm new file mode 100644 index 000000000000..2b8ec94fdbe9 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm @@ -0,0 +1,63 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; DynamicCookie.nasm +; +; Abstract: +; +; Generates random number through CPU RdRand instruction on a 32-bit platform +; to store a random value in the GCC __stack_check_guard stack cookie. +; The first byte is 0'd to prevent string copy functions from clobbering +; the stack cookie. +; +; Notes: +; +; If RdRand fails, the build time static stack cookie value will be used instead. +; +;------------------------------------------------------------------------------ + +SECTION .text + +extern ASM_PFX(__security_cookie) +extern ASM_PFX(_CModuleEntryPoint) +global ASM_PFX(_ModuleEntryPoint) + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; _ModuleEntryPoint ( +; Parameters are passed through +; ); +;------------------------------------------------------------------------------ +global _ModuleEntryPoint +_ModuleEntryPoint: + push ebx + push ecx + push edx + + mov eax, 1 ; CPUID function 1 + cpuid + test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX + jz c_entry ; If not set, jump to c_entry + + rdrand eax ; Use rdrand, getting a 32 bit value as on + ; IA32, __security_cookie is a 32 bit value. + ; CF=1 if RN generated ok, otherwise CF=0 + jnc c_entry ; If the cmd fails, don't update __security_cookie, we'll have to move forward + ; with the static value provided at build time. + + lea ebx, [ASM_PFX(__security_cookie)] ; load the address of __stack_chk_guard into ebx + + xor ah, ah ; Zero a byte of the __security_cookie value to protect against string functions + ; (such as strcpy like functions) clobbering past the canary + mov [ebx], eax ; Store our random value, with 0'd first byte to __security_cookie + +c_entry: + pop edx + pop ecx + pop ebx + jmp ASM_PFX(_CModuleEntryPoint) diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c new file mode 100644 index 000000000000..204702727319 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c @@ -0,0 +1,65 @@ +/** @file + Entry point to the Standalone Mm Core. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +Copyright (c) Microsoft Corporation. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiMm.h> + +#include <Library/StandaloneMmCoreEntryPoint.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> + +// +// Cache copy of HobList pointer. +// +VOID *gHobList = NULL; + +/** + The entry point of PE/COFF Image for the STANDALONE MM Core. + + This function is the entry point for the STANDALONE MM Core. This function is required to call + ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return. + The STANDALONE MM Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI + System Table and the image handle for the STANDALONE MM Core itself have been established. + If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system. + + @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase. + +**/ +VOID +EFIAPI +_CModuleEntryPoint ( + IN VOID *HobStart + ) +{ + // + // Cache a pointer to the HobList + // + gHobList = HobStart; + + // + // Call the Standalone MM Core entry point + // + ProcessModuleEntryPointList (HobStart); +} + +/** + Required by the EBC compiler and identical in functionality to _ModuleEntryPoint(). + + This function is required to call _ModuleEntryPoint() passing in HobStart. + + @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase. + +**/ +VOID +EFIAPI +EfiMain ( + IN VOID *HobStart + ) +{ + _ModuleEntryPoint (HobStart); +} diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf new file mode 100644 index 000000000000..b82415e6b8fc --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf @@ -0,0 +1,38 @@ +## @file +# Module entry point library for StandaloneMm core that dynamically updates the stack cookie. +# The AARCH64 version of this library lives in ArmPkg. +# +# Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = StandaloneMmCoreEntryPointDynamicInit + FILE_GUID = 490073A1-4DBC-4E9E-B30D-A4204139FC5F + MODULE_TYPE = MM_CORE_STANDALONE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + LIBRARY_CLASS = StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE + +# +# VALID_ARCHITECTURES = X64 +# + +[Sources.X64] + StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c + +[Sources.X64] + X64/DynamicCookieGcc.nasm | GCC + X64/DynamicCookieMsvc.nasm | MSFT + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + StackCheckLib diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c new file mode 100644 index 000000000000..51df419953d5 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c @@ -0,0 +1,135 @@ +/** @file + Entry point to a Standalone MM driver. + +Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2016 - 2018, ARM Ltd. All rights reserved.<BR> +Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PiMm.h> + +#include <Protocol/LoadedImage.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/MmServicesTableLib.h> +#include <Library/StandaloneMmDriverEntryPoint.h> + +/** + Unloads an image from memory. + + This function is a callback that a driver registers to do cleanup + when the UnloadImage boot service function is called. + + @param ImageHandle The handle to the image to unload. + + @return Status returned by all unload(). + +**/ +EFI_STATUS +EFIAPI +_DriverUnloadHandler ( + EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + // + // If an UnloadImage() handler is specified, then call it + // + Status = ProcessModuleUnloadList (ImageHandle); + + // + // If the driver specific unload handler does not return an error, then call all of the + // library destructors. If the unload handler returned an error, then the driver can not be + // unloaded, and the library destructors should not be called + // + if (!EFI_ERROR (Status)) { + ProcessLibraryDestructorList (ImageHandle, gMmst); + } + + // + // Return the status from the driver specific unload handler + // + return Status; +} + +/** + The entry point of PE/COFF Image for a Standalone MM Driver. + + This function is the entry point for a Standalone MM Driver. + This function must call ProcessLibraryConstructorList() and + ProcessModuleEntryPointList(). + If the return status from ProcessModuleEntryPointList() + is an error status, then ProcessLibraryDestructorList() must be called. + The return value from ProcessModuleEntryPointList() is returned. + If _gMmRevision is not zero and SystemTable->Hdr.Revision is + less than _gMmRevision, then return EFI_INCOMPATIBLE_VERSION. + + @param ImageHandle The image handle of the Standalone MM Driver. + @param MmSystemTable A pointer to the MM System Table. + + @retval EFI_SUCCESS The Standalone MM Driver exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gMmRevision is greater than + MmSystemTable->Hdr.Revision. + @retval Other Return value from + ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +_CModuleEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN IN EFI_MM_SYSTEM_TABLE *MmSystemTable + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + + if (_gMmRevision != 0) { + // + // Make sure that the MM spec revision of the platform + // is >= MM spec revision of the driver + // + if (MmSystemTable->Hdr.Revision < _gMmRevision) { + return EFI_INCOMPATIBLE_VERSION; + } + } + + // + // Call constructor for all libraries + // + ProcessLibraryConstructorList (ImageHandle, MmSystemTable); + + // + // Install unload handler... + // + if (_gDriverUnloadImageCount != 0) { + Status = gMmst->MmHandleProtocol ( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + ASSERT_EFI_ERROR (Status); + LoadedImage->Unload = _DriverUnloadHandler; + } + + // + // Call the driver entry point + // + Status = ProcessModuleEntryPointList (ImageHandle, MmSystemTable); + + // + // If all of the drivers returned errors, then invoke all of the library destructors + // + if (EFI_ERROR (Status)) { + ProcessLibraryDestructorList (ImageHandle, MmSystemTable); + } + + // + // Return the cumulative return status code from all of the driver entry points + // + return Status; +} diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni new file mode 100644 index 000000000000..de36debd74ec --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni @@ -0,0 +1,17 @@ +// /** @file +// +// Module entry point library for standalone MM driver +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> +// Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR> +// Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for standalone MM driver" + +#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for standalone MM driver." + diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf new file mode 100644 index 000000000000..a5cb42518c1b --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf @@ -0,0 +1,53 @@ +## @file +# Module entry point library for Standalone MM drivers that dynamically updates the stack cookie. +# +# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2016-2018, ARM Ltd. All rights reserved.<BR> +# Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = StandaloneMmDriverEntryPointDynamicInit + MODULE_UNI_FILE = StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni + FILE_GUID = 28CBCD87-2FEE-4D46-BB5C-B37732BBEEB1 + MODULE_TYPE = MM_STANDALONE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + LIBRARY_CLASS = StandaloneMmDriverEntryPoint|MM_STANDALONE + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = X64 AARCH64 +# + +[Sources] + StandaloneMmDriver/StandaloneMmDriverEntryPoint.c + +[Sources.IA32] + IA32/DynamicCookieGcc.nasm | GCC + IA32/DynamicCookieMsvc.nasm | MSFT + +[Sources.X64] + X64/DynamicCookieGcc.nasm | GCC + X64/DynamicCookieMsvc.nasm | MSFT + +[Sources.AARCH64] + AArch64/DynamicCookieGcc.S | GCC + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + MmServicesTableLib + StackCheckLib + +[Protocols] + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c new file mode 100644 index 000000000000..81b9b55130e3 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c @@ -0,0 +1,112 @@ +/** @file + Entry point library instance to a UEFI application. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> +#include <Library/UefiApplicationEntryPoint.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> + +/** + Entry point to UEFI Application. + + This function is the entry point for a UEFI Application. This function must call + ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList(). + The return value from ProcessModuleEntryPointList() is returned. + If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than _gUefiDriverRevison, + then return EFI_INCOMPATIBLE_VERSION. + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision. + @retval Other Return value from ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +_CModuleEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + if (_gUefiDriverRevision != 0) { + // + // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the application. + // + if (SystemTable->Hdr.Revision < _gUefiDriverRevision) { + return EFI_INCOMPATIBLE_VERSION; + } + } + + // + // Call constructor for all libraries. + // + ProcessLibraryConstructorList (ImageHandle, SystemTable); + + // + // Call the module's entry point + // + Status = ProcessModuleEntryPointList (ImageHandle, SystemTable); + + // + // Process destructor for all libraries. + // + ProcessLibraryDestructorList (ImageHandle, SystemTable); + + // + // Return the return status code from the driver entry point + // + return Status; +} + +/** + Invokes the library destructors for all dependent libraries and terminates + the UEFI Application. + + This function calls ProcessLibraryDestructorList() and the EFI Boot Service Exit() + with a status specified by Status. + + @param Status Status returned by the application that is exiting. + +**/ +VOID +EFIAPI +Exit ( + IN EFI_STATUS Status + ) + +{ + ProcessLibraryDestructorList (gImageHandle, gST); + + gBS->Exit (gImageHandle, Status, 0, NULL); +} + +/** + Required by the EBC compiler and identical in functionality to _ModuleEntryPoint(). + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision. + @retval Other Return value from ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +EfiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return _ModuleEntryPoint (ImageHandle, SystemTable); +} diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni new file mode 100644 index 000000000000..168ce7469bb7 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni @@ -0,0 +1,16 @@ +// /** @file +// Module entry point library for UEFI Application. +// +// Module entry point library for UEFI Application. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI Application" + +#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI Application." + diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf new file mode 100644 index 000000000000..1a82fc498de1 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf @@ -0,0 +1,45 @@ +## @file +# Module entry point library for UEFI Application that dynamically updates the stack cookie. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiApplicationEntryPointDynamicInit + MODULE_UNI_FILE = UefiApplication/UefiApplicationEntryPoint.uni + FILE_GUID = 755B9094-E5AF-4E5B-BE33-D430CDE2C5D2 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiApplicationEntryPoint|UEFI_APPLICATION + +# +# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# + +[Sources] + UefiApplication/ApplicationEntryPoint.c + +[Sources.IA32] + IA32/DynamicCookieGcc.nasm | GCC + IA32/DynamicCookieMsvc.nasm | MSFT + +[Sources.X64] + X64/DynamicCookieGcc.nasm | GCC + X64/DynamicCookieMsvc.nasm | MSFT + +[Sources.AARCH64] + AArch64/DynamicCookieGcc.S | GCC + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + DebugLib + BaseLib + StackCheckLib diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c new file mode 100644 index 000000000000..ad17e0d1c616 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c @@ -0,0 +1,162 @@ +/** @file + Entry point to a EFI/DXE driver. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> + +#include <Protocol/LoadedImage.h> + +#include <Library/UefiDriverEntryPoint.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/UefiBootServicesTableLib.h> + +/** + Unloads an image from memory. + + This function is a callback that a driver registers to do cleanup + when the UnloadImage boot service function is called. + + @param ImageHandle The handle to the image to unload. + + @return Status returned by all unload(). + +**/ +EFI_STATUS +EFIAPI +_DriverUnloadHandler ( + EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + + // + // If an UnloadImage() handler is specified, then call it + // + Status = ProcessModuleUnloadList (ImageHandle); + + // + // If the driver specific unload handler does not return an error, then call all of the + // library destructors. If the unload handler returned an error, then the driver can not be + // unloaded, and the library destructors should not be called + // + if (!EFI_ERROR (Status)) { + ProcessLibraryDestructorList (ImageHandle, gST); + } + + // + // Return the status from the driver specific unload handler + // + return Status; +} + +/** + The entry point of PE/COFF Image for a DXE Driver, DXE Runtime Driver, DXE SMM + Driver, or UEFI Driver. + + This function is the entry point for a DXE Driver, DXE Runtime Driver, DXE SMM Driver, + or UEFI Driver. This function must call ProcessLibraryConstructorList() and + ProcessModuleEntryPointList(). If the return status from ProcessModuleEntryPointList() + is an error status, then ProcessLibraryDestructorList() must be called. The return + value from ProcessModuleEntryPointList() is returned. If _gDriverUnloadImageCount + is greater than zero, then an unload handler must be registered for this image + and the unload handler must invoke ProcessModuleUnloadList(). + If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than + _gUefiDriverRevison, then return EFI_INCOMPATIBLE_VERSION. + + + @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver, + DXE SMM Driver, or UEFI Driver. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM + Driver, or UEFI Driver exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than + SystemTable->Hdr.Revision. + @retval Other Return value from ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +_CModuleEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + + if (_gUefiDriverRevision != 0) { + // + // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver + // + if (SystemTable->Hdr.Revision < _gUefiDriverRevision) { + return EFI_INCOMPATIBLE_VERSION; + } + } + + // + // Call constructor for all libraries + // + ProcessLibraryConstructorList (ImageHandle, SystemTable); + + // + // Install unload handler... + // + if (_gDriverUnloadImageCount != 0) { + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + ASSERT_EFI_ERROR (Status); + LoadedImage->Unload = _DriverUnloadHandler; + } + + // + // Call the driver entry point + // + Status = ProcessModuleEntryPointList (ImageHandle, SystemTable); + + // + // If all of the drivers returned errors, then invoke all of the library destructors + // + if (EFI_ERROR (Status)) { + ProcessLibraryDestructorList (ImageHandle, SystemTable); + } + + // + // Return the cummalative return status code from all of the driver entry points + // + return Status; +} + +/** + Required by the EBC compiler and identical in functionality to _ModuleEntryPoint(). + + This function is required to call _ModuleEntryPoint() passing in ImageHandle, + and SystemTable. + + @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver, DXE + SMM Driver, or UEFI Driver. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM + Driver, or UEFI Driver exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than + SystemTable->Hdr.Revision. + @retval Other Return value from ProcessModuleEntryPointList(). +**/ +EFI_STATUS +EFIAPI +EfiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return _ModuleEntryPoint (ImageHandle, SystemTable); +} diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni new file mode 100644 index 000000000000..9d820b25f063 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni @@ -0,0 +1,16 @@ +// /** @file +// Module entry point library for UEFI driver, DXE driver and SMM driver. +// +// Module entry point library for UEFI driver, DXE driver and SMM driver. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver" + +#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver." + diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf new file mode 100644 index 000000000000..522bcd930c23 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf @@ -0,0 +1,68 @@ +## @file +# Module entry point library for UEFI driver, DXE driver and SMM driver that dynamically sets the stack cookie. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiDriverEntryPointDynamicInit + MODULE_UNI_FILE = UefiDriver/UefiDriverEntryPoint.uni + FILE_GUID = 900238F9-1421-4596-9548-A1BF58C97693 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 AARCH64 +# + +[Sources] + UefiDriver/DriverEntryPoint.c + +[Packages] + MdePkg/MdePkg.dec + +[Sources.IA32] + IA32/DynamicCookieGcc.nasm | GCC + IA32/DynamicCookieMsvc.nasm | MSFT + +[Sources.X64] + X64/DynamicCookieGcc.nasm | GCC + X64/DynamicCookieMsvc.nasm | MSFT + +[Sources.AARCH64] + AArch64/DynamicCookieGcc.S | GCC + +[LibraryClasses] + UefiBootServicesTableLib + DebugLib + BaseLib + StackCheckLib + +[Protocols] + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES + +# +# For UEFI drivers, these architectural protocols defined in PI 1.0 spec need +# to be appended and merged to the final dependency section. +# +[Depex.common.UEFI_DRIVER] + gEfiBdsArchProtocolGuid AND + gEfiCpuArchProtocolGuid AND + gEfiMetronomeArchProtocolGuid AND + gEfiMonotonicCounterArchProtocolGuid AND + gEfiRealTimeClockArchProtocolGuid AND + gEfiResetArchProtocolGuid AND + gEfiRuntimeArchProtocolGuid AND + gEfiSecurityArchProtocolGuid AND + gEfiTimerArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid AND + gEfiVariableArchProtocolGuid AND + gEfiWatchdogTimerArchProtocolGuid diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm new file mode 100644 index 000000000000..782e8bbb791a --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm @@ -0,0 +1,63 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; DynamicCookie.nasm +; +; Abstract: +; +; Generates random number through CPU RdRand instruction on 64-bit platform +; to store a random value in the GCC __stack_check_guard stack cookie. +; The first byte is 0'd to prevent string copy functions from clobbering +; the stack cookie. +; +; Notes: +; +; If RdRand fails, the build time static stack cookie value will be used instead. +; +;------------------------------------------------------------------------------ + +DEFAULT REL +SECTION .text + +extern ASM_PFX(__stack_chk_guard) +extern ASM_PFX(_CModuleEntryPoint) + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; _ModuleEntryPoint ( +; Parameters are passed through. TODO: Make sure there are only two args on X64 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + push rbx + push rcx + push rdx + + mov eax, 1 ; Set eax to 1 to get feature information + cpuid ; Call cpuid + test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx + jz c_entry ; If rdrand is not supported, jump to c_entry + + rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on + ; X64, __stack_chk_guard is a 64 bit value. + ; CF=1 if RN generated ok, otherwise CF=0 + jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward + ; with the static value provided at build time. + + lea rbx, [rel ASM_PFX(__stack_chk_guard)] ; load the address of __stack_check_guard into rbx + + xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions + ; (such as strcpy like functions) clobbering past the canary + mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard + +c_entry: + pop rdx + pop rcx + pop rbx + jmp ASM_PFX(_CModuleEntryPoint) diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm new file mode 100644 index 000000000000..bd290f712634 --- /dev/null +++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm @@ -0,0 +1,63 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) Microsoft Corporation. +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; DynamicCookie.nasm +; +; Abstract: +; +; Generates random number through CPU RdRand instruction on 64-bit platform +; to store a random value in the GCC __stack_check_guard stack cookie. +; The first byte is 0'd to prevent string copy functions from clobbering +; the stack cookie. +; +; Notes: +; +; If RdRand fails, the build time static stack cookie value will be used instead. +; +;------------------------------------------------------------------------------ + +DEFAULT REL +SECTION .text + +extern ASM_PFX(__security_cookie) +extern ASM_PFX(_CModuleEntryPoint) + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; _ModuleEntryPoint ( +; Parameters are passed through. TODO: Make sure there are only two args on X64 +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + push rbx + push rcx + push rdx + + mov eax, 1 ; Set eax to 1 to get feature information + cpuid ; Call cpuid + test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx + jz c_entry ; If rdrand is not supported, jump to c_entry + + rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on + ; X64, __stack_chk_guard is a 64 bit value. + ; CF=1 if RN generated ok, otherwise CF=0 + jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward + ; with the static value provided at build time. + + lea rbx, [rel ASM_PFX(__security_cookie)] ; load the address of __stack_check_guard into rbx + + xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions + ; (such as strcpy like functions) clobbering past the canary + mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard + +c_entry: + pop rdx + pop rcx + pop rbx + jmp ASM_PFX(_CModuleEntryPoint) |
